package com.mortals.xhx.module.staff.web;

import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.annotation.UnAuth;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.OrderCol;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.util.DateUtils;
import com.mortals.framework.util.StringUtils;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.common.pdu.WeightPdu;
import com.mortals.xhx.common.utils.StaffPerformUtil;
import com.mortals.xhx.module.check.model.vo.StaffCheckSummaryQuery;
import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.model.StaffPerformSummaryEditEntity;
import com.mortals.xhx.module.staff.model.StaffPerformSummaryEditQuery;
import com.mortals.xhx.module.staff.model.StaffPerformSummaryEntity;
import com.mortals.xhx.module.staff.service.StaffPerformSummaryEditService;
import com.mortals.xhx.module.staff.service.StaffService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static com.mortals.xhx.common.key.ParamKey.SYS_PARAM_WEIGHT;
import static com.mortals.xhx.common.key.RedisKey.KEY_CHECK_SUMMARY_CACHE;
import static com.mortals.xhx.common.key.RedisKey.STAFF_PERFORM_SUMMARY;
/**
*
* 员工绩效统计
*
* @author zxfei
* @date 2025-04-10
*/
@RestController
@RequestMapping("staff/perform/summary/edit")
public class StaffPerformSummaryEditController extends BaseCRUDJsonBodyMappingController<StaffPerformSummaryEditService,StaffPerformSummaryEditEntity,Long> {

    @Autowired
    private ParamService paramService;
    @Autowired
    private StaffService staffService;
    @Autowired
    private ICacheService cacheService;

    private static String SUMMARY_TASK_KEY = "staffPerformSummaryTask:run";

    private ExecutorService executorService = Executors.newCachedThreadPool();

    public StaffPerformSummaryEditController() {
        super.setModuleDesc("员工绩效统计");
    }

    @Override
    protected void init(Map<String, Object> model, Context context) {
        super.init(model, context);
    }

    @Override
    protected void saveBefore(StaffPerformSummaryEditEntity entity, Map<String, Object> model, Context context) throws AppException {
        StaffPerformSummaryEditQuery query = new StaffPerformSummaryEditQuery();
        query.setStaffName(entity.getStaffName());
        query.setDeptId(entity.getDeptId());
        query.setSalaId(entity.getSalaId());
        query.setWorkNum(entity.getWorkNum());
        query.setMonth(entity.getMonth());
        query.setYear(entity.getYear());
        StaffPerformSummaryEditEntity temp = service.selectOne(query);
        if(temp!=null && entity.getId()==null){
            throw new AppException("当月已存在绩效数据");
        }
        entity.setDataType(2);
        String value = paramService.getValueByKey(SYS_PARAM_WEIGHT);
        WeightPdu weightPdu;
        if (ObjectUtils.isEmpty(value)){
            weightPdu = new WeightPdu();
        }else {
            weightPdu = JSONObject.parseObject(value,WeightPdu.class);
        }
        computeSummary(entity,weightPdu);
        super.saveBefore(entity, model, context);
    }

    /**
     * 根据页面总分逆向运算各指标扣减分数
     * @param StaffPerformSummaryEditEntity
     * @param weightPdu
     */
    private void computeSummary(StaffPerformSummaryEditEntity StaffPerformSummaryEditEntity, WeightPdu weightPdu){

        BigDecimal reviewScore = StaffPerformSummaryEditEntity.getReviewScore().subtract(weightPdu.reviewWeight());//评价
        StaffPerformSummaryEditEntity.setReviewScore(reviewScore.setScale(2,BigDecimal.ROUND_DOWN));

        BigDecimal attendScore = StaffPerformSummaryEditEntity.getAttendScore().subtract(weightPdu.attendWeight());//考勤
        StaffPerformSummaryEditEntity.setAttendScore(attendScore.setScale(2,BigDecimal.ROUND_DOWN));

        BigDecimal complainScore = StaffPerformSummaryEditEntity.getComplainScore().divide(weightPdu.selfWeight(),2,BigDecimal.ROUND_DOWN);  //自评
        StaffPerformSummaryEditEntity.setComplainScore(complainScore.setScale(2,BigDecimal.ROUND_DOWN));

        BigDecimal goworkScore = StaffPerformSummaryEditEntity.getGoworkScore().subtract(weightPdu.goworkWeight());//办件
        StaffPerformSummaryEditEntity.setGoworkScore(goworkScore.setScale(2,BigDecimal.ROUND_DOWN));

        BigDecimal effectScore = StaffPerformSummaryEditEntity.getEffectScore().subtract(weightPdu.effectWeight());//效能
        StaffPerformSummaryEditEntity.setEffectScore(effectScore.setScale(2,BigDecimal.ROUND_DOWN));
        BigDecimal erro = new BigDecimal(0);
        erro = erro.add(StaffPerformSummaryEditEntity.getReviewScore());
        erro = erro.add(StaffPerformSummaryEditEntity.getAttendScore());
        if(StaffPerformSummaryEditEntity.getComplainScore().compareTo(BigDecimal.ZERO)!=0){
            BigDecimal complainScoreErro = StaffPerformUtil.SCORE100.subtract(StaffPerformSummaryEditEntity.getComplainScore());
            erro = erro.add(BigDecimal.ZERO.subtract(complainScoreErro));
        }
        erro = erro.add(StaffPerformSummaryEditEntity.getGoworkScore());
        erro = erro.add(StaffPerformSummaryEditEntity.getEffectScore());
        StaffPerformSummaryEditEntity.setErrorScore(erro);
        StaffPerformUtil.computeSummary(StaffPerformSummaryEditEntity,weightPdu);
    }

