package com.yunzhupaas.base.util;

import cn.hutool.core.util.ObjectUtil;
import com.yunzhupaas.model.visualJson.FieLdsModel;
import com.yunzhupaas.model.visualJson.config.ConfigModel;
import com.yunzhupaas.util.*;
import com.yunzhupaas.util.visiual.YunzhupaasKeyConsts;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 在线开发公用
 *
 * @author 云筑产品开发平台组
 * @version V3.1.0
 * @copyright 深圳市乐程软件有限公司（http://www.szlecheng.cn）
 * @date 2024/7/28
 */
public class FormPublicUtils {

    /**
     * 递归控件，除子表外控件全部提到同级
     * 取子集，子表不外提
     *
     * @return
     */
    public static void recursionFieldsExceptChild(List<FieLdsModel> allFields, List<FieLdsModel> fieLdsModelList) {
        for (FieLdsModel fieLdsModel : fieLdsModelList) {
            ConfigModel config = fieLdsModel.getConfig();
            String yunzhupaasKey = config.getYunzhupaasKey();
            if (YunzhupaasKeyConsts.CHILD_TABLE.equals(yunzhupaasKey)) {
                allFields.add(fieLdsModel);
                continue;
            } else {
                if (config.getChildren() != null) {
                    recursionFieldsExceptChild(allFields, config.getChildren());
                } else {
                    if (yunzhupaasKey == null) {
                        continue;
                    }
                    allFields.add(fieLdsModel);
                }
            }
        }
    }

    /**
     * 转换时间格式
     *
     * @param time
     * @return
     */
    public static String getTimeFormat(String time) {
        String result;
        switch (time.length()) {
            case 16:
                result = time + ":00";
                break;
            case 19:
                result = time;
                break;
            case 21:
                result = time.substring(0, time.length() - 2);
                break;
            case 10:
                result = time + " 00:00:00";
                break;
            case 8:
                result = "2000-01-01 " + time;
                break;
            case 7:
                result = time + "-01 00:00:00";
                break;
            case 4:
                result = time + "-01-01 00:00:00";
                break;
            default:
                result = "";
                break;
        }
        return result;
    }

    public static String getLastTimeFormat(String time) {
        String result;
        switch (time.length()) {
            case 16:
                result = time + ":00";
                break;
            case 19:
                result = time;
                break;
            case 10:
                result = time + " 23:59:59";
                break;
            case 8:
                result = "2000-01-01 " + time;
                break;
            case 7:
                // 获取月份最后一天
                String[] split = time.split("-");
                Calendar cale = Calendar.getInstance();
                cale.set(Calendar.YEAR, Integer.valueOf(split[0]));// 赋值年份
                cale.set(Calendar.MONTH, Integer.valueOf(split[1]) - 1);// 赋值月份
                int lastDay = cale.getActualMaximum(Calendar.DAY_OF_MONTH);// 获取月最大天数
                cale.set(Calendar.DAY_OF_MONTH, lastDay);// 设置日历中月份的最大天数
                cale.set(Calendar.HOUR_OF_DAY, 23);
                cale.set(Calendar.SECOND, 59);
                cale.set(Calendar.MINUTE, 59);
                result = DateUtil.daFormatHHMMSS(cale.getTime().getTime());
                break;
            case 4:
                result = time + "-12-31 23:59:59";
                break;
            default:
                result = "";
                break;
        }
        return result;
    }

