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

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tofly.api.GdglinfoClient;
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.PipeMfRecordService;
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.mq.IMessageRecipientService;
import com.tofly.gpsboot.service.paln.CheckhistoryService;
import com.tofly.gpsboot.util.DateTimeUtil;
import com.tofly.pojo.comm.Audit;
import com.tofly.pojo.maintain.PipeMfRecord;
import com.tofly.pojo.maintain.Repairorder;
import com.tofly.pojo.maintain.Repairrecord;
import com.tofly.pojo.maintain.Repairuser;
import com.tofly.pojo.message.Messagepush;
import com.tofly.pojo.message.Usertask;
import com.tofly.pojo.plan.dto.ReportAuditDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
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 PipeMfRecordService pipeMfRecordService;
    @Autowired
    private RepairuserService repairuserService;
    @Autowired
    private UserTaskClient userTaskClient;
    @Autowired
    private CheckhistoryService checkhistoryService;
    @Autowired
    private IAuditMessageService iAuditMessageService;
    @Autowired
    private IAuditService iAuditService;
    @Autowired
    private GdglinfoClient gdglinfoClient;
    @Autowired
    private IMessageRecipientService messageRecipientService;
    @Value("${gps.plan.web.repairOrder}")
    private String planWebRepairOrderRouteIp;
    @Value("${gps.plan.app.repairOrder}")
    private String planAppRepairOrderRouteIp;

    @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, auditId);
                // 更新当前审批对象
                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, Long auditId) {
        List<Repairuser> list = repairuserService.list(new QueryWrapper<Repairuser>().lambda().eq(Repairuser::getRepairId, repairOrderId));
        list.forEach(info -> {
            if (AuditSateEnum.AUDIT_YES.getCode().equals(auditResult)) {
                // 判断是否为最后一个处理人，如果是，则审核完成，如果不是，则交给下一审核人处理
                String teamUser = info.getTeamUser();
                String respUser = String.valueOf(info.getRespUser());
                String users;
                if (StringUtils.isBlank(teamUser)) {
                    users = respUser;
                } else {
                    users = teamUser + "," + respUser;
                }
                List<Long> userList = Arrays.stream(users.split(Constant.CSV)).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
                Long lastUser = userList.get(userList.size() - 1);
                if (Objects.equals(auditId, lastUser)) {
                    // 通过个人任务状态改为4已完成
                    info.setState(OrderStateEnum.ORDER_STATE_PROCESSING_COMPLETE.getCode());
                    // 待办事项处理
                    Usertask usertask = new Usertask();
                    usertask.setTableName(MessageTopicEnum.TASK_PLAN_MAINTENANCE_ORDER.getTableName());
                    usertask.setTableId(repairOrderId);
                    List<Usertask> result = userTaskClient.getUserTaskInfo(usertask).getResult();
                    if (null != result && result.size() > 0) {
                        result.forEach(task->{
                            task.setHandleTime(date);
                            task.setIshandle(UserTaskStateEnumEnum.IS_HANDLER_COMPLETED.getCode());
                            userTaskClient.updateById(task);
                        });
                    }
                } else {
                    // 不通过个人任务计划 状态改为3正在执行 系统用时清空 实际完成个数清空
                    info.setState(OrderStateEnum.ORDER_STATE_BEING_PERFORMED.getCode());
                    info.setRealTime(BigDecimal.ZERO.doubleValue());
                    info.setOverNum(BigDecimal.ZERO.longValue());
                    // 待办事项处理
                    Usertask usertask = new Usertask();
                    usertask.setTableName(MessageTopicEnum.TASK_PLAN_MAINTENANCE_ORDER.getTableName());
                    usertask.setTableId(repairOrderId);
                    List<Usertask> result = userTaskClient.getUserTaskInfo(usertask).getResult();
                    Date startTime = null;
                    Date endTime = null;
                    if (null != result && result.size() > 0) {
                        startTime = result.get(0).getStartTime();
                        endTime = result.get(0).getEndTime();
                        result.forEach(task->{
                            task.setHandleTime(date);
                            task.setIshandle(UserTaskStateEnumEnum.IS_HANDLER_COMPLETED.getCode());
                            userTaskClient.updateById(task);
                        });
                    }
                    Long nextUser = userList.get(userList.indexOf(repairOrderId) + 1);
                    // 待办事项新增
                    if (startTime != null && endTime != null) {
                        Usertask usertaskNext = new Usertask();
                        usertaskNext.setEndTime(startTime);
                        usertaskNext.setStartTime(endTime);
                        usertaskNext.setTknm(MessageTopicEnum.TASK_PLAN_MAINTENANCE_ORDER.getTopic());
                        usertaskNext.setTkty(MessageTypeEnum.MESSAGE_TYPE_ROB_MAINTENANCE.getCode());
                        usertaskNext.setTableName(MessageTopicEnum.TASK_PLAN_MAINTENANCE_ORDER.getTableName());
                        usertaskNext.setTableId(info.getId());
                        usertaskNext.setIshandle(UserTaskStateEnumEnum.IS_HANDLER_NOT_STARTED.getCode());
                        usertaskNext.setRouteIp(planWebRepairOrderRouteIp);
                        usertaskNext.setRouteAppIp(planAppRepairOrderRouteIp);
                        usertaskNext.setHandleUser(nextUser);
                        userTaskClient.save(usertaskNext);
                    }
                    Messagepush messagepush = new Messagepush();
                    // 消息主题/消息类型/消息表名/消息表中id/路由地址跳转
                    messagepush.setTopic(MessageTopicEnum.TASK_PLAN_MAINTENANCE_ORDER.getTopic());
                    messagepush.setType(MessageTypeEnum.MESSAGE_TYPE_ROB_MAINTENANCE.getCode());
                    messagepush.setTableName(MessageTopicEnum.TASK_PLAN_MAINTENANCE_ORDER.getTableName());
                    messagepush.setTableId(info.getId());
                    // 跳转到工单页面
                    messagepush.setRouteIp(planWebRepairOrderRouteIp);
                    messagepush.setRouteIpApp(planAppRepairOrderRouteIp);
                    // 消息与接收人信息处理
                    messageRecipientService.setMessageRecipient(messagepush, nextUser);
                }
            } else {
                // 不通过个人任务计划 状态改为3正在执行 系统用时清空 实际完成个数清空
                info.setState(OrderStateEnum.ORDER_STATE_BEING_PERFORMED.getCode());
                info.setRealTime(BigDecimal.ZERO.doubleValue());
                info.setOverNum(BigDecimal.ZERO.longValue());
            }
        });
        repairuserService.updateBatchById(list);
        Repairorder repairorder = repairorderService.getById(repairOrderId);
        List<Long> collect = list.stream().map(Repairuser::getId).collect(Collectors.toList());
        // 判断是否为养护
        if("1".equals(repairorder.getMaintenanceFlag())){
            List<PipeMfRecord> list1 = pipeMfRecordService.list(new QueryWrapper<PipeMfRecord>().lambda().in(PipeMfRecord::getRepairUserId, collect));
            list1.forEach(info -> {
                if (AuditSateEnum.AUDIT_NO.getCode().equals(auditResult)) {
                    // 不通过过程上报有效状态设置为 0 无效
                    info.setFlag(IsValidEnum.IS_VALID_NO.getCode());
                }
            });
            pipeMfRecordService.updateBatchById(list1);
        }else {
            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);
        }


        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)) {
                // 调用工单回调接口
                Boolean aBoolean = gdglinfoClient.gdGdUpdateState(String.valueOf(repairOrderId), 1).getResult();
                log.info("调用工单回调接口工单id: {},是否成功: {}", repairOrderId, aBoolean);
                // TODO 若异常则回滚
            }

        } else {
            repairorder.setState(OrderStateEnum.ORDER_STATE_BEING_PERFORMED.getCode());
        }
        // 待办事项处理
        Usertask usertask = new Usertask();
        usertask.setTableName(MessageTopicEnum.REPORT_REPAIR_RECORD.getTableName());
        usertask.setTableId(repairOrderId);
        List<Usertask> result = userTaskClient.getUserTaskInfo(usertask).getResult();
        if (null != result && result.size() > 0) {
            result.forEach(task->{
                task.setHandleTime(date);
                task.setHandleUser(SecurityUtils.getUserId());
                task.setIshandle(UserTaskStateEnumEnum.IS_HANDLER_COMPLETED.getCode());
                userTaskClient.updateById(task);
            });
        }
        repairorderService.updateById(repairorder);

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

}
