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.IAuditRepairOrderOverServer;
import com.tofly.gpsboot.service.comm.IAuditService;
import com.tofly.gpsboot.service.maintain.RepairorderService;
import com.tofly.gpsboot.service.maintain.RepairrecordService;
import com.tofly.gpsboot.service.maintain.RepairuserService;
import com.tofly.gpsboot.service.mq.IAuditMessageService;
import com.tofly.gpsboot.service.paln.CheckhistoryService;
import com.tofly.gpsboot.util.DateTimeUtil;
import com.tofly.pojo.comm.Audit;
import com.tofly.pojo.maintain.Repairorder;
import com.tofly.pojo.maintain.Repairrecord;
import com.tofly.pojo.maintain.Repairuser;
import com.tofly.pojo.message.Usertask;
import com.tofly.pojo.plan.dto.ReportAuditDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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 BZ-DJJ
 */
@Service("AUDIT_REPAIR_ORDER_OVER")
@Slf4j
public class AuditRepairOrderOverServerImpl implements IAuditRepairOrderOverServer {
    @Autowired
    private RepairrecordService repairrecordService;
    @Autowired
    private RepairorderService repairorderService;
    @Autowired
    private RepairuserService repairuserService;
    @Autowired
    private UserTaskClient userTaskClient;
    @Autowired
    private CheckhistoryService checkhistoryService;
    @Autowired
    private IAuditMessageService iAuditMessageService;
    @Autowired
    private IAuditService iAuditService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void audit(ReportAuditDto dto) throws BusinessException {
        Long id = dto.getId();
        Long auditId = dto.getAuditId();
        String auditResult = dto.getAuditResult();
        String auditNotes = dto.getAuditNotes();
        // 获取审批链
        List<Audit> list = iAuditService.list(new QueryWrapper<Audit>().lambda().eq(Audit::getAuditType, AuditTypeEnum.AUDIT_TYPE_REPAIR_RECORD.getCode()).eq(Audit::getAuditPlanId, id));
        if (null != list && list.size() > 0) {
            // 判断当前审核人是否拥有审核当前对象的权力
            // 不支持对应的同一个负责人审批多次
            List<Audit> auditList = list.stream().filter(i -> auditId.equals(i.getAuditUser()) && AuditSateEnum.AUDIT_UNCOMMITTED.getCode().equals(i.getAuditState())).collect(Collectors.toList());
            if (auditList.size() > 0) {
                Audit audit = auditList.get(0);
                Date date = DateTimeUtil.convertLDTToDate(LocalDateTime.now());
                // 修改审核对象 审核时间/审核说明/审核状态
                audit.setAuditTime(date);
                audit.setAuditNote(auditNotes);
                audit.setAuditState(auditResult);
                // 当前审批是否通过 处理逻辑
                Set<Long> longSet = this.sendRepairUser(id, auditResult, date);
                // 更新当前审批对象
                iAuditService.updateById(audit);
                if(AuditSateEnum.AUDIT_NO.getCode().equals(auditResult)){
                    // 存入当前计划审批历史信息
                    checkhistoryService.recordHis(AuditTypeEnum.AUDIT_TYPE_REPAIR_RECORD.getCode(), id, auditResult, auditNotes, auditId, date);
                }

                // 通知上报对象mq消息
                iAuditMessageService.auditTypeRepairRecord(dto,longSet);

            } else {
                throw new BusinessException(Constant.PLAN_DISPATCHING_AUDIT_ERROR_CODE, Constant.PLAN_DISPATCHING_AUDIT_ERROR);
            }
        } else {
            throw new BusinessException(Constant.PLAN_DISPATCHING_AUDIT_ERROR_CODE, Constant.PLAN_DISPATCHING_AUDIT_ERROR);
        }

    }

    private Set<Long> sendRepairUser(Long repairOrderId, String auditResult, Date date) {
        List<Repairuser> list = repairuserService.list(new QueryWrapper<Repairuser>().lambda().eq(Repairuser::getRepairId, repairOrderId));
        list.forEach(info -> {
            if (AuditSateEnum.AUDIT_YES.getCode().equals(auditResult)) {
                // 通过个人任务状态改为4已完成
                info.setState(OrderStateEnum.ORDER_STATE_PROCESSING_COMPLETE.getCode());
            } else {
                // 不通过个人任务计划 状态改为3正在执行 系统用时清空 实际完成个数清空
                info.setState(OrderStateEnum.ORDER_STATE_BEING_PERFORMED.getCode());
                info.setRealTime(BigDecimal.ZERO.doubleValue());
                info.setOverNum(BigDecimal.ZERO.longValue());
            }

        });
        repairuserService.updateBatchById(list);
        if (AuditSateEnum.AUDIT_NO.getCode().equals(auditResult)) {
            List<Long> collect = list.stream().map(Repairuser::getId).collect(Collectors.toList());
            List<Repairrecord> repairrecords = repairrecordService.list(new QueryWrapper<Repairrecord>().lambda().in(Repairrecord::getRepairUserid, collect));
            repairrecords.forEach(info -> {
                if(AuditSateEnum.AUDIT_YES.getCode().equals(auditResult)){
                    info.setState(AuditSateEnum.AUDIT_YES.getCode());
                }else {
                    // 不通过过程上报有效状态设置为 0 无效
                    info.setFlag(IsValidEnum.IS_VALID_NO.getCode());
                    info.setState(AuditSateEnum.AUDIT_NO.getCode());
                }

            });
            repairrecordService.updateBatchById(repairrecords);
        }
        Repairorder repairorder = repairorderService.getById(repairOrderId);
        if(AuditSateEnum.AUDIT_YES.getCode().equals(auditResult)){
            repairorder.setState(OrderStateEnum.ORDER_STATE_PROCESSING_COMPLETE.getCode());
            repairorder.setOverTime(date);
            // 判断当前工单是否类型是否为热线工单
            String orderSource = repairorder.getOrderSource();
            if(OrderSourceEnum.ORDER_SOURCE_HOTLINE.getCode().equals(orderSource)){

                // TODO 若异常则回滚
            }
            // 待办事项处理
            Usertask usertask = new Usertask();
            usertask.setTableName(MessageTopicEnum.AUDIT_REPAIR_RECORD.getTableName());
            usertask.setHandleUser(SecurityUtils.getUserId());
            usertask.setTableId(repairOrderId);
            List<Usertask> result = userTaskClient.getUserTaskInfo(usertask).getResult();
            if (null != result && result.size() > 0) {
                Usertask task = result.get(0);
                task.setHandleTime(date);
                task.setHandleUser(SecurityUtils.getUserId());
                task.setIshandle(UserTaskStateEnumEnum.IS_HANDLER_COMPLETED.getCode());
                userTaskClient.updateById(task);
            }
        }else {
            repairorder.setState(OrderStateEnum.ORDER_STATE_BEING_PERFORMED.getCode());
        }

        repairorderService.updateById(repairorder);

        return list.stream().map(Repairuser::getRespUser).collect(Collectors.toSet());
    }

}