    /**
     * 判断时间是否在设置范围内
     *
     * @param swapDataVo
     * @param format
     * @param value
     * @param data
     * @param yunzhupaasKey
     * @return
     */
    public static boolean dateTimeCondition(FieLdsModel swapDataVo, String format, Object value,
            Map<String, Object> data, String yunzhupaasKey) {
        long valueTimeLong;
        // 输入值转long
        if (value instanceof String) {
            valueTimeLong = cn.hutool.core.date.DateUtil.parse(String.valueOf(value), format).getTime();
        } else {
            // 输入值按格式补全
            String timeFormat = getTimeFormat(String.valueOf(value));
            valueTimeLong = DateUtil.stringToDate(timeFormat).getTime();
        }
        boolean timeHasRangeError = false;
        // 开始时间判断
        if (swapDataVo.getConfig().getStartTimeRule()) {
            String startTimeValue = swapDataVo.getConfig().getStartTimeValue();
            String startTimeType = swapDataVo.getConfig().getStartTimeType();
            String startTimeTarget = swapDataVo.getConfig().getStartTimeTarget();
            String startTimeRelationField = swapDataVo.getConfig().getStartRelationField();
            // 根据类型获取开始时间戳
            long startTimeLong = getDateTimeLong(data, yunzhupaasKey, startTimeValue, startTimeType, startTimeTarget,
                    startTimeRelationField, format);
            if (startTimeLong != 0 && valueTimeLong < startTimeLong) {
                timeHasRangeError = true;
            }
        }
        // 结束时间判断
        if (swapDataVo.getConfig().getEndTimeRule()) {
            String endTimeValue = swapDataVo.getConfig().getEndTimeValue();
            String endTimeType = swapDataVo.getConfig().getEndTimeType();
            String endTimeTarget = swapDataVo.getConfig().getEndTimeTarget();
            String endTimeRelationField = swapDataVo.getConfig().getEndRelationField();
            // 根据类型获取开始时间戳
            long endTimeLong = getDateTimeLong(data, yunzhupaasKey, endTimeValue, endTimeType, endTimeTarget,
                    endTimeRelationField, format);
            if (endTimeLong != 0 && valueTimeLong > endTimeLong) {
                timeHasRangeError = true;
            }
        }
        return timeHasRangeError;
    }

