package com.boco.nbd.wios.flow.process;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.bestvike.linq.Linq;
import com.boco.nbd.cams.core.util.LambdaUtils;
import com.boco.nbd.framework.workflow.entity.SubmitFlowRequest;
import com.boco.nbd.framework.workflow.entity.SubmitTypeEnum;
import com.boco.nbd.framework.workflow.entity.exception.FlowException;
import com.boco.nbd.framework.workflow.flow.IFlowCommonHandle;
import com.boco.nbd.wios.flow.entity.bo.LocalSubmitFlowBO;
import com.boco.nbd.wios.flow.entity.bo.TimeNotifyBO;
import com.boco.nbd.wios.flow.entity.po.FlowNodeUserPO;
import com.boco.nbd.wios.flow.entity.po.OrderPO;
import com.boco.nbd.wios.flow.entity.qo.FlowNodeUserQo;
import com.boco.nbd.wios.flow.enums.FlowNodeEnum;
import com.boco.nbd.wios.flow.service.INoticeService;
import com.boco.nbd.wios.flow.service.IOrderService;
import com.boco.nbd.wios.flow.util.ProcessUtil;
import com.boco.nbd.wios.manage.entity.cams.enums.OrderStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * @author:cao hai
 * @date:2022/8/29 8:47
 * @version:V1.0
 * @description:OrderCommonHandle
 * @modify:
 */
@Service
@Slf4j
public class OrderCommonHandle implements IFlowCommonHandle {

    @Autowired
    protected IOrderService orderService;

    @Autowired
    INoticeService noticeService;

    /**
     * 流程提交前共性处理:失败抛出FlowException异常
     *
     * @param request
     */
    @Override
    public void beforeSubmitHandle(SubmitFlowRequest request) {
        LocalSubmitFlowBO bo = (LocalSubmitFlowBO) request;
        //如果表单数据为空,后端补齐
        if (bo.getBusiness() == null) {
            bo.setBusiness(new OrderPO());
            bo.getBusiness().setId(bo.getWorkId());
        }
        if (SubmitTypeEnum.CloseFlow.equals(bo.getSubmitType())) {
            bo.setNextNodeEnum(FlowNodeEnum.NODE_END);
            bo.setCommentMsg("流程关闭");
        }
        if (SubmitTypeEnum.Transfer.equals(bo.getSubmitType()) || SubmitTypeEnum.UpdateVariable.equals(bo.getSubmitType())) {
            bo.setNextNodeEnum(bo.getCurrentNodeEnum());
            if (SubmitTypeEnum.UpdateVariable.equals(bo.getSubmitType())) {
                bo.setCommentMsg("更新业务数据");
            }
        }
        if (FlowNodeEnum.NODE_END.getKey().equals(bo.getNextNode())) {
            bo.setIsFinished(true);
            bo.getBusiness().setCloseTime(new Date());
        }
        bo.setNextNode(bo.getNextNodeEnum().getKey());
        if (!bo.getIsFinished() && !SubmitTypeEnum.UpdateVariable.equals(bo.getSubmitType())) {
            //处理时限统一添加
            if (!bo.getCurrentNode().equals(bo.getNextNode())) {
                Date limitTime = orderService.getDueDate(bo.getNextNode(), getDueStartTime(bo.getNextNode(), bo.getOldBusiness()));
                if (limitTime != null) {
                    bo.setLimitTime(limitTime);
                }

                if (bo.getUserNames().isEmpty()) {
                    //自动获取流程用户组信息
                    FlowNodeUserQo qo = FlowNodeUserQo.init(bo.getNextNode());
                    List<FlowNodeUserPO> users = orderService.getFlowNodeUserInfo(qo);
                    bo.setUserNames(Linq.of(users).select(s -> s.getUserId()).distinct().toList());
                }
            }
            //存在超级用户组 统一添加
            List<String> superUser = Linq.of(orderService.getSuperUserByGroup()).select(s -> s.getId()).toList();
            bo.getUserNames().addAll(superUser);
            //添加PM用户
            if (ProcessUtil.areSurveyTransfer(bo.getNextNode()) || ProcessUtil.areInstallTransfer(bo.getNextNode())) {
                List<String> transferUser = ProcessUtil.getTransferUser(orderService.getPmUser(), bo.getOldBusiness());
                bo.getUserNames().addAll(transferUser);
                bo.getBusiness().setTransferUserValue(superUser, transferUser);
            }
            bo.setUserNames(Linq.of(bo.getUserNames()).distinct().toList());
        }
        //状态=>目前未设别状态
        OrderStatus orderStatus = FlowNodeEnum.getOrderStatus(bo.getSubmitType(), bo.getCurrentNodeEnum(), bo.getNextNodeEnum());
        if (orderStatus != null) {
            bo.getBusiness().setStatus(orderStatus.getType());
            bo.getTaskParam().put(LambdaUtils.getFieldName(OrderPO::getStatus), bo.getBusiness().getStatus());
        }

        bo.initTaskParam();
        bo.verify();
    }

