package com.sifang.modules.sys.util;

import com.google.common.collect.Maps;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.setting.constant.ProcessSetConstants;
import com.sifang.modules.sys.common.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

public class FormSetUtils {

    private static Logger logger = LoggerFactory.getLogger(FormSetUtils.class);
    // 存储资方id集合
    private static List<String> capitals = Arrays.asList("01");

    /**
     * 获取资方-越秀在系统的编号
     */
    public static String getYXCapitalId() {
        return capitals.get(0);
    }

    public static List<PartnerStepVo> findAllPartnerStep() {
        List<Record> records = Db.find("SELECT p.id, p.person_in_charge as name FROM crm_partner p WHERE 1=1 and p.status = '0' ORDER BY p.`id`");
        List<PartnerStepVo> stepVos = new ArrayList<>();
        List<Record> stepList = Db.find("SELECT * FROM sys_form_stage s WHERE 1=1 ORDER BY s.`sort`");
        List<StepVo> vos = new ArrayList<>();
        for (Record r : stepList) {
            StepVo vo = new StepVo();
            vo.setId(r.getStr("id"));
            vo.setName(r.getStr("name"));
            vo.setSort(r.getInt("sort"));
            vos.add(vo);
        }
        for (Record r : records) {
            PartnerStepVo vo = new PartnerStepVo();
            vo.setId(r.getStr("id"));
            vo.setName(r.getStr("name"));
            vo.setStep(vos);
            stepVos.add(vo);
        }
        return stepVos;
    }

    /**
     * 获取某阶段的表单设置
     * @param step  阶段节点id，可为空
     * @param partner 资方id，不可为空
     * @param selectUsed 筛选数据范围：true 已启用的，false 全部
     */
    public static List<Record> getRecordFormPartSetByStep(LayuiPage<Record> page,String type, String step,
                                                          String partner, boolean selectUsed) {
        SqlBuilder sb = new SqlBuilder();
        sb.line("SELECT s.id, s.type, s.`stage`, cp.name as 'partnerName', fs.`name` AS 'stageName', ");
        sb.line("s.`group_type`, s.`column_name`, s.`sort`, c.`param_name`, c.`must_fill_flag`,");
        sb.line("s.`must_fill_flag` AS parent_must_fill_flag, s.group_flag, s.column_type, s.`column_key`, ");
        sb.line("s.parent_set, gt.name AS group_type_name, c.`id` AS cid, c.status, c.limit_flag,s.remarks");
        sb.line("FROM crm_form_set s ");
        sb.line("INNER JOIN sys_form_stage fs ON fs.`id`= s.`stage` ");
        sb.line("INNER JOIN sys_form_group_type gt ON gt.`id`= s.`group_type` ");
        sb.line("INNER JOIN crm_partner cp ON cp.`id`= ?", partner);
        sb.line("INNER JOIN crm_form_partner_set c ");
        sb.line("ON s.`id` = c.`form_set_id` AND c.`partner` = ? ", partner);
        if (selectUsed) {
            sb.line("AND c.`status` = '1' ");
        }
        sb.line("WHERE s.`is_show` = '1' ");
        if (StringUtil.isNotBlank(step)) {
            sb.line(" AND s.`stage` = ? ", step);
        }
        if (StringUtil.isNotBlank(type)) {
            sb.line(" AND s.`type` = ? ", type);
        }
        sb.line(" ORDER BY s.stage, s.group_type, s.sort ");
        if (page != null) {
            sb.line(" limit " + page.getLimit() + " offset " + (page.getPage() - 1) * page.getLimit());
            Long count = countFormPartSetByStep(type, step, partner, selectUsed);
            page.setCount(count);
        }
        logger.info("getFormCaSetByStep， build:{}, params:{}", sb.build(), sb.params());
        return Db.find(sb.build(), sb.params());
    }

    public static Long countFormPartSetByStep(String type, String step, String partner, boolean selectUsed) {
        SqlBuilder sb = new SqlBuilder();
        sb.line("SELECT count(1) ");
        sb.line("FROM crm_form_set s ");
        sb.line("INNER JOIN sys_form_stage fs ON fs.`id`= s.`stage` ");
        sb.line("INNER JOIN sys_form_group_type gt ON gt.`id`= s.`group_type` ");
        sb.line("INNER JOIN crm_partner cp ON cp.`id`= ?", partner);
        sb.line("INNER JOIN crm_form_partner_set c ");
        sb.line("ON s.`id` = c.`form_set_id` AND c.`partner` = ? ", partner);
        if (selectUsed) {
            sb.line("AND c.`status` = '1' ");
        }
        sb.line("WHERE s.`is_show` = '1' ");
        if (StringUtil.isNotBlank(step)) {
            sb.line(" AND s.`stage` = ? ", step);
        }
        if (StringUtil.isNotBlank(type)) {
            sb.line(" AND s.`type` = ? ", type);
        }
        return Db.queryLong(sb.build(), sb.params());
    }

