package com.ningdatech.pmapi.scheduler.task;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Maps;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.pmapi.common.constant.RegionConst;
import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum;
import com.ningdatech.pmapi.common.helper.RegionCacheHelper;
import com.ningdatech.pmapi.scheduler.contants.TaskContant;
import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.sys.model.entity.Region;
import com.ningdatech.pmapi.sys.service.IRegionService;
import com.wflow.bean.dto.WflowModelHistorysDto;
import com.wflow.bean.entity.WflowForms;
import com.wflow.bean.entity.WflowModels;
import com.wflow.workflow.bean.dto.OrgInfoDTO;
import com.wflow.workflow.bean.process.ProcessNode;
import com.wflow.workflow.service.ProcessModelService;
import com.wflow.workflow.service.WflowFormsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author ZPF
 * @description
 * @since 2023/1/18 08:54
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class InitProcessTask {

    private final IRegionService regionService;

    private final ProcessModelService processModelService;

    private final WflowFormsService formsService;

    private final RegionCacheHelper regionCacheHelper;

    @Scheduled(cron = "0 14 16 07 3 ?")
    public void doTask() throws UnknownHostException {
        if (TaskContant.Host.HOST_ZPF.equals(InetAddress.getLocalHost().getHostName())) {
            log.info("=========== 初始化丽水二期 系统表单和流程配置 ======== 任务开始");
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            //1.查出丽水市下的 区县 分别去初始化 表单和流程配置数据
            List<RegionDTO> regions = regionCacheHelper.listChildren(RegionConst.RC_LS, RegionConst.RL_CITY);

            if(CollUtil.isEmpty(regions)){
                throw new BizException("丽水地区数据为空 任务结束!");
            }

            Map<String, WflowForms> formsMap = Maps.newConcurrentMap();
            //2.首先插入表单默认配置
            for(RegionDTO region : regions){
                log.info("当前初始化的是 【{}】 表单信息",region.getRegionName());

                WflowForms existsForm = formsService.getOne(Wrappers.lambdaQuery(WflowForms.class)
                        .eq(WflowForms::getRegionCode, region.getRegionCode())
                        .last("limit 1"));
                if(Objects.nonNull(existsForm)){
                    log.info("当前区域 【{}】 已经有表单数据 不需要初始化",region.getRegionName());
                    formsMap.put(existsForm.getRegionCode(),existsForm);
                    continue;
                }

                WflowForms wflowForms = new WflowForms();
                wflowForms.setFormId("fm" + IdUtil.objectId());
                wflowForms.setCreateOn(LocalDateTime.now());
                wflowForms.setUpdateOn(LocalDateTime.now());
                wflowForms.setFormName(TaskContant.Wflow.DEFAULT_FORM_NAME);
                wflowForms.setRegionCode(region.getRegionCode());
                wflowForms.setRegionName(region.getRegionName());
                if(formsService.save(wflowForms)){
                    log.info("当前区域 【{}】 表单数据已经保存成功",region.getRegionName());
                    formsMap.put(wflowForms.getRegionCode(),wflowForms);
                }else{
                    log.info("当前区域 【{}】 表单数据已经保存失败",region.getRegionName());
                }
            }

            //3.接着插入流程默认配置
            for(RegionDTO region : regions){
                log.info("当前初始化的是 【{}】 流程配置",region.getRegionName());

                if(processModelService.count(Wrappers.lambdaQuery(WflowModels.class)
                        .eq(WflowModels::getRegionCode,region.getRegionCode())) > 0){
                    log.info("当前区域 【{}】 已经有流程数据 不需要初始化",region.getRegionName());
                    continue;
                }

//                WflowForms form = formsMap.get(region.getRegionCode());
//                if(Objects.isNull(form)){
//                    log.info("此区域 【{}】 没有对应form 不进行 流程配置初始化",region.getRegionName());
//                    continue;
//                }

                Integer[] processTypeList = TaskContant.Wflow.DEFAULT_PROCESS_TYPE_LIST;
                for(Integer processType : processTypeList){
                    String formName = ProjectProcessStageEnum.getDesc(processType);
                    WflowModelHistorysDto models = new WflowModelHistorysDto();
//                    models.setFormId("wf" + IdUtil.objectId());
                    models.setVersion(1);
                    models.setGroupId(1);
                    models.setProcessDefId("pd" + IdUtil.objectId());
                    models.setFormName(formName);
                    models.setProcessType(processType);
                    models.setRegionCode(region.getRegionCode());
                    String process = "{\"children\":{\"children\":{},\"id\":\"node_039152532706\",\"name\":\"审批人\",\"parentId\":\"root\",\"props\":{\"mode\":\"AND\",\"role\":[],\"refuse\":{\"type\":\"TO_END\",\"target\":\"\"},\"assignedOrg\":[{\"orgName\":\"数转办\",\"orgCode\":\"GO_3bc86256687a4884ae410af00682b762\",\"type\":\"DEFAULT\",\"processDefId\":\"\"}],\"sign\":false,\"assignedType\":\"ASSIGN_ORG\",\"assignedDept\":[]},\"type\":\"SUB\"},\"id\":\"root\",\"name\":\"发起人\",\"props\":{\"formPerms\":[],\"assignedUser\":[]},\"type\":\"ROOT\"}";
                    ProcessNode processNode = JSON.parseObject(process,ProcessNode.class);
                    models.setProcess(processNode);
                    models.setSettings("{\"sign\":false,\"admin\":[],\"notify\":{},\"commiter\":[]}");
                    models.setFormItems("[]");

                    String formId = processModelService.saveProcess(models);
                    if(StringUtils.isNotBlank(formId)){
                        //初始的流程在部署表也存一份，用来查询
                        if(StringUtils.isNotBlank(processModelService.deployProcess(formId,null))){
                            log.info("当前区域 【{}】 流程名[{}] 流程数据已经保存成功",region.getRegionName(),formName);
                        }else{
                            log.info("当前区域 【{}】 流程名[{}] 流程数据保存失败",region.getRegionName(),formName);
                        }
                    }else{
                        log.info("当前区域 【{}】流程名[{}]  流程数据保存失败",region.getRegionName(),formName);
                    }
                }
            }

            stopWatch.stop();
            log.info("=========== 初始化丽水二期 系统表单和流程配置 ======== 任务结束 {}s",stopWatch.getTotalTimeSeconds());
        }
    }
}
