package com.mortals.xhx.module.perform.service.impl;

import cn.hutool.core.date.DateUtil;
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.model.PageInfo;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.util.DateUtils;
import com.mortals.xhx.base.system.message.MessageService;
import com.mortals.xhx.common.code.*;
import com.mortals.xhx.module.check.model.*;
import com.mortals.xhx.module.check.service.*;
import com.mortals.xhx.module.dingding.CheckDingMsg;
import com.mortals.xhx.module.dingding.personal.service.IDingPersonService;
import com.mortals.xhx.module.perform.dao.PerformAttendAppealDao;
import com.mortals.xhx.module.perform.model.*;
import com.mortals.xhx.module.perform.model.vo.AppealInfo;
import com.mortals.xhx.module.perform.model.vo.AppealSummaryQuery;
import com.mortals.xhx.module.perform.service.PerformAttendAppealFilesService;
import com.mortals.xhx.module.perform.service.PerformAttendAppealService;
import com.mortals.xhx.module.perform.service.PerformRulesCategoryService;
import com.mortals.xhx.module.perform.service.PerformRulesService;
import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.service.StaffService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * PerformAttendAppealService
 * 绩效记录申诉信息 service实现
 *
 * @author zxfei
 * @date 2023-07-12
 */
@Service("performAttendAppealService")
@Slf4j
public class PerformAttendAppealServiceImpl extends AbstractCRUDServiceImpl<PerformAttendAppealDao, PerformAttendAppealEntity, Long> implements PerformAttendAppealService {

    @Autowired
    private CheckAttendRecordService checkAttendRecordService;
    @Autowired
    private CheckReviewRecordService checkReviewRecordService;
    @Autowired
    private CheckComplainRecordService checkComplainRecordService;
    @Autowired
    private CheckEffectRecordService checkEffectRecordService;
    @Autowired
    private CheckGoworkRecordService checkGoworkRecordService;
    @Autowired
    private CheckOtherRecordService checkOtherRecordService;

    @Autowired
    private PerformAttendAppealFilesService performAttendAppealFilesService;

    @Autowired
    private IDingPersonService dingPersonService;
    @Autowired
    private StaffService staffService;
    @Autowired
    private MessageService messageService;
    @Autowired
    private PerformRulesCategoryService categoryService;
    @Autowired
    private PerformRulesService rulesService;


    private void sendCheckDingTalk(PerformAttendAppealEntity entity) {
       // String ruleStr = String.format("%s/%s/%s", PerformTypeEnum.getByValue(entity.getPerformType()).getDesc(), entity.getCategoryName(), entity.getRuleName());
        String ruleStr = String.format("%s/%s/%s", PerformTypeEnum.考勤绩效.getDesc(), entity.getCategoryName(), entity.getRuleName());
        //绩效核查通知
        StaffEntity staffCache = staffService.getCache(entity.getStaffId().toString());
        if (!ObjectUtils.isEmpty(staffCache)) {
            Rest<String> personRest = dingPersonService.getPersonByMobile(staffCache.getPhoneNumber());
            if (YesNoEnum.YES.getValue() == personRest.getCode()) {
                CheckDingMsg checkDingMsg = new CheckDingMsg();
                checkDingMsg.setUserIds(personRest.getData());
                checkDingMsg.setDateTime(DateUtil.formatDateTime(entity.getAppealTime() == null ? new Date() : entity.getAppealTime()));
                checkDingMsg.setRuleStr(ruleStr);
                checkDingMsg.setScore(entity.getScore().toString());
                checkDingMsg.setAppealResult(entity.getAppealResult());
                checkDingMsg.setAppealDesc(entity.getAppealDesc());

                Rest<String> msgRest = messageService.sendDingTalkAppealMsg(checkDingMsg);
            } else {
                log.error("根据手机号码获取人员错误，msg:{}", personRest.getMsg());
            }
        } else {
            log.error("员工未找到,staffId:{}", entity.getStaffId());
        }
    }

