package com.lz.modules.performance.controller;

import com.lz.common.utils.PageUtils;
import com.lz.common.utils.R;
import com.lz.common.utils.StringUtil;
import com.lz.modules.app.dto.StaffSimpleDto;
import com.lz.modules.app.entity.DepartmentsEntity;
import com.lz.modules.app.entity.DepartmentsStaffRelateEntity;
import com.lz.modules.app.entity.StaffEntity;
import com.lz.modules.app.service.DepartmentsService;
import com.lz.modules.app.service.DepartmentsStaffRelateService;
import com.lz.modules.app.service.StaffService;
import com.lz.modules.flow.dao.FlowStartMapper;
import com.lz.modules.flow.entity.FlowRecord;
import com.lz.modules.flow.entity.FlowStart;
import com.lz.modules.flow.entity.StaffRole;
import com.lz.modules.flow.entity.StaffRoleDepartment;
import com.lz.modules.flow.service.EvaluationStartStaffService;
import com.lz.modules.flow.service.FlowRecordService;
import com.lz.modules.flow.service.StaffRoleDepartmentService;
import com.lz.modules.flow.service.StaffRoleService;
import com.lz.modules.job.business.DingtalkBusiness;
import com.lz.modules.performance.req.AssessChangeReq;
import com.lz.modules.performance.req.AssessListReq;
import com.lz.modules.performance.req.AssessDetailReq;
import com.lz.modules.performance.req.AssessToScoreReq;
import com.lz.modules.performance.res.AssessManagerDetailRes;
import com.lz.modules.performance.res.AssessManagerListRes;
import com.lz.modules.performance.res.ChartStatistical;
import com.lz.modules.performance.res.ChartStatisticalRes;
import com.lz.modules.performance.service.AssessManagerService;
import com.lz.modules.performance.service.ChartResultService;
import com.lz.modules.sys.controller.AbstractController;
import com.lz.modules.sys.dao.app.ResultRecordMapper;
import com.lz.modules.sys.entity.app.ResultRecord;
import com.lz.modules.sys.service.app.ResultRecordService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: djc
 * @Desc:
 * @Date: 2020/10/20 17:33
 */
@RestController
@RequestMapping("/performance")
@Slf4j
@Api(value="考核管理接口", tags={"考核管理"})
public class AssessManagerController extends AbstractController{

    @Autowired
    private FlowStartMapper flowStartMapper;
    @Autowired
    private AssessManagerService assessManagerService;
    @Autowired
    private ResultRecordMapper resultRecordMapper;
    @Autowired
    private ChartResultService chartResultService;
    @Autowired
    private StaffRoleService staffRoleService;

    @Autowired
    private DingtalkBusiness dingtalkBusiness;

    @Autowired
    private DepartmentsStaffRelateService departmentsStaffRelateService;

    @Autowired
    private StaffRoleDepartmentService staffRoleDepartmentService;

    @Autowired
    private DepartmentsService departmentsService;

    @Autowired
    private StaffService staffService;

    @Autowired
    private FlowRecordService flowRecordService;



    @PostMapping("assess/manager/list")
    @ApiOperation("获取考核列表")
    @ApiResponses({@ApiResponse(code = 200,message = "成功",response = AssessManagerListRes.class)})
    public R assessList(@RequestBody AssessListReq req){
        Long userId = null;
        try {
            userId = getUserId();
            req.setLoginUserId(userId);
            PageUtils pageUtils = assessManagerService.assessList(req);
            return R.ok().put("data",pageUtils);
        } catch (Exception e) {
            log.error("获取考核列表异常，userId: "  + userId,e);
            return R.error(e.getMessage());
        }
    }

    @PostMapping("assess/manager/detail")
    @ApiOperation("获取考核详情列表")
    @ApiResponses({@ApiResponse(code = 200,message = "成功",response = AssessManagerDetailRes.class)})
    public R assessDetail(@RequestBody AssessDetailReq req){
        PageUtils pageUtils;
        Long userId = null;
        try {
            userId = getUserId();
            req.setLoginUserId(userId);
            pageUtils = assessManagerService.assessDetail(req);
        } catch (Exception e) {
            log.error("获取考核详情列表异常，userId: "  + userId,e);
            return R.error(e.getMessage());
        }
        return R.ok().put("data",pageUtils);

    }