    @Override
    protected void doListBefore(StaffPerformSummaryEditEntity query, Map<String, Object> model, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(query.getOrderColList())) {
//            query.getOrderColList().add(new OrderCol("year",OrderCol.DESCENDING));
//            query.getOrderColList().add(new OrderCol("month",OrderCol.DESCENDING));
        }
        List<OrderCol> orderColList = new ArrayList();
        if(query.getSortKind()!=null && query.getSortKind()==1){
            orderColList.add(new OrderCol("totalScore",OrderCol.DESCENDING));
        }else if(query.getSortKind()!=null && query.getSortKind()==2) {
            orderColList.add(new OrderCol("totalScore",OrderCol.ASCENDING));
        }else {
            orderColList.add(new OrderCol("salaName",OrderCol.ASCENDING));
            orderColList.add(new OrderCol("deptName",OrderCol.ASCENDING));
        }
        query.setOrderColList(orderColList);
    }

    @Override
    protected int doListAfter(StaffPerformSummaryEditEntity query, Map<String, Object> model, Context context) throws AppException {
        String value = paramService.getValueByKey(SYS_PARAM_WEIGHT);
        WeightPdu weightPdu;
        if (ObjectUtils.isEmpty(value)){
            weightPdu = new WeightPdu();
        }else {
            weightPdu = JSONObject.parseObject(value,WeightPdu.class);
        }
        this.addDict(model,"weightPdu",weightPdu);
        String summaryTime =  cacheService.get(STAFF_PERFORM_SUMMARY);
        if(StringUtils.isNotEmpty(summaryTime)){
            this.addDict(model,"summaryTime",summaryTime);
        }else {
            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.DAY_OF_MONTH,-1);
            summaryTime = DateUtils.getDateTime(cal.getTime(),"yyyy-MM-dd");
            this.addDict(model,"summaryTime", summaryTime+" 22:00:00");
        }
        return super.doListAfter(query,model,context);
    }

    @Override
    protected int viewAfter(Long id, Map<String, Object> model, StaffPerformSummaryEditEntity entity, Context context) throws AppException {
        StaffEntity staffEntity = staffService.get(entity.getStaffId());
        if(staffEntity!=null){
            entity.setWorkNum(staffEntity.getWorkNum());
            entity.setPhoneNumber(staffEntity.getPhoneNumber());
        }
        return 1;
    }

    @PostMapping({"sync"})
    @UnAuth
    public Rest<Object> sync(@RequestBody StaffCheckSummaryQuery query) {
        Rest<Object> ret = new Rest();
        Map<String, Object> model = new HashMap();
        Context context = this.getContext();
        String busiDesc = "执行考勤汇总任务";
        int code=1;
        try {
            String verify = cacheService.get(SUMMARY_TASK_KEY);
            if(StringUtils.isNotEmpty(verify)&&verify.equals("true")){
                throw new AppException("同步任务正在执行，请勿重复操作");
            }
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    cacheService.setnx(SUMMARY_TASK_KEY,"true",90);
                    if(StringUtils.isNotEmpty(query.getCheckTimeStart())) {
                        Date date = DateUtils.StrToDateTime(query.getCheckTimeStart());
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTime(date);
                        int year = calendar.get(Calendar.YEAR);
                        int month = calendar.get(Calendar.MONTH) + 1;
                        service.syncStaffPerformSummary(year,month,query.getStaffId());
                    }
                }
            });
//            cacheService.setnx(SUMMARY_TASK_KEY,"false",60);
//            if(StringUtils.isNotEmpty(query.getCheckTimeStart())) {
//                Date date = DateUtils.StrToDateTime(query.getCheckTimeStart());
//                Calendar calendar = Calendar.getInstance();
//                calendar.setTime(date);
//                int year = calendar.get(Calendar.YEAR);
//                int month = calendar.get(Calendar.MONTH) + 1;
//                service.syncStaffPerformSummary(year,month,query.getStaffId());
//            }
            model.put("message_info","开始执行绩效汇总同步,请稍后查看");
        } catch (Exception var9) {
            code = -1;
            this.doException(this.request, busiDesc, model, var9);
        }
        ret.setCode(code);
        ret.setMsg(model.get("message_info") == null ? "" : model.remove("message_info").toString());
        return ret;
    }

    @Override
    public void doExportBefore(Context context, StaffPerformSummaryEditEntity query, List<String> properties) throws AppException {
        if(CollectionUtils.isNotEmpty(query.getProperties())){
            properties.addAll(query.getProperties());
        }
    }
}