    @Override
    public Rest<Void> audit(PerformAttendAppealEntity appeal, Context context) {
        PerformAttendAppealEntity appealEntity = this.get(appeal.getId(), context);
        if (appealEntity.getProcessStatus() == ProcessStatusEnum.已处理.getValue()) {
            throw new AppException("当前申诉已审核！");
        }

        appealEntity.setProcessStatus(ProcessStatusEnum.已处理.getValue());
        appealEntity.setAppealDesc(appeal.getAppealDesc());
        appealEntity.setAppealResult(appeal.getAppealResult());
        appealEntity.setAppealTime(new Date());
        appealEntity.setUpdateUserId(context.getUser().getId());
        appealEntity.setUpdateTime(new Date());
        this.getDao().update(appealEntity);

        PerformRulesEntity ruleCache = rulesService.getCache(appealEntity.getRuleId().toString());
        if (!ObjectUtils.isEmpty(ruleCache)) {
            PerformRulesCategoryEntity categoryEntity = categoryService.get(ruleCache.getCategoryId());
            if (!ObjectUtils.isEmpty(categoryEntity)) {
                appealEntity.setCategoryName(categoryEntity.getName());
            }
        }
        String appealMsg = "申诉成功，返回所扣分数，申诉ID:" + appeal.getId().toString();
        sendCheckDingTalk(appealEntity);
        log.info(appealMsg);

        if (appeal.getAppealResult() == AppealResultEnum.通过.getValue()) {
            if (appeal.getSubAddType() == SubAddTypeEnum.扣除.getValue()) {
                //需增一条记录后 冲销相关核查的记录
                if (PerformTypeEnum.考勤绩效.getValue().equals(appeal.getPerformType())) {
                    CheckAttendRecordEntity checkEntity = checkAttendRecordService.get(appeal.getId(), context);

                    CheckAttendRecordEntity checkAttendRecordEntity = new CheckAttendRecordEntity();
                    checkAttendRecordEntity.initAttrValue();
                    BeanUtils.copyProperties(checkEntity, checkAttendRecordEntity, new String[]{"id", "recordId"});
                    checkAttendRecordEntity.setSubAddType(SubAddTypeEnum.增加.getValue());
                    checkAttendRecordEntity.setSubMethod(SubMethodEnum.申诉冲销.getValue());
                    checkAttendRecordEntity.setRemark(appealMsg);
                    checkAttendRecordService.save(checkAttendRecordEntity, context);
                } else if (PerformTypeEnum.评价差评绩效.getValue().equals(appeal.getPerformType())) {
                    CheckReviewRecordEntity checkEntity = checkReviewRecordService.get(appeal.getId(), context);
                    CheckReviewRecordEntity checkRecordEntity = new CheckReviewRecordEntity();
                    checkRecordEntity.initAttrValue();
                    BeanUtils.copyProperties(checkEntity, checkRecordEntity, new String[]{"id", "recordId"});
                    checkRecordEntity.setSubAddType(SubAddTypeEnum.增加.getValue());
                    checkRecordEntity.setSubMethod(SubMethodEnum.申诉冲销.getValue());
                    checkRecordEntity.setRemark(appealMsg);
                    checkRecordEntity.setCreateTime(new Date());
                    checkRecordEntity.setCreateUserId(this.getContextUserId(context));
                    checkReviewRecordService.save(checkRecordEntity, context);
                } else if (PerformTypeEnum.评价投诉绩效.getValue().equals(appeal.getPerformType())) {
                    CheckComplainRecordEntity checkEntity = checkComplainRecordService.get(appeal.getId(), context);

                    CheckComplainRecordEntity checkRecordEntity = new CheckComplainRecordEntity();
                    checkRecordEntity.initAttrValue();
                    BeanUtils.copyProperties(checkEntity, checkRecordEntity, new String[]{"id", "recordId"});
                    checkRecordEntity.setSubAddType(SubAddTypeEnum.增加.getValue());
                    checkRecordEntity.setSubMethod(SubMethodEnum.申诉冲销.getValue());
                    checkRecordEntity.setRemark(appealMsg);
                    checkRecordEntity.setCreateTime(new Date());
                    checkRecordEntity.setCreateUserId(this.getContextUserId(context));
                    checkComplainRecordService.save(checkRecordEntity, context);

                } else if (PerformTypeEnum.办件绩效.getValue().equals(appeal.getPerformType())) {
                    CheckGoworkRecordEntity checkEntity = checkGoworkRecordService.get(appeal.getId(), context);
                    CheckGoworkRecordEntity checkRecordEntity = new CheckGoworkRecordEntity();
                    checkRecordEntity.initAttrValue();
                    BeanUtils.copyProperties(checkEntity, checkRecordEntity, new String[]{"id", "recordId"});
                    checkRecordEntity.setSubAddType(SubAddTypeEnum.增加.getValue());
                    checkRecordEntity.setSubMethod(SubMethodEnum.申诉冲销.getValue());
                    checkRecordEntity.setRemark(appealMsg);
                    checkRecordEntity.setCreateTime(new Date());
                    checkRecordEntity.setCreateUserId(this.getContextUserId(context));
                    checkGoworkRecordService.save(checkRecordEntity, context);

                } else if (PerformTypeEnum.效能绩效.getValue().equals(appeal.getPerformType())) {
                    CheckEffectRecordEntity checkEntity = checkEffectRecordService.get(appeal.getId(), context);
                    CheckEffectRecordEntity checkRecordEntity = new CheckEffectRecordEntity();
                    checkRecordEntity.initAttrValue();
                    BeanUtils.copyProperties(checkEntity, checkRecordEntity, new String[]{"id", "recordId"});
                    checkRecordEntity.setSubAddType(SubAddTypeEnum.增加.getValue());
                    checkRecordEntity.setSubMethod(SubMethodEnum.申诉冲销.getValue());
                    checkRecordEntity.setRemark(appealMsg);
                    checkRecordEntity.setCreateTime(new Date());
                    checkRecordEntity.setCreateUserId(this.getContextUserId(context));
                    checkEffectRecordService.save(checkRecordEntity, context);

                } else if (PerformTypeEnum.其它绩效.getValue().equals(appeal.getPerformType())) {
                    CheckOtherRecordEntity checkEntity = checkOtherRecordService.get(appeal.getId(), context);
                    CheckOtherRecordEntity checkRecordEntity = new CheckOtherRecordEntity();
                    checkRecordEntity.initAttrValue();
                    BeanUtils.copyProperties(checkEntity, checkRecordEntity, new String[]{"id", "recordId"});
                    checkRecordEntity.setSubAddType(SubAddTypeEnum.增加.getValue());
                    checkRecordEntity.setSubMethod(SubMethodEnum.申诉冲销.getValue());
                    checkRecordEntity.setRemark(appealMsg);
                    checkRecordEntity.setCreateTime(new Date());
                    checkRecordEntity.setCreateUserId(this.getContextUserId(context));
                    checkOtherRecordService.save(checkRecordEntity, context);
                }
            }
        }


        return Rest.ok();
    }