    @PostMapping("assess/manager/chart")
    @ApiOperation("获取考核详情列表人数统计")
    @ApiResponses({@ApiResponse(code = 200,message = "成功",response = ChartStatistical.class)})
    public R assessChart(@RequestBody AssessDetailReq req){
        List<ChartStatistical> process;
        Long userId = null;
        try {
            userId = getUserId();
            req.setLoginUserId(userId);
            process = chartResultService.countAssessNumByFlowProcess(req);
        } catch (Exception e) {
            log.error("获取详情顶部人数统计异常，userId: "  + userId,e);
            return R.error(e.getMessage());
        }
        return R.ok().put("data",process);

    }


    @PostMapping("assess/manager/change")
    @ApiOperation("考核管理组管理变更")
    @ApiResponses({@ApiResponse(code = 200,message = "成功"),@ApiResponse(code = 503,message = "去设置",response = StaffSimpleDto.class)})
    public R assessChange(@RequestBody AssessChangeReq req){
        try {
            return assessManagerService.assessChange(req);
        } catch (Exception e) {
            log.error("考核管理变更异常" ,e);
            return R.error(e.getMessage());
        }
    }


    @GetMapping("assess/manager/delete")
    @ApiOperation("删除考核任务")
    @ApiResponses({@ApiResponse(code = 200,message = "成功",response = ChartStatisticalRes.class)})
    @ApiImplicitParam(name = "assessId",value = "发起考核id", required = true, dataType = "Long",paramType = "query")
    public R assessDelete(@RequestParam Long assessId){
        FlowStart flowStart = flowStartMapper.selectFlowStartById(assessId);
        if(flowStart == null){
            return R.error("没有此条记录");
        }
        try {
            Long userId = getUserId();
            StaffRole role = staffRoleService.selectByStaffId(userId);
            if(role == null || role.getDepartmentId()!=0){
                return R.error("您不是绩效管理员或未管理全公司，无法删除此任务");
            }
            assessManagerService.accessDelete(flowStart);
        } catch (Exception e) {
            log.error("删除考核任务异常, id:" + assessId ,e);
            return R.error(e.getMessage());
        }
        return R.ok();
    }

    @PostMapping("assess/manager/toScore")
    @ApiOperation("开始评分")
    @ApiResponses({@ApiResponse(code = 200,message = "成功")})
    public R assessToScore(@RequestBody @ApiParam AssessToScoreReq req){
        try {
            log.info("开始评分，当前登陆用户，userId：" + getUserId());
            assessManagerService.toScore(req);
        } catch (Exception e) {
            log.error("开始评分异常" ,e);
            return R.error(e.getMessage());
        }
        return R.ok();
    }

