package com.chinaweal.aiccs.aiccs.punishment.controller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chinaweal.aiccs.aiccs.abnormal.entity.EBaseinfo;
import com.chinaweal.aiccs.aiccs.abnormal.service.EBaseinfoService;
import com.chinaweal.aiccs.aiccs.auditing.entity.TSOpinion;
import com.chinaweal.aiccs.aiccs.auditing.service.TSOpinionService;
import com.chinaweal.aiccs.aiccs.business.entity.TSTaskList;
import com.chinaweal.aiccs.aiccs.business.entity.TSTwfProcessNode;
import com.chinaweal.aiccs.aiccs.business.entity.dto.TaskListUnionDto;
import com.chinaweal.aiccs.aiccs.business.service.TSTaskListService;
import com.chinaweal.aiccs.aiccs.business.service.TSTwfProcessNodeService;
import com.chinaweal.aiccs.aiccs.business.service.WorkFlowService;
import com.chinaweal.aiccs.aiccs.entbase.entity.TREntPriseType;
import com.chinaweal.aiccs.aiccs.entbase.service.TREntPriseTypeService;
import com.chinaweal.aiccs.aiccs.punishment.entity.TsbizPunishLock;
import com.chinaweal.aiccs.aiccs.punishment.service.*;
import com.chinaweal.aiccs.aiccs.punishment.util.BusTridMakeUtil;
import com.chinaweal.aiccs.common.base.controller.BaseController;
import com.chinaweal.aiccs.common.constant.BaseDataConstant;
import com.chinaweal.aiccs.common.constant.Constant;
import com.chinaweal.aiccs.common.util.FlowUtil;
import com.chinaweal.aiccs.common.util.StringUtils;
import com.chinaweal.aiccs.common.util.WorkFlowUtil;
import com.chinaweal.aicorg.model.AICUser;
import com.chinaweal.youfool.framework.springboot.exception.custom.BusinessException;
import com.chinaweal.youfool.framework.springboot.mybatis.plus.page.PageRequestDto;
import com.chinaweal.youfool.framework.springboot.rest.RestResult;
import com.chinaweal.youfool.framework.springboot.rest.ResultCode;
import com.chinaweal.youfool.framework.springboot.util.AssertUtils;
import com.chinaweal.youfool.framework.springboot.util.DateTimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;


/**
 * <p>
 * 联合惩戒锁定业务表 前端控制器
 * </p>
 *
 * @author Lee
 * @since 2021-06-06
 */
@Slf4j
@RestController
@RequestMapping("/tsbizPunishLock")
public class TsbizPunishLockController extends BaseController implements ServletContextListener {

    @Autowired
    private EBaseinfoService eBaseinfoService;
    @Autowired
    private TsbizPunishLockService tsbizPunishLockService;
    @Autowired
    private TSTaskListService taskListService;
    @Autowired
    private TolockentlistService tolockentlistService;
    @Autowired
    private AqschmdAjService aqschmdAjService;
    @Autowired
    private HgsxrzqymdService hgsxrzqymdService;
    @Autowired
    private WorkFlowService workFlowService;
    @Autowired
    private BusTridMakeUtil busTridMakeUtil;
    @Autowired
    private TSOpinionService opinionService;
    @Autowired
    private TSTwfProcessNodeService tsTwfProcessNodeService;
    @Autowired
    private PunishmeasuresService punishmeasuresService;

    @Autowired
    private TREntPriseTypeService trEntPriseTypeService;

    @Autowired
    private EntlockService entlockService;

    @Autowired
    private PersonlockService personlockService;

    /**
     * 线程池
     **/
    private final ExecutorService executorService = Executors.newFixedThreadPool(50);

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        executorService.shutdown();
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {

    }

