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


import com.alibaba.fastjson.JSON;
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.IAuditConstructionSiteEliminationServer;
import com.tofly.gpsboot.service.build.BuildService;
import com.tofly.gpsboot.service.build.BuildplanService;
import com.tofly.gpsboot.service.build.BulidclearService;
import com.tofly.gpsboot.service.mq.IAuditMessageService;
import com.tofly.gpsboot.service.paln.CheckhistoryService;
import com.tofly.gpsboot.service.paln.PlantypeService;
import com.tofly.gpsboot.service.paln.task.PlanInspectUserService;
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.build.Build;
import com.tofly.pojo.build.Buildplan;
import com.tofly.pojo.build.Bulidclear;
import com.tofly.pojo.message.Usertask;
import com.tofly.pojo.plan.Plan;
import com.tofly.pojo.plan.PlanInspectUser;
import com.tofly.pojo.plan.Planchild;
import com.tofly.pojo.plan.Plantype;
import com.tofly.pojo.plan.dto.ReportAuditDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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


/**
 * 工地监护消除上报 审核
 *
 * @author Zev
 */
@Service("AUDIT_TYPE_CONSTRUCTION_SITE_ELIMINATION")
public class AuditConstructionSiteEliminationServiceImpl implements IAuditConstructionSiteEliminationServer {
    @Autowired
    private IAuditMessageService iAuditMessageService;

    @Autowired
    private CheckhistoryService checkhistoryService;

    @Autowired
    private BuildService buildService;

    @Autowired
    private BulidclearService bulidclearService;

    @Autowired
    private UserTaskClient userTaskClient;

    @Autowired
    private PlanService planService;

    @Autowired
    private PlanchildService planchildService;

    @Autowired
    private PlantypeService plantypeService;
    @Autowired
    private BuildplanService buildplanService;

    @Autowired
    private PlanInspectUserService planInspectUserService;