    @GetMapping("assess/manager/Urging")
    @ApiOperation("一键催办")
    @ApiResponses({@ApiResponse(code = 200,message = "成功")})
    public R assessToScore(@RequestParam Map<String, String> params){
        log.info("接受的至{}", params);
        Long startId = Long.parseLong(params.get("startId"));
        Long flowProcess = null;
        if(params.containsKey("flowProcess")){
            flowProcess =  Long.parseLong(params.get("flowProcess"));
        }

        try {
            Long userId = getUserId();
            log.info("一键催办" + userId);
            StaffRole staffRole = staffRoleService.selectByStaffId(userId);
            int isManagementDepartment = 0;
            List<String> departmentIds = new ArrayList<>();
            if(staffRole != null){
                //查询管理的部门信息
                if(staffRole.getDepartmentId().intValue() == 2){//管理特定部门
                    List<StaffRoleDepartment> staffRoleDepartments =
                            staffRoleDepartmentService.selectStaffRoleDepartmentByStaffRoleId(staffRole.getId());
                    if(staffRoleDepartments.size() > 0){
                        departmentIds.addAll(staffRoleDepartments.stream().map(new Function<StaffRoleDepartment, String>() {
                            @Override
                            public String apply(StaffRoleDepartment staffRoleDepartment) {
                                return staffRoleDepartment.getDepartmentId();
                            }
                        }).collect(Collectors.toList()));
                    }
                }else if(staffRole.getDepartmentId().intValue() == 1){
                    //管理所在部门及子部门
                    isManagementDepartment = 1;//所在部门及子部门
                }else if(staffRole.getDepartmentId().intValue() == 0){
                    isManagementDepartment = 2;//所有部门
                }

            }
            List<Long> staffIds = null;
            if(isManagementDepartment == 2){
                //管理所有部门
                log.info("管理所有部门");
                staffIds = departmentsStaffRelateService.selectAllStaffIds();
            }else{
                //看下是否为部门领导
                log.info("管理所指定部门");
                DepartmentsStaffRelateEntity departmentsStaffRelateEntity
                        = departmentsStaffRelateService.selectByStaffId(userId);
                if (departmentsStaffRelateEntity != null && (isManagementDepartment == 1 ||
                        departmentsStaffRelateEntity.getIsLeader().intValue() == 1)) {//特定部门的
                    //获取所在部门下面的所有人员id
                    departmentIds.add(departmentsStaffRelateEntity.getDepartmentId());
                }
                if(departmentIds.size() > 0){
                    //去重
                    log.info("去重前数据{}", departmentIds.size());
                    departmentIds = departmentIds.stream().distinct().collect(Collectors.toList());
                    log.info("去重后数据{}", departmentIds.size());

                    List<String> childIds = new ArrayList<>();
                    //获取子部门信息
                    for (String pareId:departmentIds
                    ) {
                        childIds.addAll(getChildsId(pareId));
                    }
                    if(childIds.size() > 0){
                        departmentIds.addAll(childIds);
                    }
                }
                //根据部门获取所有员工的id
                staffIds = departmentsStaffRelateService.selectLongStaffIdsByDepartments(departmentIds);
            }

            log.info("查询到有权限可以推送的人员数量为{}， 如下{}", staffIds.size(), staffIds);
            //下面查询当前startId，当前flowProcess下面有多少人员id
            List<ResultRecord> resultRecords = resultRecordMapper.selectStaffIdsByStartIdAndFlowProcess(startId, flowProcess);
            Map<Long, ResultRecord> mapReords =
                    resultRecords.stream().collect(Collectors.toMap(ResultRecord::getStaffId, Function.identity(), (e, r) -> e));

            List<Long> staffIds1 = mapReords.keySet().stream().collect(Collectors.toList());
            log.info("查询到在当前节点下的人数为{}，如下{}", staffIds1.size(), staffIds1);
            if(staffIds1.size() > 0 && staffIds.size() > 0){
                staffIds.retainAll(staffIds1);//求交集
                log.info("需要推送绩效个数{}", staffIds.size());
                if(staffIds.size() > 0){

                    staffIds1 = mapReords.keySet().stream().collect(Collectors.toList());
                    staffIds1.retainAll(staffIds);
                    log.info("去掉排除的数据后数量{}", staffIds1.size());
                    for (Long id:staffIds1
                         ) {
                        mapReords.remove(id);
                    }
                    //获取催办的节点的人员信息
                    List<Long> recordIds = resultRecords.stream().map(new Function<ResultRecord, Long>() {
                        @Override
                        public Long apply(ResultRecord resultRecord) {
                            return resultRecord.getId();
                        }
                    }).collect(Collectors.toList());
                    log.info("剩余需要处理record的数量{}", recordIds.size());
                    List<FlowRecord> flowRecords;
                    if(flowProcess == null){//催全部，获取当前节点的人员信息

                        flowRecords =
                                flowRecordService.selectFlowRecordByRecordIdsStatus(recordIds, 2);
                        log.info("催当前节点的人员，数量{}", flowRecords.size());
                    }else{
                        flowRecords =
                                flowRecordService.selectFlowRecordByRecordIdsFlowProcess(recordIds, flowProcess);
                        log.info("催指定节点的人员，数量{}", flowRecords.size());
                    }

                    staffIds = flowRecords.stream().map(new Function<FlowRecord, Long>() {
                        @Override
                        public Long apply(FlowRecord flowRecord) {
                            return flowRecord.getApprovalStaffId();
                        }
                    }).collect(Collectors.toList());
                    log.info("最终能推送人员个数{}", staffIds.size());
                    mapReords = resultRecords.stream().collect(Collectors.toMap(ResultRecord::getId, Function.identity(), (e, r) -> e));
                    List<StaffEntity> staffEntities = staffService.selectByIds(staffIds);
                    Map<Long, StaffEntity> mapStaffs = staffEntities.stream().collect(Collectors.toMap(StaffEntity::getId, Function.identity(), (e, r) -> e));
                    dingtalkBusiness.urging(flowRecords, mapStaffs, mapReords);
                }
            }
        } catch (Exception e) {
            log.error("开始评分异常" ,e);
            return R.error(e.getMessage());
        }
        return R.ok();
    }

    //获取部门下面的所有子部门信息
    private List<String> getChildsId(String pareId){
        log.info("查询{}的子部门", pareId);
        List<String> ids = new ArrayList<>();
        List<DepartmentsEntity> entitys = departmentsService.selectEntityByParentDepartmentId(pareId);
        if(entitys.size() > 0){
            for (DepartmentsEntity entity:entitys
                 ) {
                List<String> childsId = getChildsId(entity.getDepartmentId());
                if(childsId.size() > 0){
                    ids.addAll(childsId);
                }
            }
        }
        log.info("子部门个数{}", ids.size());
        return ids;
    }
}
