package com.ningdatech.pmapi.sys.manage;

import cn.hutool.core.bean.BeanUtil;
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.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.pmapi.common.constant.BizConst;
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.common.model.entity.MenuTreeEntity;
import com.ningdatech.pmapi.common.util.TreeUtil;
import com.ningdatech.pmapi.scheduler.contants.TaskContant;
import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.sys.model.entity.Menu;
import com.ningdatech.pmapi.sys.model.vo.MenuRoleVO;
import com.ningdatech.pmapi.sys.service.IMenuService;
import com.ningdatech.pmapi.sys.service.IRegionService;
import com.wflow.bean.dto.WflowModelHistorysInsertDto;
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.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * MenuManage - 菜单管理业务层
 * </p>
 *
 * @author WendyYang
 * @since 14:23 2023/1/28
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class MenuManage {

    private final IMenuService menuService;
    private final ProcessModelService processModelService;
    private final RegionCacheHelper regionCacheHelper;

    public List<MenuRoleVO> buildUserMenu(List<Menu> list) {
        Set<Long> menuIds = new HashSet<>();
        List<MenuRoleVO> menuRoles = CollUtils.convert(list, w -> {
            menuIds.add(w.getId());
            return BeanUtil.copyProperties(w, MenuRoleVO.class);
        });
        List<Long> pidList = menuRoles.stream()
                .map(MenuTreeEntity::getPid)
                .filter(pid -> !menuIds.contains(pid) && pid != BizConst.PARENT_ID)
                .collect(Collectors.toList());
        parentMenuCheck(pidList, menuRoles, menuIds);
        return TreeUtil.buildUserTree(menuRoles);
    }

    public void parentMenuCheck(List<Long> pidList, List<MenuRoleVO> menuRoles, Set<Long> menuIds) {
        if (pidList.isEmpty()) {
            return;
        }
        List<Menu> menus = menuService.listByIds(pidList);
        if (menus.isEmpty()) {
            return;
        }
        Set<Long> tmpSet = new HashSet<>();
        menus.forEach(w -> {
            menuIds.add(w.getId());
            tmpSet.add(w.getPid());
            menuRoles.add(BeanUtil.copyProperties(w, MenuRoleVO.class));
        });
        List<Long> tmpPidList = tmpSet.stream()
                .filter(pid -> !menuIds.contains(pid) && pid != BizConst.PARENT_ID)
                .collect(Collectors.toList());
        parentMenuCheck(tmpPidList, menuRoles, menuIds);
    }

    public String init() {
        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("丽水地区数据为空 任务结束!");
        }

        for(RegionDTO region : regions){
            log.info("当前初始化的是 【{}】 流程配置",region.getRegionName());

            Integer[] processTypeList = TaskContant.Wflow.APPLY_PROCESS_TYPE_LIST;
            for(Integer processType : processTypeList){
                String formName = ProjectProcessStageEnum.getDesc(processType);
                WflowModelHistorysInsertDto models = new WflowModelHistorysInsertDto();

                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.insertProcess(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());
        return "初始化完成";
    }
}