    /**
     * 获取时效计算开始时间
     *
     * @param nextNode
     * @param po       勘测预约节点处理时限 首联环节填写的首联时间开始算
     *                 上传勘测资料节点处理时限 从预约勘测时间开始计算
     *                 上传安装资料节点处理时限 从预约安装时间
     * @return
     */
    public Date getDueStartTime(int nextNode, OrderPO po) {
        if (FlowNodeEnum.NODE_104.getKey() == nextNode) {
            if (po == null || po.getConnectTime() == null) {
                throw new FlowException(LambdaUtils.getFieldName(OrderPO::getConnectTime) + "空异常");
            }
            return po.getConnectTime();
        }
        if (FlowNodeEnum.NODE_106.getKey() == nextNode) {
            if (po == null || po.getSurveyReserveTime() == null) {
                throw new FlowException(LambdaUtils.getFieldName(OrderPO::getSurveyReserveTime) + "空异常");
            }
            return po.getSurveyReserveTime();
        }
        if (FlowNodeEnum.NODE_111.getKey() == nextNode) {
            if (po == null || po.getInstallReserveTime() == null) {
                throw new FlowException(LambdaUtils.getFieldName(OrderPO::getInstallReserveTime) + "空异常");
            }
            return po.getInstallReserveTime();
        }
        return new Date();
    }

    /**
     * 业务数据处理:失败抛出FlowException异常
     *
     * @param request
     */
    @Override
    public void businessDataHandle(SubmitFlowRequest request) {
        LocalSubmitFlowBO bo = (LocalSubmitFlowBO) request;
        //启动流程 setProcessInsId
        if (SubmitTypeEnum.StartFlow.equals(request.getSubmitType())) {
            bo.getBusiness().setProcessInsId(bo.getProcessInsId());
            bo.getBusiness().setNodeFlag(bo.getNextNode());
            bo.getBusiness().setCreateTime(new Date());
            orderService.insert(bo.getBusiness());
        } else {
            if (bo.getBusiness() != null) {
                //关闭流程个性处理 业务表保留关闭节点的nodeFlag
                if (!SubmitTypeEnum.CloseFlow.equals(request.getSubmitType())) {
                    bo.getBusiness().setNodeFlag(bo.getNextNode());
                }
                //files字段长度不够统一置空不保存
                bo.getBusiness().setFiles(null);
                //修改预约时间发短信
                if (bo.getBusiness().getInstallReserveTime() != null) {
                    try {
                        String time = DateUtil.format(bo.getBusiness().getInstallReserveTime(), DatePattern.NORM_DATETIME_PATTERN);
                        TimeNotifyBO timeConfirmBO = new TimeNotifyBO(request.getWorkId(), time);
                        String phone = StrUtil.isEmpty(bo.getBusiness().getInstallClientPhone()) ? bo.getOldBusiness().getInstallClientPhone() : bo.getBusiness().getInstallClientPhone();
                        noticeService.appointmentTimeNotify(timeConfirmBO, phone);
                        log.info(request.getWorkId() + "安装预约时间变更通知发送短信成功");
                    } catch (Exception ex) {
                        log.error(request.getWorkId() + "安装预约时间变更通知发送短信异常:", ex);
                    }
                }

                orderService.updateByPrimaryKeySelective(bo.getBusiness());
            }
            if (bo.getBusinessSurvey() != null) {
                orderService.saveOrderSurvey(bo.getBusinessSurvey());
            }
            if (bo.getBusinessInstall() != null) {
                orderService.saveOrderInstall(bo.getBusinessInstall(), bo.getSubmitUserName());
            }
        }
    }
}