    @PostMapping(value = "/saveAccept")
    public RestResult<?> saveAccept(String pripids, String punishFrom, HttpServletRequest request) {

        AssertUtils.isNotBlank(pripids);
        AICUser aicUser = getLoginUser(request);
        //生成业务号
        String bizSeq = UUID.randomUUID().toString();
        String[] pripidArray = pripids.split(Constant.SEMICOLON);

        ArrayList<TsbizPunishLock> tsbizPunishLocks = new ArrayList<>();
        for (int i = 0; i < pripidArray.length; i++) {
            if (tsbizPunishLockService.checkpunishlock(pripidArray[i])) {
                return RestResult.error(ResultCode.BUSINESS_ASSOCIATED, "该主体已存在锁定业务中");
            }
            LambdaQueryWrapper<EBaseinfo> eBaseinfoWrapper = new LambdaQueryWrapper<>();
            eBaseinfoWrapper.eq(EBaseinfo::getPripid, pripidArray[i]);
            EBaseinfo one = eBaseinfoService.getOne(eBaseinfoWrapper);
            if (entlockService.check(pripidArray[i]) != null && !"3".equals(entlockService.check(pripidArray[i]).getState())) {
                return RestResult.error(ResultCode.BUSINESS_ASSOCIATED, "该主体还在锁定中");
            }

            if (personlockService.check(one.getLerep()) != null && "1".equals(personlockService.check(one.getLerep()).getLockstate())) {
                return RestResult.error(ResultCode.BUSINESS_ASSOCIATED, "该法人还在锁定中");
            }
        }

        LambdaQueryWrapper<EBaseinfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(EBaseinfo::getPripid, pripidArray);
        List<EBaseinfo> eBaseinfolists = eBaseinfoService.list(queryWrapper);
        for (int i = 0; i < eBaseinfolists.size(); i++) {

            TsbizPunishLock tsbizPunishLockModel = new TsbizPunishLock();
//        LambdaQueryWrapper<Tolockentlist> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(Tolockentlist::getPunishFrom,punishFrom);
//        queryWrapper.in(Tolockentlist::getPripid,pripidArray);
//        List<Tolockentlist> tolockentlists = tolockentlistService.list(queryWrapper);
//        for (int i = 0; i < tolockentlists.size(); i++) {
            //Tolockentlist tolockentlist = tolockentlists.get(i);
//            tsbizPunishLockModel.setBizseq(bizSeq);
//            tsbizPunishLockModel.setPripid(tolockentlist.getPripid());
//            tsbizPunishLockModel.setRegno(tolockentlist.getRegno());
//            tsbizPunishLockModel.setUniscid(tolockentlist.getUniscid());
//            tsbizPunishLockModel.setEntname(tolockentlist.getEntName());
//            tsbizPunishLockModel.setApprovaldate(LocalDate.now());
//            tsbizPunishLockModel.setPunishFrom(punishFrom);
//            tsbizPunishLockModel.setPunishInfoId(tolockentlist.getPunishInfoId());
//            tsbizPunishLockModel.setTolockentlistid(tolockentlist.getTolockId());

            EBaseinfo eBaseinfo = eBaseinfolists.get(i);
            tsbizPunishLockModel.setBizseq(bizSeq);
            tsbizPunishLockModel.setPripid(eBaseinfo.getPripid());
            tsbizPunishLockModel.setRegno(eBaseinfo.getRegno());
            tsbizPunishLockModel.setUniscid(eBaseinfo.getUniscid());
            tsbizPunishLockModel.setEntname(eBaseinfo.getEntname());
            tsbizPunishLockModel.setApprovaldate(LocalDate.now());
            //tsbizPunishLockModel.setPunishFrom(punishFrom);
            tsbizPunishLockModel.setLocktype("001");
            tsbizPunishLocks.add(tsbizPunishLockModel);
        }
        if (tsbizPunishLocks.size() == 0) throw new BusinessException("尚未查找到主体信息");
        //待办
        TSTaskList taskListModel = new TSTaskList();
        taskListModel.setBizseqid(bizSeq);
        taskListModel.setBustype(BaseDataConstant.PUNISH_TYPE_LOCK);
        //封装待办业务名称
        String entname = "联合惩戒锁定" + busTridMakeUtil.getLockCurAcceptNo();
        String entname1 = eBaseinfolists.get(0).getEntname();
        if (eBaseinfolists.size() > 1) {
            taskListModel.setBusname(entname1 + "等企业");
        }
        taskListModel.setBusname(entname1);
        //taskListModel = tsbizPunishLockService.savePunishLockAccept(aicUser, taskListModel, tsbizPunishLocks, tolockentlists);
        taskListModel = tsbizPunishLockService.savePunishLockAccept(aicUser, taskListModel, tsbizPunishLocks, null);
        //taskListModel = tsbizPunishLockService.savePunishLockAccept(aicUser, taskListModel, tsbizPunishLocks);
        if (StringUtils.isNotBlank(taskListModel.getTasklistid())) {
            Map<String, String> result = new HashMap<>();
            result.put("tasklistid", taskListModel.getTasklistid());
            result.put("bizseq", bizSeq);
            result.put("workflowId", taskListModel.getWorkflowid());
            return RestResult.ok(result);
        }
        return OK;
    }

