package com.zcxk.evaluation.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zcxk.client.UserCenterClient;
import com.zcxk.evaluation.dao.EvaluationResultMapper;
import com.zcxk.evaluation.dto.EvaluationReportDto;
import com.zcxk.evaluation.dto.EvaluationReportQueryDto;
import com.zcxk.evaluation.dto.EvaluationResultDto;
import com.zcxk.evaluation.dto.EvaluationResultQueryDto;
import com.zcxk.evaluation.enums.EvaluationCycleEnums;
import com.zcxk.evaluation.service.EvaluationResultService;
import com.zcxk.evaluation.vo.*;
import com.zcxk.model.LoginUser;
import com.zcxk.org.OrgInfoUtil;
import com.zcxk.util.UserUtil;
import com.zcxk.utils.EvaluationUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName EvaluationResultServiceImpl
 * @Description: 考评结果业务处理
 * @Author lihui
 * @Date 2021/5/7
 * @Version V1.0
 **/
@Slf4j
@Service
public class EvaluationResultServiceImpl implements EvaluationResultService {

    @Autowired
    private EvaluationResultMapper evaluationResultMapper;

    @Autowired
    private OrgInfoUtil orgInfoUtil;

    @Autowired
    private UserCenterClient userCenterClient;

    @Override
    public IPage<EvaluationResultVo> findPage(EvaluationResultDto dto) {
        EvaluationResultQueryDto queryDto = getEvaluationReportQueryDto(dto);
        if (queryDto == null) {
            return null;
        }
        Page<EvaluationResultVo> page =  evaluationResultMapper.findPage(new Page<>(dto.getPageNum(), dto.getPageSize()), queryDto);
        formatEvaluationResultVo(page.getRecords(), dto.getCycle());
        return page;
    }

    @Override
    public List<EvaluationReportRankingVo> findRanking(EvaluationReportDto dto) {
        EvaluationReportQueryDto queryDto = getReportQuery(dto);
        if (queryDto == null) {
            return null;
        }
        List<EvaluationReportRankingVo> list =  evaluationResultMapper.findRanking(queryDto);
        if (CollectionUtil.isEmpty(list)) {
            return list;
        }
        Map<String,String> gradMap  = userCenterClient.selectListByPCodes("SC_EVALUATION_GRADE");
        for (EvaluationReportRankingVo evaluationReportRankingVo: list) {
            evaluationReportRankingVo.setEvaluationGrade(gradMap.get(evaluationReportRankingVo.getEvaluationGrade()));
            evaluationReportRankingVo.setCompletionRate(EvaluationUtil.onTimeCompletionRate(evaluationReportRankingVo.getCompleteCount(),
                    evaluationReportRankingVo.getDelayCompleteCount(), evaluationReportRankingVo.getTotalCount()).divide(new BigDecimal("100"),2));
        }
        return list;
    }

