package com.tofly.gpsboot.service.audit.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tofly.api.UserTaskClient;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.gpsboot.common.Constant;
import com.tofly.gpsboot.common.system.*;
import com.tofly.gpsboot.exception.BusinessException;
import com.tofly.gpsboot.service.audit.IAuditPlanMtServer;
import com.tofly.gpsboot.service.comm.IAuditService;
import com.tofly.gpsboot.service.mq.IAuditMessageService;
import com.tofly.gpsboot.service.paln.CheckhistoryService;
import com.tofly.gpsboot.service.paln.PlanMtService;
import com.tofly.gpsboot.service.paln.PlanchildtypeService;
import com.tofly.gpsboot.service.paln.PlantypeService;
import com.tofly.gpsboot.service.paln.task.PlanService;
import com.tofly.gpsboot.service.paln.task.PlanchildService;
import com.tofly.gpsboot.util.DateTimeUtil;
import com.tofly.pojo.comm.Audit;
import com.tofly.pojo.message.Usertask;
import com.tofly.pojo.plan.*;
import com.tofly.pojo.plan.dto.ReportAuditDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Zev
 */
@Service("AUDIT_TYPE_PLAN_MT")
public class AuditPlanMtServerImpl implements IAuditPlanMtServer {
    @Autowired
    private PlanService planService;

    @Autowired
    private PlanMtService planMtService;

    @Autowired
    private PlanchildService planchildService;

    @Autowired
    private CheckhistoryService checkhistoryService;

    @Autowired
    private IAuditMessageService iAuditMessageService;
    @Autowired
    private UserTaskClient userTaskClient;

    @Autowired
    private IAuditService auditService;

    @Autowired
    private PlantypeService plantypeService;

    @Autowired
    private PlanchildtypeService planchildtypeService;