    @PostMapping(value = "/next")
    public RestResult<?> next(HttpServletRequest request, TsbizPunishLock tsbizPunishLockModel, TSOpinion opinionModel,
                              String tasklistid, String nextPerformerids, String nextPerformerNames, String nextNodeID) {
        AICUser user = getLoginUser(request);
        Map<String, Object> resultMap = new HashMap<>();

        //更新业务表
        if (tsbizPunishLockModel != null && StringUtils.isNotBlank(tsbizPunishLockModel.getBizseq())) {
            TSTaskList taskListModel = taskListService.selectByTasklistID(tasklistid);
            TsbizPunishLock paramModel = new TsbizPunishLock();
            LambdaQueryWrapper<TsbizPunishLock> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(TsbizPunishLock::getBizseq, tsbizPunishLockModel.getBizseq());
            //批量，业务主体有多个
            List<TsbizPunishLock> tsbizPunishLocks = tsbizPunishLockService.list(wrapper);
            LocalDateTime nowDateTime = LocalDateTime.now();
            for (TsbizPunishLock bizPunishLockModel : tsbizPunishLocks) {
                //下一步为审核
                if (FlowUtil.PUNISHWORKFLOWE_HANDLEPUNISH.equals(nextNodeID)) {
                    TSTwfProcessNode processNode = workFlowService.findCurrentNode(taskListModel.getWorkflowid());
                    int order = WorkFlowUtil.checkNextOrder(processNode.getCurrentnode(), nextNodeID);
                    if (order > 0) {
//                        LambdaQueryWrapper<Punishmeasures> queryWrapper = new LambdaQueryWrapper<>();
//                        queryWrapper.eq(Punishmeasures::getMeasure,tsbizPunishLockModel.getMeasure());
//                        Punishmeasures one = punishmeasuresService.getOne(queryWrapper);
//                        Set<String> strings = PunishFromAndDepartmentMap.keySet();
//                        for (String string : strings) {
//                            if(one.getDepartmentCode().equals(PunishFromAndDepartmentMap.get(string))){
//                                bizPunishLockModel.setPunishFrom(string);
//                            }
//                        }
                        bizPunishLockModel.setPunishFrom(tsbizPunishLockModel.getPunishFrom());
                        bizPunishLockModel.setLockreason(tsbizPunishLockModel.getLockreason());
                        bizPunishLockModel.setMeasure(tsbizPunishLockModel.getMeasure());
                        bizPunishLockModel.setLocktype(tsbizPunishLockModel.getLocktype());
                        bizPunishLockModel.setLockusername(user.getName());
                        bizPunishLockModel.setLockTime(nowDateTime);
                    }
                }
            }
            if (StringUtils.isBlank(nextPerformerids)) {
                TSTwfProcessNode processNode = workFlowService.findCurrentNode(taskListModel.getWorkflowid());
                int order = WorkFlowUtil.checkNextOrder(processNode.getCurrentnode(), nextNodeID);
                // 通过order判断为回退还是前进 >0前进
                if (order > 0) {
                    LambdaQueryWrapper<TSOpinion> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(TSOpinion::getWorkflowid, taskListModel.getWorkflowid())
                            .eq(TSOpinion::getOpiniontype, "0")// 经办为0
                            .orderByDesc(TSOpinion::getLauptime);
                    List<TSOpinion> list = opinionService.list(queryWrapper);
                    if (org.apache.commons.collections4.CollectionUtils.isEmpty(list)) {
                        return RestResult.error(ResultCode.DATA_NONE);
                    }
                    nextPerformerids = list.get(0).getHandlerid();
                    nextPerformerNames = list.get(0).getHandler();
                }
                // 回退时 获取上一个处理人
                if (order < 0) {
                    if (taskListModel == null) {
                        return RestResult.error(ResultCode.DATA_NONE);
                    }
                    List<TSTwfProcessNode> tsTwfProcessNodes = tsTwfProcessNodeService.queryByPROCESSIDAndCURRENTNODE(taskListModel.getWorkflowid(), nextNodeID);
                    nextPerformerids = tsTwfProcessNodes.get(0).getCurruserid();
                    nextPerformerNames = tsTwfProcessNodeService.queryRealName(tsTwfProcessNodes.get(0).getCurruserid());
//                    nextPerformerids = taskListModel.getSenderuserid();
//                    nextPerformerNames = taskListModel.getSendername();
                }
            }

            //发送
            String[] ids = StringUtils.split(nextPerformerids, Constant.COMMA);
            String[] names = StringUtils.split(nextPerformerNames, Constant.COMMA);
            tsbizPunishLockService.savePunishLockProcess(user, taskListModel, tsbizPunishLocks, opinionModel, nextNodeID, ids, names);
            if (ids.length == 1 && StringUtils.equals(user.getPrimaryKey(), ids[0])) {
                resultMap.put("bizseq", tsbizPunishLockModel.getBizseq());
                resultMap.put("nextNodeId", nextNodeID);
                resultMap.put("taskListId", tasklistid);
                resultMap.put("workFlowId", taskListModel.getWorkflowid());
            }
        } else {
            return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR);
        }
        return RestResult.ok(resultMap);
    }

    /**
     * 联合惩戒锁定批量审核/审核
     */
    @PostMapping("/batchLhcjsdReviewAndExamine")
    public RestResult<?> batchLhcjsdReviewAndExamine(@RequestBody Map<String, Object> data, HttpServletRequest request) {
        AICUser user = getLoginUser(request);
        List<TaskListUnionDto> taskList = JSONObject.parseArray(JSONObject.toJSONString(data.get("taskListUnionDto")), TaskListUnionDto.class);

        String nextNodeID = (String) data.get("nextNodeID");
        String opinion = (String) data.get("opinion");
        String batchType = (String) data.get("batchType");
        String handledateStr = (String) data.get("handledate");
        LocalDateTime handledate = LocalDateTime.parse(handledateStr, DateTimeUtils.DATETIME_FORMATTER);

        String nextPerformerids = null;
        String nextPerformerNames = null;
        if (data.get("nextPerformerids") != null) {
            nextPerformerids = (String) data.get("nextPerformerids");
            nextPerformerNames = (String) data.get("nextPerformerNames");
        }
        if ("end".equals(nextNodeID) && CollectionUtils.isNotEmpty(taskList) && taskList.size() > 100)
            throw new BusinessException("超出最大审批数量，最多不能超过100条。");
        CountDownLatch countDownLatch = new CountDownLatch(taskList.size());

        //遍历批量审核列表参数，并调用方法
        for (TaskListUnionDto taskListUnionDto : taskList) {
            String finalNextPerformerids = nextPerformerids;
            String finalNextPerformerNames = nextPerformerNames;
            Runnable runnable = () -> {
                TsbizPunishLock tsbizPunishLock = new TsbizPunishLock();
                tsbizPunishLock.setBizseq(taskListUnionDto.getBizseqid());

                TSOpinion opinionModel = new TSOpinion();
                opinionModel.setWorkflowid(taskListUnionDto.getWorkflowid());
                opinionModel.setHandler(user.getName());
                opinionModel.setHandlerid(user.getPrimaryKey());
                opinionModel.setOpinioncontent(opinion);
                opinionModel.setHandledate(handledate);

                if (batchType.equals("review")) {
                    //审核
                    opinionModel.setOpiniontype("1");
                } else if (batchType.equals("examine")) {
                    //审批
                    opinionModel.setOpiniontype("2");
                }

                next(request, tsbizPunishLock, opinionModel, taskListUnionDto.getTasklistid(), finalNextPerformerids, finalNextPerformerNames, nextNodeID);
                countDownLatch.countDown();//减1
            };
            executorService.submit(runnable);
        }

        try {
            countDownLatch.await(5, TimeUnit.MINUTES);//5分钟超时
        } catch (Exception e) {
            log.error("批量审核/审批失败", e);
        }
        return OK;
    }


    @PostMapping("getEntInfoPageandPunishFrom")
    public RestResult<?> getEntInfoPageandPunishFrom(@RequestBody PageRequestDto pageRequestDto) {
        String punishfrom = " ";

        AssertUtils.isNotNull(pageRequestDto, pageRequestDto.getCustomParamMap());
        Map<String, Object> customParamMap = pageRequestDto.getCustomParamMap();
        String bizseq = StringUtils.tranObject(customParamMap.get("bizseq"));
        String searchName = StringUtils.tranObject(customParamMap.get("searchName"));
        AssertUtils.isNotBlank(bizseq);
        LambdaQueryWrapper<TsbizPunishLock> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TsbizPunishLock::getBizseq, bizseq);
        wrapper.like(StringUtils.isNotBlank(searchName), TsbizPunishLock::getEntname, searchName);
        List<TsbizPunishLock> tsbizPunishLocks = tsbizPunishLockService.list(wrapper);

        if (tsbizPunishLocks.size() == 0) {
            return RestResult.error(ResultCode.DATA_NONE);
        }
        ArrayList<String> infoIds = new ArrayList<>();
        for (TsbizPunishLock tsbizPunishLock : tsbizPunishLocks) {
//            infoIds.add(tsbizPunishLock.getPunishInfoId());
            infoIds.add(tsbizPunishLock.getPripid());
        }
        TsbizPunishLock tsbizPunishLockModel = tsbizPunishLocks.get(0);
        if (null != tsbizPunishLockModel.getPunishFrom()) {
            punishfrom = tsbizPunishLockModel.getPunishFrom();
        }
        //6月23日String punishFrom = tsbizPunishLockModel.getPunishFrom();
        //6月23日String department = PunishFromAndDepartmentMap.get(punishFrom);
        Page<?> page = new Page<>();
