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.EAlterRecoderTemp;
import com.chinaweal.aiccs.aiccs.abnormal.entity.EBaseinfo;
import com.chinaweal.aiccs.aiccs.abnormal.entity.Gzaiccode;
import com.chinaweal.aiccs.aiccs.abnormal.service.EAlterRecoderTempService;
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.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.TBizFraud;
import com.chinaweal.aiccs.aiccs.fraudreg.entity.TFraudCheck;
import com.chinaweal.aiccs.aiccs.fraudreg.entity.TFraudEnt;
import com.chinaweal.aiccs.aiccs.fraudreg.entity.TFraudPerson;
import com.chinaweal.aiccs.aiccs.fraudreg.service.*;
import com.chinaweal.aiccs.aiccs.market.service.ITSUsualInspectService;
import com.chinaweal.aiccs.aiccs.temp.service.TemporarySaveService;
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.crgs.entity.E_CONTACTCrgs;
import com.chinaweal.aiccs.crgs.moveinDetails.entity.EAlterRecoder;
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.exception.custom.BusinessException;
import com.chinaweal.youfool.framework.springboot.rest.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * Created by IDEA.
 * Code: lwd
 * Date: 2023/02/01
 * Time: 15:50
 */

@Service
@Slf4j
public class IFraudEntryServiceImpl implements IFraudEntryService {


    @Resource
    private ITBizFraudService itBizFraudService;
    @Resource
    private ITFraudEntService itFraudEntService;
    @Resource
    private ITFraudPersonService itFraudPersonService;
    @Resource
    private EBaseinfoService eBaseInfoService;
    @Resource
    private TSTaskListService taskListService;
    @Resource
    private WorkFlowService workFlowService;
    @Resource
    private FileStorageService fileStorageService;


    @Resource
    private TSAttachmentService attachmentService;
    @Resource
    private OrgUM orgUM;
    @Resource
    private ITSUsualInspectService iTSUsualInspectService;
    @Resource
    private ITFraudCheckService iTFraudCheckService;
    @Resource
    private TUsersService tUsersService;
    @Resource
    private IGzaiccodeService iGzaiccodeService;
    @Resource
    private IFraudProcessService fraudProcessService;
    @Resource
    private TemporarySaveService temporarySaveService;
    @Resource
    private EAlterRecoderTempService eAlterRecoderTempService;


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

        String bizSeq = IdUtil.simpleUUID();

        // 冒用业务信息
        TBizFraud tBizFraud = new TBizFraud();
        tBizFraud.setBizSeq(bizSeq);
        tBizFraud.setUserId(loginUser.getPrimaryKey());
        tBizFraud.setOrgUnitID(loginUser.getRegionID());
        tBizFraud.setIntoSponsor(loginUser.getName());
        tBizFraud.setStatus("1");
        tBizFraud.setLinkType("1");
        itBizFraudService.save(tBizFraud);

        // 涉嫌冒用企业主体信息
        TFraudEnt tFraudEnt = new TFraudEnt();
        tFraudEnt.setBizSeq(bizSeq);
        tFraudEnt.setPripid(eBaseInfo.getPripid());
        tFraudEnt.setEntName(eBaseInfo.getEntname());
        tFraudEnt.setUniScId(eBaseInfo.getUniscid());
        tFraudEnt.setRegNo(eBaseInfo.getRegno());
        tFraudEnt.setRegOrg(eBaseInfo.getRegorg());
        tFraudEnt.setRegOrgCn(eBaseInfo.getRegorgCn());
        tFraudEnt.setTel(eBaseInfo.getTel());
        tFraudEnt.setRegTime(eBaseInfo.getEstdate());
        itFraudEntService.save(tFraudEnt);

        // 虚假责任人
        TFraudPerson tFraudPerson = new TFraudPerson();
        tFraudPerson.setBizSeq(bizSeq);
        tFraudPerson.setPripid(eBaseInfo.getPripid());
        tFraudPerson.setName(eBaseInfo.getName());
        tFraudPerson.setEntName(eBaseInfo.getEntname());
        tFraudPerson.setUniScId(eBaseInfo.getUniscid());
        tFraudPerson.setRegNo(eBaseInfo.getRegno());
        itFraudPersonService.save(tFraudPerson);

        // 启动工作流
        TSTaskList tsTaskList = new TSTaskList();
        tsTaskList.setBizseqid(bizSeq);
        tsTaskList.setBustype(BaseDataConstant.CANCEL_EASYENTRY);
        tsTaskList.setBusname(eBaseInfo.getEntname());
        //新待办 设置待办信息
        tsTaskList = HandleWorkFlowUtil.createTaskList(tsTaskList, loginUser);
        //开始工作流
        taskListService.startWorkFlow(tsTaskList, loginUser, FlowUtil.CANCELEASYENTRYWORKFLOW);

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