    @Override
    public void audit(ReportAuditDto dto) throws BusinessException {
        Long id = dto.getId();
        Long auditId = dto.getAuditId();
        String auditResult = dto.getAuditResult();
        String auditNotes = dto.getAuditNotes();
        List<PlanMt> planMtList = dto.getPlanMtList();
        // 判断传值问题
        if (null == id || null == auditId || StringUtils.isEmpty(auditResult) || planMtList.isEmpty()) {
            throw new BusinessException(Constant.DATA_VALIDATION_CODE, Constant.DATA_VALIDATION + " 审核计划id= " + id + ",审核人= " + auditId + ",审核状态= " + auditResult + ",维护审核列表" + planMtList.toString());
        }
        List<Audit> auditList = auditService.list(new QueryWrapper<Audit>().lambda()
                .ge(Audit::getAuditType, AuditTypeEnum.AUDIT_TYPE_PLAN_MT.getCode())
                .ge(Audit::getAuditUser, auditId)
                .ge(Audit::getAuditPlanId, id)
                .ge(Audit::getAuditState, AuditSateEnum.AUDIT_UNCOMMITTED.getCode()));
        // 判断当前是否有审核信息
        if (null != auditList && auditList.size() > 0) {
            Date date = new Date();
            Plan plan = planService.getById(id);
            Audit audit = auditList.get(0);
            audit.setAuditTime(date);
            audit.setAuditUser(auditId);
            audit.setAuditState(auditResult);
            audit.setAuditNote(auditNotes);

            if (AuditSateEnum.AUDIT_YES.getCode().equals(auditResult)) {
                // 计划状态设置为 4 已完成
                // 完成当前计划id下所有代办信息
                plan.setPlanState(PlanStateEnum.PLAN_STATE_PLAN_COMPLETE.getCode());
                Usertask usertask = new Usertask();
                usertask.setTableName(MessageTopicEnum.TASK_PLAN_SEND.getTableName());
                usertask.setTableId(id);
                List<Usertask> result = userTaskClient.getUserTaskInfo(usertask).getResult();
                if (null != result && result.size() > 0) {
                    result.forEach(info -> {
                        info.setHandleTime(DateTimeUtil.convertLDTToDate(LocalDateTime.now()));
                        info.setIshandle(UserTaskStateEnumEnum.IS_HANDLER_COMPLETED.getCode());
                        userTaskClient.updateById(info);
                    });
                }
            } else {
                // 计划状态设置为 5 已开始未执行
                plan.setPlanState(PlanStateEnum.PLAN_STATE_EXECUTION_NOT_STARTED.getCode());
                // 判断当前是否传入 任务延期时间
                if (null != dto.getEndTime()) {
                    plan.setPlanEnddate(dto.getEndTime());
                }
                // 将维护计划 设置为历史
                planMtList.forEach(i -> {
                    i.setIsHis("1");
                });
                // 获取同意数据分组列表
                Set<PlanMt> success = planMtList.stream().filter(i -> AuditSateEnum.AUDIT_YES.getCode().equals(i.getAuditResult())).collect(Collectors.toSet());
                int sum = success.size();
                // 计算当前设备完成率
                List<Plantype> planTypeList = plantypeService.list(new QueryWrapper<Plantype>().lambda().eq(Plantype::getPlanId, id));
                // 一个计划一个类型
                Plantype plantype = planTypeList.get(0);
                BigDecimal totalCount = plantype.getTotalCount();
                plantype.setOverEquipmentCount(BigDecimal.valueOf(sum));
                BigDecimal multiply = BigDecimal.valueOf(sum).divide(totalCount, 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
                plantype.setEquipmentRate(multiply);
                plantype.setLossEquipmentRate((totalCount.subtract(BigDecimal.valueOf(sum))).divide(totalCount, 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)));
                plantypeService.updateById(plantype);
                // 计算个人完成率
                // 按照用户分组成功数据列表
                Map<Long, List<PlanMt>> userGroupList = success.stream().collect(Collectors.groupingBy(PlanMt::getMaintainUserId));
                userGroupList.forEach((userId,v)->{
                    List<Planchild> list = planchildService.list(new QueryWrapper<Planchild>().lambda()
                            .eq(Planchild::getPlanId, id).eq(Planchild::getRespUser, userId));
                    Planchild planchild = list.get(0);
                    List<Planchildtype> planChildTypeList = planchildtypeService.list(new QueryWrapper<Planchildtype>().lambda()
                            .eq(Planchildtype::getPlanChildId, planchild.getId())
                            .eq(Planchildtype::getUserId, userId));
                    BigDecimal bigDecimal = BigDecimal.valueOf(v.size());
                    if(null!=planChildTypeList && planChildTypeList.size()>0){
                        Planchildtype planchildtype = planChildTypeList.get(0);
                        BigDecimal add = bigDecimal.add(planchildtype.getOverEquipmentCount());
                        planchildtype.setOverEquipmentCount(add);
                        planchildtype.setEquipmentRate(add.divide(totalCount, 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)));
                        planchildtypeService.updateById(planchildtype);
                    }else {
                        Planchildtype planchildtype = new Planchildtype();
                        planchildtype.setPlanChildId(planchild.getId());
                        planchildtype.setUserId(planchild.getRespUser());
                        planchildtype.setTotalCount(totalCount);
                        planchildtype.setTotalLength(plantype.getTotalLength());
                        planchildtype.setTypeId(plantype.getTypeId());
                        planchildtype.setOverEquipmentCount(BigDecimal.valueOf(sum));
                        planchildtype.setEquipmentRate(multiply);
                        planchildtypeService.save(planchildtype);
                    }
                });

                // 审核人待办事项处理
                Usertask usertask = new Usertask();
                usertask.setTableName(MessageTopicEnum.REPORT_PLAN_MT.getTableName());
                usertask.setHandleUser(auditId);
                usertask.setTableId(id);
                List<Usertask> result = userTaskClient.getUserTaskInfo(usertask).getResult();
                if (null != result && result.size() > 0) {
                    result.forEach(task->{
                        task.setHandleTime(DateTimeUtil.convertLDTToDate(LocalDateTime.now()));
                        task.setHandleUser(auditId);
                        task.setIshandle(UserTaskStateEnumEnum.IS_HANDLER_COMPLETED.getCode());
                        userTaskClient.updateById(task);
                    });

                }
            }
            // 更新审核信息
            auditService.updateById(audit);
            // 批量修改维护计划审核信息
            planMtService.updateBatchById(planMtList);

            // 存入当前计划审批历史信息
            checkhistoryService.recordHis(AuditTypeEnum.AUDIT_TYPE_PLAN_MT.getCode(), id, auditResult, auditNotes, auditId, date);

            // 修改计划信息
            planService.updateById(plan);

            // 通知审核对象mq消息 给上报对象到消息提示列表
            iAuditMessageService.auditPlanMt(dto, planMtList.stream().map(PlanMt::getMaintainUserId).collect(Collectors.toSet()));
        } else {
            throw new BusinessException(Constant.AUDIT_SEL_NULL_CODE, Constant.AUDIT_SEL_NULL);
        }
    }


}