    @Override
    public List<EvaluationGradePercentageVo> findGradePercentage(EvaluationReportDto dto) {
        EvaluationReportQueryDto queryDto = getReportQuery(dto);
        if (queryDto == null) {
            return null;
        }
        List<EvaluationGradePercentageVo> list = evaluationResultMapper.findGradePercentage(queryDto);
        if (CollectionUtil.isEmpty(list)) {
            return list;
        }
        Map<String,String> gradMap  = userCenterClient.selectListByPCodes("SC_EVALUATION_GRADE");
        BigDecimal total = new BigDecimal("0");
        for (EvaluationGradePercentageVo vo: list) {
            total = total.add(new BigDecimal(vo.getPercentage()));
        }
        for (EvaluationGradePercentageVo vo: list) {
            vo.setEvaluationGrade(gradMap.get(vo.getEvaluationGrade()));
            vo.setPercentageRate(new BigDecimal(vo.getPercentage()).divide(total,4, BigDecimal.ROUND_HALF_DOWN).multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_DOWN).toString());
        }
        return list;
    }

    @Override
    public List<EvaluationQualifiedNumberVo> countQualifiedNumber(EvaluationReportDto dto, BigDecimal qualifiedValue) {
        EvaluationReportQueryDto queryDto = getReportQuery(dto);
        if (queryDto == null) {
            return null;
        }
        if (queryDto.getCycle() == EvaluationCycleEnums.MONTH.getType()) {
            return null;
        }
        if (queryDto.getCycle() == EvaluationCycleEnums.QUARTER.getType()) {
            queryDto.setMonths(EvaluationUtil.formatList(queryDto.getMonth()));
        }
        queryDto.setCycle(0);
        return evaluationResultMapper.countQualifiedNumber(queryDto, qualifiedValue);
    }

    @Override
    public List<EvaluationPerformanceAvgVo> countPerformanceAvg(EvaluationReportDto dto) {
        EvaluationReportQueryDto queryDto = getReportQuery(dto);
        if (queryDto == null) {
            return null;
        }
        if (queryDto.getCycle() == EvaluationCycleEnums.MONTH.getType()) {
            return null;
        }
        if (queryDto.getCycle() == EvaluationCycleEnums.QUARTER.getType()) {
            queryDto.setMonths(EvaluationUtil.formatList(queryDto.getMonth()));
        }
        queryDto.setCycle(0);
        return evaluationResultMapper.countPerformanceAvg(queryDto);
    }

    @Override
    public List<EvaluationResultVo> listEvaluationResult(EvaluationResultDto dto) {
        EvaluationResultQueryDto queryDto = getEvaluationReportQueryDto(dto);
        if (queryDto == null) {
            return null;
        }
        List<EvaluationResultVo> resultVos = evaluationResultMapper.listEvaluationResult(queryDto);
        formatEvaluationResultVo(resultVos, dto.getCycle());
        return resultVos;
    }


    /***
     * 考评结果参数
     * @author lihui
     * @date 14:55 2021/5/19
     * @param dto : 请求参数
     * @return com.zcxk.evaluation.dto.EvaluationResultQueryDto
     **/
    private EvaluationResultQueryDto getEvaluationReportQueryDto(EvaluationResultDto dto){
        EvaluationResultQueryDto queryDto = new EvaluationResultQueryDto();
        BeanUtils.copyProperties(dto, queryDto);
        // 获取用户权限
        LoginUser currentUser = UserUtil.getCurrentUser();
        if (StringUtils.isEmpty(currentUser.getTenantId())){
            return null;
        }
        queryDto.setTenantId(currentUser.getTenantId());
        queryDto.setProgramItems(currentUser.getProgramItemList());
        queryDto.setUserType("3");
        queryDto.setPermissonType(currentUser.getPermissonType());
        // 季度需要格式化月份
        if (queryDto.getCycle() != null && queryDto.getCycle() == EvaluationCycleEnums.QUARTER.getType()){
            queryDto.setMonth(EvaluationUtil.format(queryDto.getMonth()));
        }
        return queryDto;
    }

    /***
     * 报表参数
     * @author lihui
     * @date 14:54 2021/5/19
     * @param dto : 请求参数
     * @return com.zcxk.evaluation.dto.EvaluationReportQueryDto
     **/
    private EvaluationReportQueryDto getReportQuery(EvaluationReportDto dto){
        EvaluationReportQueryDto queryDto = new EvaluationReportQueryDto();
        BeanUtils.copyProperties(dto, queryDto);
        // 季度需要格式化月份
        if (dto.getCycle() == EvaluationCycleEnums.QUARTER.getType()){
            queryDto.setMonth(EvaluationUtil.format(dto.getMonth()));
        }
        // 获取用户权限
        LoginUser currentUser = UserUtil.getCurrentUser();
        if (StringUtils.isEmpty(currentUser.getTenantId())){
            return null;
        }
        queryDto.setTenantId(currentUser.getTenantId());
        queryDto.setProgramItems(currentUser.getProgramItemList());
        queryDto.setUserType("3");
        queryDto.setPermissonType(currentUser.getPermissonType());
        return queryDto;
    }

    /***
     * t格式化数据
     * @author lihui
     * @date 14:45 2021/5/19
     * @param list : 数据层
     * @param cycle :  季度、月度、年度
     * @return void
     **/
    private void formatEvaluationResultVo(List<EvaluationResultVo> list, int cycle){
        if (CollectionUtil.isEmpty(list)) {
            return;
        }
        Map<String,String> stateMap = userCenterClient.selectListByPCodes("SC_EVALUATION_STATE");
        Map<String,String> gradMap  = userCenterClient.selectListByPCodes("SC_EVALUATION_GRADE");
        // 避免相同的id去缓存取
        Map<String, String> companyOrgNameMap = new HashMap<>();
        Map<String, String> deptOrgNameMap    = new HashMap<>();
        for (EvaluationResultVo vo : list) {
            if (StringUtils.isNotEmpty(vo.getCompanyOrgId())){
                vo.setCompanyOrgName(getOrgName(companyOrgNameMap, vo.getCompanyOrgId()));
            }
            if (StringUtils.isNotEmpty(vo.getDeptOrgId())) {
                vo.setDeptOrgName(getOrgName(deptOrgNameMap, vo.getDeptOrgId()));
            }
            vo.setState(stateMap.get(vo.getState()));
            vo.setEvaluationGrade(gradMap.get(vo.getEvaluationGrade()));
            vo.setCycle(EvaluationUtil.formatCycle(cycle, vo.getYear(), vo.getMonth()));
        }
    }

    /**
    * @Author lihui
    * @Description 避免相同的id去缓存取
    * @Date 14:39 2021/5/8
    * @Param [map, id]
    * @return java.lang.String
    **/
    private String getOrgName(Map<String, String> map, String id){
        String value = map.get(id);
        value = value != null ? value : orgInfoUtil.getOrgName(Integer.parseInt(id));
        map.put(id, value);
        return value;
    }


}