//        switch (punishFrom){
//            case "1": // 安全生产黑名单（安监总局）
//                LambdaQueryWrapper<AqschmdAj> queryWrapper1 = new LambdaQueryWrapper<>();
//                queryWrapper1.in(AqschmdAj::getId,infoIds);
//                page = aqschmdAjService.page(new Page<>(pageRequestDto.getCurPage(), pageRequestDto.getPageSize()), queryWrapper1);
//                break;
//            case "3": //海关失信认证企业名单（海关总署）
//                LambdaQueryWrapper<Hgsxrzqymd> queryWrapper3 = new LambdaQueryWrapper<>();
//                queryWrapper3.in(Hgsxrzqymd::getId,infoIds);
//                page = hgsxrzqymdService.page(new Page<>(pageRequestDto.getCurPage(), pageRequestDto.getPageSize()), queryWrapper3);
//                break;
//            default:
//                break;
//        }
        LambdaQueryWrapper<EBaseinfo> queryWrapper3 = new LambdaQueryWrapper<>();
        queryWrapper3.in(EBaseinfo::getPripid, infoIds);
        List<EBaseinfo> eBaseinfos = eBaseinfoService.list(queryWrapper3);
        LambdaQueryWrapper<TREntPriseType> trEntPriseTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        for (EBaseinfo eBaseinfo : eBaseinfos) {
            trEntPriseTypeLambdaQueryWrapper.eq(TREntPriseType::getEnttypeid, eBaseinfo.getEnttype());
            TREntPriseType one = trEntPriseTypeService.getOne(trEntPriseTypeLambdaQueryWrapper);
            eBaseinfo.setEnttypeCn(one.getPrintvalue());
        }


        HashMap<String, Object> map = new HashMap<>();
        //6月23日map.put("punishFrom",punishFrom);
        map.put("punishFrom", punishfrom);
        map.put("lockReason", tsbizPunishLockModel.getLockreason());
//        map.put("lockUserName",tsbizPunishLockModel.getLockusername());
        map.put("locktype", tsbizPunishLockModel.getLocktype());
        map.put("measure", tsbizPunishLockModel.getMeasure());
        //6月23日map.put("department",department);
        map.put("department", " ");
        map.put("page", eBaseinfos);
        return RestResult.ok(map);
    }


}