    @Override
    public String processControlEasyTFraud(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";
        // 参考 cancelEasyEntryWorkFlow.xml 配置流程扭转
        switch (link) {
            case "startLrAccept_approvalLrCancel":      //受理——审批
                this.toHandleCancel(fraudProcessDto, tsTaskList, loginUser);
                break;
            case "approvalLrCancel_startLrAccept":      //审批——受理
                this.backStartAccept(fraudProcessDto, tsTaskList, loginUser);
                break;
            case "approvalLrCancel_endLrCase":          //提交公示
                msg = fraudProcessService.toEndCase(fraudProcessDto, tsTaskList, loginUser);
                break;
            case "startLrAccept_cancelCase":            //受理——结束流程
            case "approvalLrCancel_cancelCase":         //审批——结束流程
                fraudProcessService.cancelCase(fraudProcessDto, tsTaskList, loginUser);
                break;
            default:
                throw new RuntimeException("流程扭转出错");
        }
        temporarySaveService.delByBizseq(fraudProcessDto.getBizSeq());
        return msg;
    }


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

        //获取变更记录信息
        List<EAlterRecoderTemp> selectedRecords = fraudProcessDto.getSelectedRecords();
        if (selectedRecords != null && selectedRecords.size() > 0) {
            LambdaQueryWrapper<EAlterRecoderTemp> ecWrapper = new LambdaQueryWrapper<>();
            ecWrapper.eq(EAlterRecoderTemp::getBizseq, fraudProcessDto.getBizSeq());
            List<EAlterRecoderTemp> eAlterRecoderTempList = eAlterRecoderTempService.list(ecWrapper);
            if (eAlterRecoderTempList != null && eAlterRecoderTempList.size() > 0) {
                eAlterRecoderTempService.remove(ecWrapper);
            }
            for (int i = 0; i < selectedRecords.size(); i++) {
                EAlterRecoderTemp eAlterRecoderTemp = selectedRecords.get(i);
                eAlterRecoderTemp.setAltid(UUID.randomUUID().toString());
                eAlterRecoderTemp.setBizseq(fraudProcessDto.getBizSeq());
                eAlterRecoderTemp.setCreateTime(LocalDateTime.now());
                eAlterRecoderTemp.setUpdateTime(LocalDateTime.now());
                eAlterRecoderTempService.save(eAlterRecoderTemp);

            }

        }
        TFraudEnt tFraudEnt = itFraudEntService.getByBizSeq(fraudProcessDto.getBizSeq());
        BeanUtil.copyProperties(fraudProcessDto.getFraudEntInfo(), tFraudEnt);
//        tFraudEnt.setNoticeFrom(LocalDate.now());
//        tFraudEnt.setNoticeTo(LocalDate.now().plusDays(45));
        itFraudEntService.updateById(tFraudEnt);

        saveFraudPerson(fraudProcessDto);

        TBizFraud tBizFraud = itBizFraudService.getTBizFraudByBizSeq(fraudProcessDto.getBizSeq());
        TBizFraud tBizFraudDto = fraudProcessDto.getBizFraudInfo();
        tBizFraud.setLinkType("3");
        tBizFraud.setStatus("2");
        tBizFraud.setComplaintReason(fraudProcessDto.getComplaintReason());
        tBizFraud.setIsCase(fraudProcessDto.getIsCase());
        tBizFraud.setComplainerType(tBizFraudDto.getComplainerType());
        tBizFraud.setComplainerName(tBizFraudDto.getComplainerName());
        tBizFraud.setComplainerCertType(tBizFraudDto.getComplainerCertType());
        tBizFraud.setComplainerCertNo(tBizFraudDto.getComplainerCertNo());
        tBizFraud.setComplainerEntName(tBizFraudDto.getComplainerEntName());
        tBizFraud.setComplainerLegalPhone(tBizFraudDto.getComplainerLegalPhone());
        tBizFraud.setComplainerRegOrg_cn(tBizFraudDto.getComplainerRegOrg_cn());
        tBizFraud.setBizHandleResult(fraudProcessDto.getBizHandleResult());
        tBizFraud.setContacts(tBizFraudDto.getContacts());
        tBizFraud.setContactsPhone(tBizFraudDto.getContactsPhone());
        tBizFraud.setBusinessType(tBizFraudDto.getBusinessType());
        if("1".equals(tBizFraud.getBusinessType())){
            tsTaskList.setBustype(BaseDataConstant.CANCEL_EASYENTRY);
        }else if ("2".equals(tBizFraud.getBusinessType())) {
            tsTaskList.setBustype(BaseDataConstant.CANCEL_EASYENTRYBG);
        }else if ("3".equals(tBizFraud.getBusinessType())){
            tsTaskList.setBustype(BaseDataConstant.CANCEL_EASYENTRYZX);
        }else {
            tsTaskList.setBustype(BaseDataConstant.CANCEL_EASYENTRY);
        }
        itBizFraudService.updateById(tBizFraud);