    @Override
    public void audit(ReportAuditDto dto) throws BusinessException {
        Long id = dto.getId();

        Bulidclear bulidclear = bulidclearService.getById(id);
        Long buildId = bulidclear.getBuildId();
        Build info = buildService.getById(buildId);
        // 当前工地监护消除记录审核状态为不因该为通过
        if (AuditSateEnum.AUDIT_YES.getCode().equals(bulidclear.getAuditResult())) {
            throw new BusinessException(Constant.AUDIT_NOT_UNCOMMITTED_CODE, Constant.AUDIT_NOT_UNCOMMITTED);
        }
        String auditResult = dto.getAuditResult();
        Date date = DateTimeUtil.convertLDTToDate(LocalDateTime.now());
        String auditNotes = dto.getAuditNotes();
        Long auditId = info.getAuditUser();
        // 审核时间
        bulidclear.setAuditTime(date);
        // 审核人(同派工人)
        bulidclear.setAuditUser(auditId);
        // 审核意见
        bulidclear.setAuditResult(auditResult);
        bulidclear.setAuditNotes(auditNotes);

        if (AuditSateEnum.AUDIT_YES.getCode().equals(auditResult)) {
            // 工地监护主计划状态变为 已结束,未完成的自动完成
            info.setState(BuildSateEnum.BUILD_SATE_YES_ELIMINATE.getCode());
            // 对应的巡检计划状态全部变成4 计划完成
            Set<Long> buildPlanIdList = buildplanService.list(new QueryWrapper<Buildplan>().lambda().eq(Buildplan::getBuildId, buildId)).stream().map(Buildplan::getPlanId).collect(Collectors.toSet());
            List<Plan> list = planService.list(new QueryWrapper<Plan>().lambda().in(Plan::getId, buildPlanIdList));
            list.forEach(i->i.setPlanState(PlanStateEnum.PLAN_STATE_PLAN_COMPLETE.getCode()));
            planService.updateBatchById(list);

            //计划汇总
            List<Plantype> planTypeList=plantypeService.list(new QueryWrapper<Plantype>().lambda()
                    .in(Plantype::getPlanId,buildPlanIdList));

          //子计划完成情况，归属到消除人上面
            List<Planchild> planChildList=planchildService.list(new QueryWrapper<Planchild>().lambda()
                    .in(Planchild::getPlanId,buildPlanIdList).eq(Planchild::getRespUser, bulidclear.getSubmitUser()));
           if(planTypeList!=null && planChildList!=null &&planChildList.size()>0){
              planChildList.forEach(a->{
                Plantype plantypeFinish= planTypeList.stream().filter(m->m.getPlanId().equals(a.getPlanId())).findFirst().orElse(new Plantype());
                if(plantypeFinish!=null && plantypeFinish.getPlanId()!=null){
                    if(plantypeFinish.getTotalLength()==null){
                        plantypeFinish.setTotalLength(BigDecimal.ZERO);
                    }
                   if(plantypeFinish.getTotalCount()==null){
                        plantypeFinish.setTotalCount(BigDecimal.ZERO);
                    }
                    if(plantypeFinish.getOverLength()==null){
                        plantypeFinish.setOverLength(BigDecimal.ZERO);
                    }
                    if(plantypeFinish.getOverCount()==null){
                        plantypeFinish.setOverCount(BigDecimal.ZERO);
                    }

                   BigDecimal LastLength=plantypeFinish.getTotalLength().subtract(plantypeFinish.getOverLength());
                   BigDecimal LastCount=plantypeFinish.getTotalCount().subtract(plantypeFinish.getOverCount());
                 //有剩余未完成的
                  if(LastCount.compareTo(BigDecimal.ZERO)>0){
                      BigDecimal overCount=a.getOverCount().add(LastCount);
                      if(overCount.compareTo(plantypeFinish.getTotalCount())>0){
                          overCount=plantypeFinish.getTotalCount();
                      }
                      a.setOverCount(overCount);

                  }
                  if(LastLength.compareTo(BigDecimal.ZERO)>0){
                        BigDecimal overLength=a.getOverLen().add(LastLength);
                        if(overLength.compareTo(plantypeFinish.getTotalLength())>0){
                            overLength=plantypeFinish.getTotalLength();
                        }
                        a.setOverLen(overLength);

                    }
                }
                a.setPlanState(PlanStateEnum.PLAN_STATE_PLAN_COMPLETE.getCode());

            });
              planchildService.updateBatchById(planChildList);
           }
           if(planTypeList!=null && planChildList.size()>0){
            //总计划
            planTypeList.forEach(a->{
                a.setOverLength(a.getTotalLength());
                a.setOverCount(a.getTotalCount());
                a.setPercent(a.getCompletionRate());

            });
            plantypeService.updateBatchById(planTypeList);
           }


            // 完成处理当前工地待办计划任务信息
            bulidclearService.clearBuildUserTaskPlan(buildId);

        } else {
            // 审核不通过,上报状态再设置为 待上报
            info.setIsSubmit(ReportSateEnum.REPORT_UNCOMMITTED.getCode());
            // 工地监护主计划状态变为 已结束
            info.setState(BuildSateEnum.BUILD_SATE_PATROL.getCode());
        }
        buildService.updateById(info);
        bulidclearService.updateById(bulidclear);
        // 存入当前计划审批历史信息
        checkhistoryService.recordHis(AuditTypeEnum.AUDIT_TYPE_CONSTRUCTION_SITE_ELIMINATION.getCode(), id, auditResult, auditNotes, auditId, date);

        // 发送mq消息(计划审核成功/失败)给上报对象到消息提示列表
        // 通知审核对象mq消息
        iAuditMessageService.auditTypeConstructionSiteElimination(JSON.toJSONString(info));
        // 待办事项处理
        Usertask usertask = new Usertask();
        usertask.setTableName(MessageTopicEnum.REPORT_CONSTRUCTION_SITE_ELIMINATION.getTableName());
        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(SecurityUtils.getUserId());
                task.setIshandle(UserTaskStateEnumEnum.IS_HANDLER_COMPLETED.getCode());
                userTaskClient.updateById(task);
            });
        }
    }
}