    @Override
    public Rest<List<AppealInfo>> stat(PerformAttendAppealEntity appeal, Context context) {

        PageInfo pageInfo = new PageInfo(20);
        //统计
        String groupName = AppealStatTypeEnum.getByValue(appeal.getStatType()).getDesc();
        PerformAttendAppealQuery query = new PerformAttendAppealQuery();


        if (ObjectUtils.isEmpty(appeal.getAppealTimeStart())) {
            //未设置时间的情况，默认为当月
            query.setCreateTimeStart(DateUtil.beginOfMonth(new Date()).toDateStr());
            query.setCreateTimeEnd(DateUtil.today());
        } else {
            //格式化到指定日期的当月
            query.setCreateTimeStart(DateUtil.beginOfMonth(DateUtil.parse(appeal.getAppealTimeStart()).toJdkDate()).toDateStr());
            query.setCreateTimeEnd(DateUtil.endOfMonth(DateUtil.parse(appeal.getAppealTimeStart()).toJdkDate()).toDateStr());
        }
        query.setGroupList(Arrays.asList(groupName));
        query.setOrderColList(Arrays.asList(new OrderCol("number", OrderCol.DESCENDING)));
        List<AppealInfo> statList = this.getDao().getStatList(query, pageInfo);
        return Rest.ok(statList);
    }

    @Override
    public List<PerformAttendAppealEntity> getAppealSummaryList(AppealSummaryQuery query) {
        if (query == null) {
            query = new AppealSummaryQuery();
            query.setSummaryType(SummaryTopTypeEnum.月.getValue());
        }
        if (query.getSummaryType() == SummaryTopTypeEnum.年.getValue()) {
            query.setCheckTimeStart(DateUtils.getCurrDateTime("yyyy") + "-01-01");
        }
        if (query.getSummaryType() == SummaryTopTypeEnum.月.getValue()) {
            query.setCheckTimeStart(DateUtils.getCurrDateTime("yyyy-MM") + "-01");
        }
        if (query.getSummaryType() == SummaryTopTypeEnum.日.getValue()) {
            query.setCheckTimeStart(DateUtils.getCurrStrDate());
        }
        query.setCheckTimeEnd(DateUtils.getCurrStrDate());
        return dao.getAppealSummaryList(query);
    }


    @Override
    protected void saveAfter(PerformAttendAppealEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getPerformAttendAppealFilesList())) {
            entity.getPerformAttendAppealFilesList().stream().peek(item -> {
                item.setAppealId(entity.getId());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
            }).count();
            performAttendAppealFilesService.save(entity.getPerformAttendAppealFilesList());
        }
        super.saveAfter(entity, context);
    }

    @Override
    protected void updateAfter(PerformAttendAppealEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getPerformAttendAppealFilesList())) {
            Long[] performAttendAppealFilesIds = performAttendAppealFilesService.find(new PerformAttendAppealFilesQuery().appealId(entity.getId())).stream().map(PerformAttendAppealFilesEntity::getId).toArray(Long[]::new);
            performAttendAppealFilesService.remove(performAttendAppealFilesIds, context);
            entity.getPerformAttendAppealFilesList().stream().peek(item -> {
                item.setAppealId(entity.getId());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
                item.setUpdateUserId(this.getContextUserId(context));
                item.setUpdateTime(new Date());
            }).count();
            performAttendAppealFilesService.save(entity.getPerformAttendAppealFilesList());
        }
        super.updateAfter(entity, context);
    }

    @Override
    protected void removeAfter(Long[] ids, Context context, int result) throws AppException {
        List<PerformAttendAppealFilesEntity> performAttendAppealFileslist = performAttendAppealFilesService.find(new PerformAttendAppealFilesQuery().appealIdList(Arrays.asList(ids)));
        performAttendAppealFilesService.removeList(performAttendAppealFileslist, context);
        super.removeAfter(ids, context, result);
    }

}