package com.chinaweal.aiccs.aiccs.fraudreg.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chinaweal.aiccs.aiccs.abnormal.entity.EBaseinfo;
import com.chinaweal.aiccs.aiccs.abnormal.service.EBaseinfoService;
import com.chinaweal.aiccs.aiccs.abnormal.service.IGzaiccodeService;
import com.chinaweal.aiccs.aiccs.abnormal.service.TSAttachmentService;
import com.chinaweal.aiccs.aiccs.asyncTask.RevokeAsyncTask;
import com.chinaweal.aiccs.aiccs.business.entity.TSTaskList;
import com.chinaweal.aiccs.aiccs.business.entity.TSTwfProcessNode;
import com.chinaweal.aiccs.aiccs.business.service.TSTaskListService;
import com.chinaweal.aiccs.aiccs.business.service.WorkFlowService;
import com.chinaweal.aiccs.aiccs.fraudreg.dto.FraudProcessDto;
import com.chinaweal.aiccs.aiccs.fraudreg.entity.RevokeTBizFraud;
import com.chinaweal.aiccs.aiccs.fraudreg.entity.TBizFraud;
import com.chinaweal.aiccs.aiccs.fraudreg.entity.TFraudEnt;
import com.chinaweal.aiccs.aiccs.fraudreg.entity.TFraudPerson;
import com.chinaweal.aiccs.aiccs.fraudreg.mapper.RevokeTBizFraudMapper;
import com.chinaweal.aiccs.aiccs.fraudreg.service.*;
import com.chinaweal.aiccs.aiccs.market.service.ITSUsualInspectService;
import com.chinaweal.aiccs.aiccs.revoke.entity.CancelRevocationRegList;
import com.chinaweal.aiccs.common.constant.BaseDataConstant;
import com.chinaweal.aiccs.common.util.FlowUtil;
import com.chinaweal.aiccs.common.util.HandleWorkFlowUtil;
import com.chinaweal.aiccs.common.util.StringUtils;
import com.chinaweal.aiccs.common.util.filestorage.FileStorageService;
import com.chinaweal.aiccs.org.service.TUsersService;
import com.chinaweal.aicorg.model.AICUser;
import com.chinaweal.aicorg.services.OrgUM;
import com.chinaweal.youfool.framework.springboot.mybatis.plus.BaseServiceImpl;
import com.chinaweal.youfool.framework.sso.util.SSOUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class RevokeFraudServiceImpl extends BaseServiceImpl<RevokeTBizFraudMapper, RevokeTBizFraud> implements RevokeFraudService {


    @Resource
    private ITBizFraudService itBizFraudService;
    @Resource
    private EBaseinfoService eBaseInfoService;
    @Resource
    private TSTaskListService taskListService;
    @Resource
    private WorkFlowService workFlowService;
    @Resource
    private OrgUM orgUM;
    @Resource
    private RevokeAsyncTask revokeAsyncTask;

    @Resource
    @Lazy
    private RevokeFraudService revokeFraudService;

    @Override
    public Map<String, String> startTaskRevokeTFraud(String uscc, String bizSeqOld, AICUser loginUser) {
        Map<String, String> resultMap = new HashMap<>();
        EBaseinfo eBaseInfo = eBaseInfoService.getEntBaseInfoByCode(uscc);

        String bizSeq = IdUtil.simpleUUID();

//        LambdaQueryWrapper<TBizFraud> lambdaQueryWrapper = new LambdaQueryWrapper();
//        lambdaQueryWrapper.eq(TBizFraud :: getId ,id);
//        TBizFraud tBizFraud = itBizFraudService.getOne(lambdaQueryWrapper);

        //撤销撤销案件业务表
        RevokeTBizFraud revokeTBizFraud = new RevokeTBizFraud();
        revokeTBizFraud.setBizSeq(bizSeq);
        revokeTBizFraud.setUnisCid(eBaseInfo.getUniscid());
        revokeTBizFraud.setPriPid(eBaseInfo.getPripid());
        revokeTBizFraud.setRegNo(eBaseInfo.getRegno());
        revokeTBizFraud.setEntName(eBaseInfo.getEntname());
        revokeTBizFraud.setUserId(loginUser.getPrimaryKey());
        revokeTBizFraud.setOrgUnitID(loginUser.getRegionID());
        revokeTBizFraud.setIntoSponsor(loginUser.getName());
        revokeTBizFraud.setStatus("1");
        revokeTBizFraud.setLinkType("1");
//        revokeTBizFraud.setCreateBy(loginUser.getPrimaryKey());
//        revokeTBizFraud.setCreateName(loginUser.getName());
//        revokeTBizFraud.setUpdateBy(loginUser.getPrimaryKey());
//        revokeTBizFraud.setUpdateName(loginUser.getName());
        revokeTBizFraud.setBizseqOld(bizSeqOld);
        revokeFraudService.save(revokeTBizFraud);

        //获取对应的撤销业务
        LambdaQueryWrapper<TBizFraud> lambdaQueryWrappera = new LambdaQueryWrapper();
        lambdaQueryWrappera.eq(TBizFraud :: getBizSeq ,bizSeqOld);
        TBizFraud tBizFraud = itBizFraudService.getOne(lambdaQueryWrappera);


        // 启动工作流
        TSTaskList tsTaskList = new TSTaskList();
        tsTaskList.setBizseqid(bizSeq);
        if ("1".equals(tBizFraud.getBusinessType())){
            tsTaskList.setBustype(BaseDataConstant.CANCEL_REVOKE);
        }else if ("2".equals(tBizFraud.getBusinessType())){
            tsTaskList.setBustype(BaseDataConstant.CANCEL_REVOKEBG);
        }else if ("3".equals(tBizFraud.getBusinessType())){
            tsTaskList.setBustype(BaseDataConstant.CANCEL_REVOKEZX);
        }else {
            tsTaskList.setBustype(BaseDataConstant.CANCEL_REVOKE);
        }

        tsTaskList.setBusname(eBaseInfo.getEntname());
        //新待办 设置待办信息
        tsTaskList = HandleWorkFlowUtil.createTaskList(tsTaskList, loginUser);
        //开始工作流
        taskListService.startWorkFlow(tsTaskList, loginUser, FlowUtil.CANCELREVOKEWORKFLOW);

        // 返回结果
        resultMap.put("taskId", tsTaskList.getTasklistid());
        resultMap.put("bizSeq", bizSeq);
        resultMap.put("workflowId", tsTaskList.getWorkflowid());
        resultMap.put("bizSeqOld", bizSeqOld);
        return resultMap;
    }

    @Override
    public String processControlrevokeTFraud(FraudProcessDto fraudProcessDto, TSTaskList tsTaskList, AICUser loginUser) {
        TSTwfProcessNode twfProcessNode = workFlowService.findCurrentNode(tsTaskList.getWorkflowid());
        String link = String.format("%s_%s", twfProcessNode.getCurrentnode(), fraudProcessDto.getNextNodeID());
        String msg = "success";
        // 参考 cancelRevokeWorkflow.xml 配置流程扭转
        switch (link) {
            case "startCxAccept_handleCancelCx"://经办到审核
                this.toHandleCancelCx(fraudProcessDto, tsTaskList, loginUser);
                break;
            case "startCxAccept_overCxFinish"://经办结束流程
            case "approvalCancelCx_overCxFinish": //审批结束流程
                this.toOverCxFinish(fraudProcessDto, tsTaskList, loginUser);
                break;
            case "handleCancelCx_approvalCancelCx"://审核到审批
                this.toApprovalCancelCx(fraudProcessDto, tsTaskList, loginUser);
                break;
            case "approvalCancelCx_startCxAccept"://审批退回到经办
                this.toApprovalCancelCxStartCxAccept(fraudProcessDto, tsTaskList, loginUser);
                break;
            case "handleCancelCx_startCxAccept"://审核退回到经办
                this.toHandleCancelCxStartCxAccept(fraudProcessDto, tsTaskList, loginUser);
                break;
            case "approvalCancelCx_endApprovalCancel"://审批完成
                msg = this.toEndApprovalCancel(fraudProcessDto, tsTaskList, loginUser);
                break;
            default:
                throw new RuntimeException("流程扭转出错");
        }
        return msg;
    }

    @Override
    public void toHandleCancelCx(FraudProcessDto fraudProcessDto, TSTaskList tsTaskList, AICUser loginUser) {

        LambdaQueryWrapper<RevokeTBizFraud> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(RevokeTBizFraud:: getBizSeq ,fraudProcessDto.getBizSeq());
        RevokeTBizFraud revokeTBizFraud = revokeFraudService.getOne(lambdaQueryWrapper);
        revokeTBizFraud.setStatus("2");
        revokeTBizFraud.setLinkType("2");
        revokeTBizFraud.setRevokeApplyName(fraudProcessDto.getRevokeTBizFraudInfo().getRevokeApplyName());
        revokeTBizFraud.setRevokeApplyNo(fraudProcessDto.getRevokeTBizFraudInfo().getRevokeApplyNo());
        revokeTBizFraud.setRemark(fraudProcessDto.getRevokeTBizFraudInfo().getRemark());
        revokeTBizFraud.setRevokeFraudContent(fraudProcessDto.getRevokeTBizFraudInfo().getRevokeFraudContent());
        revokeTBizFraud.setCanceldocno(fraudProcessDto.getRevokeTBizFraudInfo().getCanceldocno());
        revokeFraudService.updateById(revokeTBizFraud);


        // 流程推进
        taskListService.updateWorkFlow(loginUser, fraudProcessDto.getOpinion(), tsTaskList,
                fraudProcessDto.getNextNodeID(), fraudProcessDto.getNextPerformerIds(), fraudProcessDto.getNextPerformerNames());
    }


    @Override
    public void toOverCxFinish(FraudProcessDto fraudProcessDto, TSTaskList tsTaskList, AICUser loginUser) {

        LambdaQueryWrapper<RevokeTBizFraud> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(RevokeTBizFraud:: getBizSeq ,fraudProcessDto.getBizSeq());
        RevokeTBizFraud revokeTBizFraud = revokeFraudService.getOne(lambdaQueryWrapper);
        revokeTBizFraud.setStatus("4");
        revokeTBizFraud.setLinkType("4");
        revokeTBizFraud.setEndReason(fraudProcessDto.getRevokeTBizFraudInfo().getEndReason());
        revokeTBizFraud.setRevokeApplyName(fraudProcessDto.getRevokeTBizFraudInfo().getRevokeApplyName());
        revokeTBizFraud.setRevokeApplyNo(fraudProcessDto.getRevokeTBizFraudInfo().getRevokeApplyNo());
        revokeTBizFraud.setRemark(fraudProcessDto.getRevokeTBizFraudInfo().getRemark());
        revokeTBizFraud.setRevokeFraudContent(fraudProcessDto.getRevokeTBizFraudInfo().getRevokeFraudContent());
        revokeTBizFraud.setCanceldocno(fraudProcessDto.getRevokeTBizFraudInfo().getCanceldocno());

        revokeFraudService.updateById(revokeTBizFraud);


        // 流程推进
        taskListService.updateWorkFlow(loginUser, fraudProcessDto.getOpinion(), tsTaskList,
                fraudProcessDto.getNextNodeID(), fraudProcessDto.getNextPerformerIds(), fraudProcessDto.getNextPerformerNames());
    }


    @Override
    public void toApprovalCancelCx(FraudProcessDto fraudProcessDto, TSTaskList tsTaskList, AICUser loginUser) {

        LambdaQueryWrapper<RevokeTBizFraud> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(RevokeTBizFraud:: getBizSeq ,fraudProcessDto.getBizSeq());
        RevokeTBizFraud revokeTBizFraud = revokeFraudService.getOne(lambdaQueryWrapper);
        revokeTBizFraud.setStatus("2");
        revokeTBizFraud.setLinkType("3");

        revokeFraudService.updateById(revokeTBizFraud);


        // 流程推进
        taskListService.updateWorkFlow(loginUser, fraudProcessDto.getOpinion(), tsTaskList,
                fraudProcessDto.getNextNodeID(), fraudProcessDto.getNextPerformerIds(), fraudProcessDto.getNextPerformerNames());
    }

    @Override
    public void toApprovalCancelCxStartCxAccept(FraudProcessDto fraudProcessDto, TSTaskList tsTaskList, AICUser loginUser) {

        LambdaQueryWrapper<RevokeTBizFraud> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(RevokeTBizFraud:: getBizSeq ,fraudProcessDto.getBizSeq());
        RevokeTBizFraud revokeTBizFraud = revokeFraudService.getOne(lambdaQueryWrapper);
        revokeTBizFraud.setStatus("1");
        revokeTBizFraud.setLinkType("1");

        revokeFraudService.updateById(revokeTBizFraud);


        // 流程推进
        taskListService.updateWorkFlow(loginUser, fraudProcessDto.getOpinion(), tsTaskList,
                fraudProcessDto.getNextNodeID(), fraudProcessDto.getNextPerformerIds(), fraudProcessDto.getNextPerformerNames());
    }

    @Override
    public void toHandleCancelCxStartCxAccept(FraudProcessDto fraudProcessDto, TSTaskList tsTaskList, AICUser loginUser) {

        LambdaQueryWrapper<RevokeTBizFraud> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(RevokeTBizFraud:: getBizSeq ,fraudProcessDto.getBizSeq());
        RevokeTBizFraud revokeTBizFraud = revokeFraudService.getOne(lambdaQueryWrapper);
        revokeTBizFraud.setStatus("1");
        revokeTBizFraud.setLinkType("1");

        // 获取受理环节经办人
        AICUser acceptUser = orgUM.findUserByPrimaryKey(revokeTBizFraud.getUserId());
        fraudProcessDto.setNextPerformerIds(new String[]{acceptUser.getPrimaryKey()});
        fraudProcessDto.setNextPerformerNames(new String[]{acceptUser.getName()});

        revokeFraudService.updateById(revokeTBizFraud);


        // 流程推进
        taskListService.updateWorkFlow(loginUser, fraudProcessDto.getOpinion(), tsTaskList,
                fraudProcessDto.getNextNodeID(), fraudProcessDto.getNextPerformerIds(), fraudProcessDto.getNextPerformerNames());
    }

    @Override
    public String toEndApprovalCancel(FraudProcessDto fraudProcessDto, TSTaskList tsTaskList, AICUser loginUser) {
        LambdaQueryWrapper<RevokeTBizFraud> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(RevokeTBizFraud:: getBizSeq ,fraudProcessDto.getBizSeq());
        RevokeTBizFraud revokeTBizFraud = revokeFraudService.getOne(lambdaQueryWrapper);
        //获取对应的撤销业务
        LambdaQueryWrapper<TBizFraud> lambdaQueryWrappera = new LambdaQueryWrapper();
        lambdaQueryWrappera.eq(TBizFraud :: getBizSeq ,revokeTBizFraud.getBizseqOld());
        TBizFraud tBizFraud = itBizFraudService.getOne(lambdaQueryWrappera);

        //=====调用外部撤销撤销设立接口======
        if(revokeTBizFraud != null && "1".equals(tBizFraud.getBusinessType())){
            //设置撤销撤销设立结果表相关信息
            AICUser aicUser = SSOUtil.getUser();
            CancelRevocationRegList cancelRevocationRegList = new CancelRevocationRegList();
            cancelRevocationRegList.setRevokeTBizFraudId(revokeTBizFraud.getId())
                    .setPripid(fraudProcessDto.getFraudEntInfo().getPripid())
                    .setUniscid(fraudProcessDto.getFraudEntInfo().getUniScId())
                    .setEntname(fraudProcessDto.getFraudEntInfo().getEntName())
                    .setRegno(fraudProcessDto.getFraudEntInfo().getRegNo())
                    .setCanceldocno(fraudProcessDto.getRevokeTBizFraudInfo().getCanceldocno())
                    .setCancelrea(fraudProcessDto.getRevokeTBizFraudInfo().getRevokeFraudContent())          // 处理原因：撤销撤销核实情况
                    .setUsername("信用监管系统")
                    .setHandlerid(aicUser.getPrimaryKey())
                    .setHandlername(aicUser.getName());

            //调用泰富撤销撤销设立接口
            String result = revokeAsyncTask.tfCancelRevocationReg(cancelRevocationRegList);
            if(!"success".equals(result)){      //接口调用失败
                String errorMsg = getCancelRevocationRegExcode(result);
                return errorMsg;
            }
        }
        //=====调用外部撤销撤销设立接口======完

        revokeTBizFraud.setStatus("3");
        revokeTBizFraud.setLinkType("4");

        revokeFraudService.updateById(revokeTBizFraud);

        // 流程推进
        taskListService.updateWorkFlow(loginUser, fraudProcessDto.getOpinion(), tsTaskList,
                fraudProcessDto.getNextNodeID(), fraudProcessDto.getNextPerformerIds(), fraudProcessDto.getNextPerformerNames());

        return "success";
    }

    //根据异常代码显示对应的提示语
    private String getCancelRevocationRegExcode(String excode){
        String msg = "";
        switch (excode){
            case "001":
                msg = "未找到对应的主体，请核实该主体是否真实存在。";
                break;
            case "002":
                msg = "该主体不是已撤销主体，请核查是否已经撤销设立。";
                break;
            case "003":
                msg="该主体存在锁定信息，不允许撤销撤销设立，请先到注册系统进行解锁操作。";
                break;
            default:
                msg = "撤销吊销失败，请联系系统工程师进一步排查原因。";
                break;
        }
        return msg;
    }
}
