package com.cpop.oam.business.controller.backstage;

import com.cpop.core.base.R;
import com.cpop.core.utils.SpringUtils;
import com.cpop.oam.business.bo.ClueFollowUpBo;
import com.cpop.oam.business.bo.CluePutOffBo;
import com.cpop.oam.business.bo.ClueUpdateBo;
import com.cpop.oam.business.bo.DeptBo;
import com.cpop.oam.business.service.ClueRecordService;
import com.cpop.oam.business.service.SignAreaService;
import com.cpop.oam.business.service.StaffService;
import com.cpop.oam.business.vo.*;
import com.cpop.system.business.entity.DictData;
import com.cpop.system.business.entity.DictType;
import com.cpop.system.business.service.DictDataService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import com.cpop.oam.business.entity.Clue;
import com.cpop.oam.business.service.ClueService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import static com.cpop.core.base.table.table.SysUserTableDef.SYS_USER;
import static com.cpop.oam.business.entity.table.ClueRecordTableDef.CLUE_RECORD;
import static com.cpop.oam.business.entity.table.SignAreaTableDef.SIGN_AREA;
import static com.cpop.oam.business.entity.table.SignGoalTableDef.SIGN_GOAL;
import static com.cpop.oam.business.entity.table.StaffTableDef.STAFF;
import static com.mybatisflex.core.query.QueryMethods.distinct;

/**
 * 线索表 控制层。
 *
 * @author DB
 * @since 2024-02-19
 */
@RestController
@Api(tags = "线索接口")
@RequestMapping("/backstage/clue")
public class BackstageClueController {

    @Autowired
    private ClueService clueService;

    @Autowired
    private ClueRecordService clueRecordService;

    /**
     * 个人线索分页
     * @author DB
     * @since 2024/2/19
     * @return R<Page<SignGoalPageVo>>
     */
    @ApiOperation("个人线索分页")
    @GetMapping("/getPersonCluePage")
    public R<Page<CluePageVo>> getPersonCluePage(@ApiParam(value = "线索状态") @RequestParam(value = "clueStatus", required = false) Integer clueStatus,
                                                 @ApiParam(value = "地区") @RequestParam(value = "city", required = false) String city,
                                                 @ApiParam(value = "品牌") @RequestParam(value = "brandId", required = false) String brandId,
                                                 @ApiParam(value = "校区") @RequestParam(value = "storeId", required = false) String storeId,
                                                 @ApiParam(value = "负责人或手机号") @RequestParam(value = "chargeOrPhone", required = false) String chargeOrPhone,
                                                 @ApiParam(value = "员工id") @RequestParam(value = "staffId", required = false) String staffId,
                                                 @ApiParam(value = "签约月份") @RequestParam(value = "signMonth", required = false) String signMonth,
                                                 @ApiParam(value = "更进状态") @RequestParam(value = "followStatus", required = false) Integer followStatus) {
        Page<CluePageVo> pageVo = clueService.getPersonCluePage(clueStatus, city, brandId, storeId, chargeOrPhone, staffId, signMonth,followStatus);
        return R.ok(pageVo);
    }

    /**
     * 获取个人签约目标
     * @author DB
     * @since 2024/2/20
     * @param signMonth 签约月份
     * @return R<PersonSignGoalVo>
     */
    @ApiOperation("获取个人签约目标")
    @GetMapping("/getPersonSignGoal")
    public R<PersonSignGoalVo> getPersonSignGoal(@ApiParam(value = "签约月份") @RequestParam(value = "signMonth", required = false) String signMonth,
                                                 @ApiParam(value = "员工id") @RequestParam(value = "staffId", required = false) String staffId) {
        PersonSignGoalVo vo = clueService.getPersonSignGoal(signMonth, staffId);
        return R.ok(vo);
    }

    /**
     * 线索跟进
     * @author DB
     * @since 2024/2/20
     * @param bo 请求对象
     * @return R<Void>
     */
    @ApiOperation("线索跟进")
    @PostMapping("/clueFollowUp")
    public R<Void> clueFollowUp(@Validated @RequestBody ClueFollowUpBo bo) {
        clueService.clueFollowUp(bo);
        return R.ok();
    }