    /**
     * 根据类型获取时间戳
     *
     * @param data
     * @param yunzhupaasKey
     * @param timeValue
     * @param timeType
     * @param timeTarget
     * @return
     */
    public static long getDateTimeLong(Map<String, Object> data, String yunzhupaasKey, String timeValue,
            String timeType, String timeTarget,
            String stringimeRelationField, String format) {
        if (StringUtil.isEmpty(timeValue)) {
            timeValue = "0";
        }
        long startTimeLong = 0;
        // 当前格式的当前时间戳
        long timestampInMillis = new Date().getTime();
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            String s = sdf.format(new Date());
            timestampInMillis = sdf.parse(s).getTime();
        } catch (ParseException e) {
        }
        switch (timeType) {
            case "1":// 特定时间
                if (YunzhupaasKeyConsts.DATE.equals(yunzhupaasKey)) {
                    startTimeLong = Long.parseLong(timeValue);
                } else {
                    String newDateStr = DateUtil.daFormat(new Date()) + " " + timeValue
                            + (timeValue.length() > 6 ? "" : ":00");
                    startTimeLong = DateUtil.stringToDate(newDateStr).getTime();
                }
                break;
            case "2":// 表单字段
                if (stringimeRelationField != null) {
                    String fieldValue = "";
                    if (stringimeRelationField.toLowerCase().contains(YunzhupaasKeyConsts.CHILD_TABLE_PREFIX)) {// 子
                        String[] split = stringimeRelationField.split("-");
                        fieldValue = data.get(split[1]) != null ? data.get(split[1]).toString() : "";
                    } else {// 主副
                        Map<String, Object> mainAndMast = data.get("mainAndMast") != null
                                ? JsonUtil.entityToMap(data.get("mainAndMast"))
                                : data;
                        fieldValue = mainAndMast.get(stringimeRelationField) != null
                                ? mainAndMast.get(stringimeRelationField).toString()
                                : "";
                    }
                    if (StringUtil.isNotEmpty(fieldValue)) {
                        String timeFormat = getTimeFormat(fieldValue);
                        startTimeLong = cn.hutool.core.date.DateUtil.parse(timeFormat, "yyyy-MM-dd HH:mm:ss").getTime();
                    }
                }
                break;
            case "3":// 填写当前时间
                startTimeLong = timestampInMillis;
                break;
            case "4":// 当前时间前
                Calendar caledel = Calendar.getInstance();
                caledel.setTimeInMillis(timestampInMillis);
                if (YunzhupaasKeyConsts.DATE.equals(yunzhupaasKey)) {
                    switch (timeTarget) {
                        case "1":// 年
                            caledel.set(Calendar.YEAR, caledel.get(Calendar.YEAR) - Integer.valueOf(timeValue));// 赋值年份
                            break;
                        case "2":// 月
                            caledel.set(Calendar.MONTH, caledel.get(Calendar.MONTH) - Integer.valueOf(timeValue));
                            break;
                        case "3":// 日
                            caledel.set(Calendar.DAY_OF_MONTH,
                                    caledel.get(Calendar.DAY_OF_MONTH) - Integer.valueOf(timeValue));
                            break;
                    }
                } else {
                    switch (timeTarget) {
                        case "1":// 时
                            caledel.set(Calendar.HOUR_OF_DAY,
                                    caledel.get(Calendar.HOUR_OF_DAY) - Integer.valueOf(timeValue));
                            break;
                        case "2":// 分
                            caledel.set(Calendar.MINUTE, caledel.get(Calendar.MINUTE) - Integer.valueOf(timeValue));
                            break;
                        case "3":// 秒
                            caledel.set(Calendar.SECOND, caledel.get(Calendar.SECOND) - Integer.valueOf(timeValue));
                            break;
                    }
                }
                startTimeLong = caledel.getTime().getTime();
                break;
            case "5":// 当前时间后
                Calendar cale = Calendar.getInstance();
                cale.setTimeInMillis(timestampInMillis);
                if (YunzhupaasKeyConsts.DATE.equals(yunzhupaasKey)) {
                    switch (timeTarget) {
                        case "1":// 年
                            cale.set(Calendar.YEAR, cale.get(Calendar.YEAR) + Integer.valueOf(timeValue));// 赋值年份
                            break;
                        case "2":// 月
                            cale.set(Calendar.MONTH, cale.get(Calendar.MONTH) + Integer.valueOf(timeValue));
                            break;
                        case "3":// 日
                            cale.set(Calendar.DAY_OF_MONTH,
                                    cale.get(Calendar.DAY_OF_MONTH) + Integer.valueOf(timeValue));
                            break;
                    }
                } else {
                    switch (timeTarget) {
                        case "1":// 时
                            cale.set(Calendar.HOUR_OF_DAY, cale.get(Calendar.HOUR_OF_DAY) + Integer.valueOf(timeValue));
                            break;
                        case "2":// 分
                            cale.set(Calendar.MINUTE, cale.get(Calendar.MINUTE) + Integer.valueOf(timeValue));
                            break;
                        case "3":// 秒
                            cale.set(Calendar.SECOND, cale.get(Calendar.SECOND) + Integer.valueOf(timeValue));
                            break;
                    }
                }
                startTimeLong = cale.getTime().getTime();
                break;
            default:
                break;
        }
        return startTimeLong;
    }

    /**
     * 字符串转数组
     *
     * @param value 值
     * @return
     */
    public static Object getDataConversion(Object value) {
        if (value instanceof Integer || value instanceof Long || value instanceof Float || value instanceof Double
                || value instanceof BigDecimal)
            return value;
        Object dataValue = getDataConversion(null, value, false, "/");
        return dataValue;
    }

    /**
     * 字符串转数组
     *
     * @param redis 转换对象
     * @param value 值
     * @return
     */
    public static Object getDataConversion(Map<String, Object> redis, Object value, boolean isMultiple,
            String separator) {
        Object dataValue = value;
        boolean iszhuanhuan = redis != null;
        try {
            List<List> list = JsonUtil.getJsonToList(String.valueOf(value), List.class);
            dataValue = list;
            if (iszhuanhuan) {
                // 一级分隔符
                StringJoiner joiner = new StringJoiner(",");
                for (List listChild : list) {
                    StringJoiner aa = new StringJoiner(separator);
                    for (Object object : listChild) {
                        String value1 = redis.get(String.valueOf(object)) != null
                                ? String.valueOf(redis.get(String.valueOf(object)))
                                : "";
                        if (StringUtil.isNotEmpty(value1)) {
                            aa.add(value1);
                        }
                    }
                    joiner.add(aa.toString());
                }
                dataValue = joiner.toString();
            }
        } catch (Exception e) {
            try {
                List<String> list = JsonUtil.getJsonToList(String.valueOf(value), String.class);
                dataValue = list;
                if (iszhuanhuan) {
                    if (isMultiple) {// 一级分隔符
                        separator = ",";
                    }
                    StringJoiner joiner = new StringJoiner(separator);
                    for (Object listChild : list) {
                        String value1 = redis.get(String.valueOf(listChild)) != null
                                ? String.valueOf(redis.get(String.valueOf(listChild)))
                                : "";
                        if (StringUtil.isNotEmpty(value1)) {
                            joiner.add(value1);
                        }
                    }
                    dataValue = joiner.toString();
                }
            } catch (Exception e1) {
                dataValue = String.valueOf(value);
                if (iszhuanhuan) {
                    dataValue = redis.get(String.valueOf(value)) != null
                            ? String.valueOf(redis.get(String.valueOf(value)))
                            : "";
                }
            }
        }
        return dataValue;
    }

    /**
     * 给列表数据添加id
     *
     * @param dataList
     * @param key
     */
    public static List<Map<String, Object>> addIdToList(List<Map<String, Object>> dataList, String key) {
        return dataList.stream().map(data -> {
            data.put(FlowFormConstant.ID, data.get(key));
            String flwoId = null;
            if (data.get(TableFeildsEnum.FLOWID.getField()) != null) {
                flwoId = String.valueOf(data.get(TableFeildsEnum.FLOWID.getField()));
            }
            if (data.get(TableFeildsEnum.FLOWID.getField().toUpperCase()) != null) {
                flwoId = String.valueOf(data.get(TableFeildsEnum.FLOWID.getField().toUpperCase()));
            }
            data.put(FlowFormConstant.FLOWID, flwoId);
            String flowTaskId = null;
            if (data.get(TableFeildsEnum.FLOWTASKID.getField()) != null) {
                flowTaskId = String.valueOf(data.get(TableFeildsEnum.FLOWTASKID.getField()));
            }
            if (data.get(TableFeildsEnum.FLOWTASKID.getField().toUpperCase()) != null) {
                flowTaskId = String.valueOf(data.get(TableFeildsEnum.FLOWTASKID.getField().toUpperCase()));
            }
            data.put(FlowFormConstant.FLOWTASKID, flowTaskId);

            return data;
        }).collect(Collectors.toList());
    }

    /**
     * 关联表单获取原字段数据（数据类型也要转换）
     *
     * @param dataMap
     * @param yunzhupaasKey
     * @param obj
     * @param vModel
     */
    public static void relationGetYunzhupaasId(Map<String, Object> dataMap, String yunzhupaasKey, Object obj,
            String vModel) {
        String vModelyunzhupaasId = vModel + "_yunzhupaasId";
        switch (yunzhupaasKey) {
            case YunzhupaasKeyConsts.CREATETIME:
            case YunzhupaasKeyConsts.MODIFYTIME:
            case YunzhupaasKeyConsts.DATE:
                Long dateTime = DateTimeFormatConstant.getDateObjToLong(dataMap.get(vModel));
                dataMap.put(vModelyunzhupaasId, dateTime != null ? dateTime : dataMap.get(vModel));
                break;
            case YunzhupaasKeyConsts.CHILD_TABLE:
                break;
            case YunzhupaasKeyConsts.SWITCH:
            case YunzhupaasKeyConsts.SLIDER:
            case YunzhupaasKeyConsts.RATE:
            case YunzhupaasKeyConsts.CALCULATE:
            case YunzhupaasKeyConsts.NUM_INPUT:
                dataMap.put(vModelyunzhupaasId,
                        ObjectUtil.isNotEmpty(obj) ? new BigDecimal(String.valueOf(obj)) : dataMap.get(vModel));
                break;
            default:
                dataMap.put(vModelyunzhupaasId, obj);
                break;
        }
        if (YunzhupaasKeyConsts.getArraysKey().contains(yunzhupaasKey) && obj != null) {
            String o = String.valueOf(obj);
            try {
                List<List> jsonToList = JsonUtil.getJsonToList(o, List.class);
                List<Object> res = new ArrayList<>();
                for (List listChild : jsonToList) {
                    List<Object> res2 = new ArrayList<>();
                    for (Object object : listChild) {
                        if (object != null && StringUtil.isNotEmpty(String.valueOf(object))) {
                            res2.add(object);
                        }
                    }
                    res.add(res2);
                }
                dataMap.put(vModelyunzhupaasId, res);
            } catch (Exception e) {
                try {
                    List<Object> jsonToList = JsonUtil.getJsonToList(o, Object.class);
                    dataMap.put(vModelyunzhupaasId, jsonToList);
                } catch (Exception e1) {
                }
            }
        }
    }
}