        // 是否转现场核查 1-发起
        if ("1".equals(fraudProcessDto.getIsCase())) {

            Optional<TFraudCheck> optional = iTFraudCheckService.lambdaQuery().eq(TFraudCheck::getBizSeq, fraudProcessDto.getBizSeq()).oneOpt();

            if (!optional.isPresent()) {

                // 生成转现场核查业务
                EBaseinfo eBaseInfo = eBaseInfoService.lambdaQuery().eq(EBaseinfo::getUniscid, tFraudEnt.getUniScId()).one();
                Gzaiccode gzaiccode = tUsersService.findOrganization(loginUser.getPrimaryKey());

                TFraudCheck tFraudCheck = fraudProcessDto.getFraudCheckInfo();
                tFraudCheck.setBizSeq(fraudProcessDto.getBizSeq());
                tFraudCheck.setPripid(eBaseInfo.getPripid());
                tFraudCheck.setEntName(eBaseInfo.getEntname());
                tFraudCheck.setUscc(eBaseInfo.getUniscid());
                tFraudCheck.setDomdistrict(StringUtils.isBlank(eBaseInfo.getDomdistrict())? eBaseInfo.getRegorg() : eBaseInfo.getDomdistrict());
                tFraudCheck.setSupOrg(eBaseInfo.getSuporg());
                tFraudCheck.setSupOrgCn(iGzaiccodeService.getNameByCode(eBaseInfo.getSuporg()));

                // 非市局发起并且属地监管不为空，直接分派当监管所
                if (StringUtils.isNotBlank(eBaseInfo.getSuporg()) && !"440101".equals(loginUser.getRegionID())) {
                    tFraudCheck.setStatus("1");
                    tFraudCheck.setSendOrg(eBaseInfo.getSuporg());
                } else {
                    tFraudCheck.setStatus("0");

                    if ("440101".equals(tFraudCheck.getDomdistrict())) {
                        if (StringUtils.isNotBlank(eBaseInfo.getSuporg())) {
                            tFraudCheck.setDomdistrict(eBaseInfo.getSuporg().substring(0, 6));
                        } else {
                            throw new BusinessException(ResultCode.BUSINESS_LOGIC_ERROR, "数据出错，无法发起现场核查业务。");
                        }
                    }
                }

                tFraudCheck.setOrg(gzaiccode.getScountrycode());
                tFraudCheck.setOrgCn(gzaiccode.getSregorgname());
                tFraudCheck.setUserId(loginUser.getPrimaryKey());
                tFraudCheck.setUserName(loginUser.getName());
                tFraudCheck.setHandleTime(LocalDateTime.now());
                iTFraudCheckService.save(tFraudCheck);
            }
        }

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

    /**
     * 保存虚假责任人信息
     * @param fraudProcessDto
     */
    private void saveFraudPerson(FraudProcessDto fraudProcessDto) {
        TFraudPerson tFraudPerson = itFraudPersonService.getByBizSeq(fraudProcessDto.getBizSeq());
        BeanUtil.copyProperties(fraudProcessDto.getFraudPersonInfo(), tFraudPerson);
        itFraudPersonService.updateById(tFraudPerson);
    }


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

        TBizFraud tBizFraud = itBizFraudService.getTBizFraudByBizSeq(fraudProcessDto.getBizSeq());
        tBizFraud.setStatus("1");
        tBizFraud.setLinkType("1");
        itBizFraudService.updateById(tBizFraud);

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

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

    }


    @Override
    public void toEndCase(FraudProcessDto fraudProcessDto, TSTaskList tsTaskList, AICUser loginUser) {
        TBizFraud tBizFraud = itBizFraudService.getTBizFraudByBizSeq(fraudProcessDto.getBizSeq());
        tBizFraud.setBizHandleResult(fraudProcessDto.getBizHandleResult());
        tBizFraud.setStatus("3");
        itBizFraudService.updateById(tBizFraud);

        TFraudEnt tFraudEnt = itFraudEntService.getByBizSeq(fraudProcessDto.getBizSeq());
        BeanUtil.copyProperties(fraudProcessDto.getFraudEntInfo(), tFraudEnt);
        itFraudEntService.updateById(tFraudEnt);

        // 当投诉原因是“冒用他人信息登记”, 处理原因是101、102、103、199四类原因时，需要同步公示虚假登记责任人信息
        if ("冒用他人身份信息登记".equals(fraudProcessDto.getComplaintReason()) && StringUtils.containsAny(tFraudEnt.getHandleRea(), "101", "102", "103", "199")) {
            TFraudPerson tFraudPerson = itFraudPersonService.getByBizSeq(fraudProcessDto.getBizSeq());
            BeanUtil.copyProperties(fraudProcessDto.getFraudPersonInfo(), tFraudPerson);
            tFraudPerson.setHandleRea(tFraudEnt.getHandleRea());
            tFraudPerson.setHandleResult(tFraudEnt.getHandleResult());
            tFraudPerson.setJudAuth(tFraudEnt.getJudAuth());
            tFraudPerson.setJudauthCn(tFraudEnt.getJudAuthCn());
            tFraudPerson.setJudDate(tFraudEnt.getJudDate());
            itFraudPersonService.updateById(tFraudPerson);
        }

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


}