    /**
     * 线索跟进记录
     * @author DB
     * @since 2024/2/20
     * @param clueId 线索id
     * @return R<List<ClueFollowUpRecordVo>>
     */
    @ApiOperation("线索跟进记录")
    @GetMapping("/getClueFollowUpRecord")
    public R<List<ClueFollowUpRecordVo>> getClueFollowUpRecord(@ApiParam(value = "线索id") @RequestParam(value = "clueId") String clueId) {
        List<ClueFollowUpRecordVo> vos = clueRecordService.listAs(QueryWrapper.create()
                        .select(CLUE_RECORD.CREATE_TIME, CLUE_RECORD.RECORD_CONTENT, CLUE_RECORD.RECORD_FILE_URL)
                        .select(STAFF.NAME.as(ClueFollowUpRecordVo::getStaffName))
                        .leftJoin(STAFF).on(STAFF.ID.eq(CLUE_RECORD.RECORD_STAFF_ID))
                        .where(CLUE_RECORD.RECORD_TYPE.eq(2)
                                .and(CLUE_RECORD.CLUE_ID.eq(clueId)))
                        .orderBy(CLUE_RECORD.CREATE_TIME.desc()),
                ClueFollowUpRecordVo.class);
        return R.ok(vos);
    }

    /**
     * 线索记录
     * @author DB
     * @since 2024/2/20
     * @param clueId 线索id
     * @return R<List<ClueRecordVo>>
     */
    @ApiOperation("线索记录")
    @GetMapping("/getClueRecordList")
    public R<List<ClueRecordVo>> getClueRecordList(@ApiParam(value = "线索id") @RequestParam(value = "clueId") String clueId) {
        List<ClueRecordVo> vos = clueRecordService.listAs(QueryWrapper.create()
                        .select(CLUE_RECORD.CREATE_TIME, CLUE_RECORD.RECORD_CONTENT,CLUE_RECORD.RECORD_TYPE)
                        .and(CLUE_RECORD.CLUE_ID.eq(clueId))
                        .orderBy(CLUE_RECORD.CREATE_TIME.desc()),
                ClueRecordVo.class);
        return R.ok(vos);
    }

    /**
     * 线索更新
     * @author DB
     * @since 2024/2/20
     * @param bo 请求对象
     * @return R<Void>
     */
    @ApiOperation("线索更新")
    @PostMapping("/clueUpdate")
    public R<Void> clueUpdate(@Validated @RequestBody ClueUpdateBo bo) {
        clueService.clueUpdate(bo);
        return R.ok();
    }

    /**
     * 线索更新记录
     * @author DB
     * @since 2024/2/20
     * @param clueId 线索id
     * @return R<List<ClueFollowUpRecordVo>>
     */
    @ApiOperation("线索更新记录")
    @GetMapping("/getClueUpdateRecord")
    public R<ClueUpdateVo> getClueUpdateRecord(@ApiParam(value = "线索id") @RequestParam(value = "clueId") String clueId) {
        ClueUpdateVo vo = clueService.getClueUpdateRecord(clueId);
        return R.ok(vo);
    }

    /**
     * 线索延期
     * @author DB
     * @since 2024/2/20
     * @param bo 请求对象
     * @return R<Void>
     */
    @ApiOperation("线索延期")
    @PostMapping("/cluePutOff")
    public R<Void> cluePutOff(@Validated @RequestBody CluePutOffBo bo) {
        clueService.cluePutOff(bo);
        return R.ok();
    }

    /**
     * 线索延期记录
     * @author DB
     * @since 2024/2/20
     * @param clueId 线索id
     * @return R<List<CluePutOffVo>>
     */
    @ApiOperation("线索延期记录")
    @GetMapping("/getCluePutOffRecord")
    public R<List<CluePutOffVo>> getCluePutOffRecord(@ApiParam(value = "线索id") @RequestParam(value = "clueId") String clueId) {
        List<CluePutOffVo> vos = clueService.getCluePutOffRecord(clueId);
        return R.ok(vos);
    }

    /**
     * 线索脱离
     * @author DB
     * @since 2024/2/20
     * @param id 线索id
     * @return R<Void>
     */
    @ApiOperation("线索脱离")
    @PutMapping("/clueDetachment/{id}")
    public R<Void> clueDetachment(@PathVariable @ApiParam(value = "线索id") String id) {
        clueService.clueDetachment(id);
        return R.ok();
    }