    public static List<FormSetVo> getFormPartSetByStep(LayuiPage<Record> page,String type,
                                                       String step, String partner, boolean selectUsed) {
        List<Record> records = getRecordFormPartSetByStep(page, type, step, partner, selectUsed);
        List<FormSetVo> voList = new ArrayList<>();
        for (Record r : records) {
            FormSetVo vo = new FormSetVo();
            vo.setValues(r);
            voList.add(vo);
        }
        return voList;
    }

    /**
     * 校验启用的表单是否有效，有效则返回空，无效则返回无效原因
     */
    public static String checkSetValid(List<FormSetVo> list) {
        String result = "";
        Map<String, Long> groupFlagMap = Maps.newHashMap();
        Map<String, String> groupNameMap = Maps.newHashMap();
        for (FormSetVo vo : list) {
            if ("1".equals(vo.getUseFlag()) && !"-1".equals(vo.getGroupFlag())) {
                String key = vo.getGroupFlag();
                Long num = groupFlagMap.get(key);
                String name = (StringUtil.isNotBlank(groupNameMap.get(key)) ? groupNameMap.get(key) : "");
                if (num == null) {
                    num = 0L;
                    name = vo.getColumnName();
                }
                else {
                    name = name + "," + vo.getColumnName();
                }
                num++;
                groupNameMap.put(key, name);
                groupFlagMap.put(key,num);
            }
        }
        ArrayList<String> strings = new ArrayList<>(groupFlagMap.keySet());
        StringBuilder sb = new StringBuilder();
        sb.append("select s.group_flag, count(s.id) as num ");
        sb.append("from crm_form_set s ");
        sb.append("where s.is_show = '1' AND s.`group_flag` != '-1' ");
        sb.append(" and s.group_flag in (" + StringUtil.joinInSql(strings) + ")");
        sb.append("group by s.group_flag having count(s.id) > 1");
        logger.info("checkSetValid, sql : {}", sb);
        List<Record> records = Db.find(sb.toString());
        for (Record r :records) {
            long rNum = r.getLong("num");
            String key = r.getStr("group_flag");
            Long num = groupFlagMap.get(key);
            num = (num == null ? 0L:num);
            if (rNum != num) {
                return groupNameMap.get(key) + "为一组，要求一同启用或禁用";
            }
        }
        return result;
    }

    /**
     * 判断过程设置是否启用 且为必要节点
     * @param partnerId
     * @param key
     * @return
     */
    public static boolean processSetEnable(String partnerId, String key) {
        if (StringUtil.isAnyBlank(partnerId, key)) {
            logger.error("缺少必要参数");
            throw new IllegalArgumentException("缺少参数：资方id不存在");
        }
        String mustFlag = Db.queryStr("select b.status from crm_entry_process_set a inner join crm_entry_process_partner_set b " +
                "on a.id=b.process_set_id where b.partner=? and a.id=? and status='1'", partnerId, key);
        if (StringUtil.isBlank(mustFlag)) {//未设置
            return false;
        } else {
            return ProcessSetConstants.MUST_FLAG_YES.equals(mustFlag) ? true : false;
        }
    }

    /**
     * 获取自定义字段
    */
    public static List<Record> findEntryAzImgs(){
        SqlBuilder sql =new SqlBuilder();
        sql.line("SELECT * FROM `crm_form_set` WHERE `stage` = '03' AND TYPE = '2' AND create_time = '2024-01-18 16:30:15' order by sort asc ");
        return Db.find(sql.build(),sql.params());
    }

    /**
     * 获取自定义字段
     */
    public static List<Record> findEntryImgs(String stage){
        SqlBuilder sql =new SqlBuilder();
        sql.line("SELECT * FROM `crm_form_set` WHERE `stage` = ? AND TYPE = '2' AND is_show='1' and column_type='9'",stage);
        if("02".equals(stage)){
            sql.line(" and group_type ='0201' ");
        }
        sql.line("  order by sort asc  ");
        return Db.find(sql.build(),sql.params());
    }

}