    /**
     * 地区线索分页
     * @author DB
     * @since 2024/2/19
     * @return R<Page<SignGoalPageVo>>
     */
    @ApiOperation("地区线索分页")
    @GetMapping("/getAreaCluePage")
    public R<Page<CluePageVo>> getAreaCluePage(@ApiParam(value = "地区") @RequestParam(value = "city", required = false) String city,
                                               @ApiParam(value = "品牌") @RequestParam(value = "brandId", required = false) String brandId,
                                               @ApiParam(value = "校区") @RequestParam(value = "storeId", required = false) String storeId,
                                               @ApiParam(value = "负责人或手机号") @RequestParam(value = "chargeOrPhone", required = false) String chargeOrPhone) {
        Page<CluePageVo> pageVo = clueService.getAreaCluePage( city, brandId, storeId, chargeOrPhone);
        return R.ok(pageVo);
    }

    /**
     * 公共线索分页
     * @author DB
     * @since 2024/2/19
     * @return R<Page<SignGoalPageVo>>
     */
    @ApiOperation("公共线索分页")
    @GetMapping("/getPublicCluePage")
    public R<Page<CluePageVo>> getPublicCluePage(@ApiParam(value = "地区") @RequestParam(value = "city", required = false) String city,
                                               @ApiParam(value = "品牌") @RequestParam(value = "brandId", required = false) String brandId,
                                               @ApiParam(value = "校区") @RequestParam(value = "storeId", required = false) String storeId,
                                               @ApiParam(value = "负责人或手机号") @RequestParam(value = "chargeOrPhone", required = false) String chargeOrPhone) {
        Page<CluePageVo> pageVo = clueService.getPublicCluePage( city, brandId, storeId, chargeOrPhone);
        return R.ok(pageVo);
    }

    /**
     * 线索领取
     * @author DB
     * @since 2024/2/20
     * @param id 线索id
     * @return R<Void>
     */
    @ApiOperation("线索领取")
    @PutMapping("/clueCollection/{id}")
    public R<Void> clueCollection(@PathVariable @ApiParam(value = "线索id") String id) {
        clueService.clueCollection(id);
        return R.ok();
    }

    /**
     * 我的开发分页
     * @author DB
     * @since 2024/2/19
     * @return R<Page<SignGoalPageVo>>
     */
    @ApiOperation("我的开发分页")
    @GetMapping("/getMyDevCluePage")
    public R<Page<CluePageVo>> getMyDevCluePage(@ApiParam(value = "地区") @RequestParam(value = "city", required = false) String city,
                                                 @ApiParam(value = "品牌") @RequestParam(value = "brandId", required = false) String brandId,
                                                 @ApiParam(value = "校区") @RequestParam(value = "storeId", required = false) String storeId,
                                                 @ApiParam(value = "负责人或手机号") @RequestParam(value = "chargeOrPhone", required = false) String chargeOrPhone) {
        Page<CluePageVo> pageVo = clueService.getMyDevCluePage( city, brandId, storeId, chargeOrPhone);
        return R.ok(pageVo);
    }

    /**
     * 描述
     * @author DB
     * @since 2024/2/27
     * @return R<Page<CluePageVo>>
     */
    @ApiOperation("获取区域列表")
    @GetMapping("/getAreaList")
    public R<List<Map<String,String>>> getAreaList() {
        List<DictData> dictDataByDictType = SpringUtils.getBean(DictDataService.class).getDictDataByDictType("oam_clue_area")
                .stream().sorted(Comparator.comparing(DictData::getDictSort)).collect(Collectors.toList());
        List<Map<String,String>> result = new ArrayList<>();
        if (!dictDataByDictType.isEmpty()){
            dictDataByDictType.forEach(item -> {
                Arrays.stream(item.getDictValue().split("/")).forEach(inner->{
                    Map<String, String> map = new HashMap<>();
                    map.put("label", inner);
                    map.put("value", inner);
                    result.add(map);
                });
            });
        }
        return R.ok(result);
    }

    /**
     * 获取市场部员工
     * @author DB
     * @since 2023/12/13
     * @return R<List<StaffVo>>
     */
    @GetMapping("/getMarketStaff")
    @ApiOperation("获取市场部员工")
    public R<List<StaffVo>> getBusinessStaff() {
        List<StaffVo> list = SpringUtils.getBean(StaffService.class).queryChain()
                .leftJoin(SYS_USER).on(SYS_USER.ID.eq(STAFF.USER_ID))
                .where(STAFF.STAFF_TYPE.in(1, 2))
                .and(SYS_USER.STATUS.eq(1))
                .listAs(StaffVo.class);
        return R.ok(list);
    }
}
