package com.malk.utils;

import cn.hutool.core.util.ObjectUtil;
import com.malk.server.common.McException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

@Slf4j
public abstract class UtilMap {

    /************* 快速创建map ************/

    /**
     * 快速创建map [key, Objects]
     */
    public static Map<String, Object> map(String keys, Object... values) {
        String[] props = keys.split(", ");
        if (props.length != values.length) {
            McException.assertParamException_Null(keys);
        }
        Map<String, Object> map = new HashMap<>();
        Arrays.stream(values).forEach(UtilMc.consumerWithIndex((item, index) -> {
            map.put(props[index], item);
        }));
        return map;
    }

    /**
     * 快速创建map [key, Objects] todo, 添加枚举, 忽略空, 忽略0, 忽略""/null字符串 ...
     */
    public static Map<String, Object> mapNotNull(String keys, Object... values) {
        String[] props = keys.split(", ");
        if (props.length != values.length) {
            McException.assertParamException_Null(keys);
        }
        Map<String, Object> map = new HashMap<>();
        Arrays.stream(values).forEach(UtilMc.consumerWithIndex((item, index) -> {
            if (ObjectUtil.isNotNull(item) && UtilString.isNotBlankCompatNull(String.valueOf(item))) {
                map.put(props[index], item);
            }
        }));
        return map;
    }

    /**
     * 快速创建map [key, Strings]
     */
    public static Map<String, String> map(String keys, String values) {
        if (UtilString.isBlankCompatNull(keys) || UtilString.isBlankCompatNull(values)) {
            return UtilMap.empty();
        }
        String[] props = keys.split(", ");
        String[] contents = values.split(", ");
        if (props.length != contents.length) {
            McException.assertParamException_Null(keys);
        }
        Map<String, String> map = new HashMap<>();
        Arrays.stream(contents).forEach(UtilMc.consumerWithIndex((item, index) -> {
            map.put(props[index], String.valueOf(item));
        }));
        return map;
    }

    // todo 字段Equal, 添加首个参数判空

    /**
     * 快速创建map [保留skeys, 取值ckeys] todo: 新版本更新, 字段覆盖
     */
    public static Map<String, Object> map(String skeys, String ckeys, Map map) {
        String[] sprops = skeys.split(", ");
        String[] cprops = ckeys.split(", ");
        if (sprops.length != cprops.length) {
            McException.assertParamException_Null(skeys);
        }
        Map data = new HashMap();
        Arrays.stream(cprops).forEach(UtilMc.consumerWithIndex((item, index) -> {
            data.put(sprops[index], map.get(item));
        }));
        return data;
    }

    /**
     * 快速创建map [合并skeys, 取值ckeys]
     */
    public static void map(String skeys, String ckeys, Map sMap, Map cMap) {
        sMap.putAll(map(skeys, ckeys, cMap));
    }

    /// 创建空对象
    public static Map empty() {
        return new HashedMap();
    }

    /// 判定 & 创建空对象
    public static Map empty(Map data) {
        if (ObjectUtil.isNotNull(data)) {
            return data;
        }
        return new HashedMap();
    }

    /************* 赋值 ************/

    /**
     * 赋值 [为空对象null, 忽略]
     */
    public static Map putNotNull(Map data, String key, Object value) {
        if (ObjectUtil.isNull(data)) {
            data = new HashMap();
        }
        if (ObjectUtil.isNotNull(value)) {
            data.put(key, value);
        }
        return data;
    }

    /**
     * 赋值 [为空字符串, 忽略]
     */
    public static Map putNotEmpty(Map data, String key, String value) {
        if (ObjectUtil.isNull(data)) {
            data = new HashMap();
        }
        if (StringUtils.isNotBlank(value)) {
            data.put(key, value);
        }
        return data;
    }

    /**
     * 非空对象全量合并
     */
    public static Map putAll(Map data, Map value) {
        if (ObjectUtil.isNull(data)) {
            if (ObjectUtil.isNull(value)) {
                return empty();
            }
            return value;
        }
        if (ObjectUtil.isNotNull(value)) {
            data.putAll(value);
        }
        return data;
    }

    /**
     * 赋值 [值为0, 忽略]
     */
    public static Map putNotZero(Map data, String key, Object value) {
        float val = 0.f;
        try {
            val = Float.valueOf(String.valueOf(value));
        } catch (Exception e) {
            data.put(key, value);
        }
        if (val != 0.f) {
            data.put(key, value);
        }
        return data;
    }

    /**
     * 赋值 [原值为空赋值默认值]
     */
    public static Map put(Map data, String key, Object defaultValue) {
        if (ObjectUtil.isNull(data)) {
            data = empty(data);
        }
        Object value = data.get(key);
        if (ObjectUtil.isNull(value)) {
            value = defaultValue;
        }
        data.put(key, value);
        return data;
    }

    /**
     * 赋值 [赋值为空赋值默认值]
     */
    public static Map put(Map data, String key, Object value, Object defaultValue) {
        data = empty(data);
        if (ObjectUtil.isNull(value)) {
            value = defaultValue;
        }
        data.put(key, value);
        return data;
    }

    /************* 取值 ************/

    /**
     * 取值 [String.valueOf 避免空指针]
     */
    public static String getString(Map data, String key) {
        if (data.containsKey(key)) {
            // 不能判空字符串
            if (ObjectUtil.isNull(data.get(key))) {
                return "";
            }
            String value = String.valueOf(data.get(key));
            // 屏蔽空指针转换
            if (value.equals("null")) {
                return "";
            }
            return value;
        }
        return "";
    }

    /**
     * 取值 [转为 long]
     */
    public static long getLong(Map data, String key) {
        McException.assertParamException_Null(data, key);
        return Long.valueOf(getString(data, key)) + 0L;
    }

    /**
     * 取值 [转为 int]
     */
    public static int getInt(Map data, String key) {
        String txt = getString(data, key);
        if (StringUtils.isBlank(txt)) {
            return 0;
        }
        return Integer.valueOf(txt);
    }

    /**
     * 取值 [转为 float]
     */
    public static Float getFloat(Map data, String key) {
        String txt = getString(data, key);
        if (StringUtils.isBlank(txt)) {
            return 0f;
        }
        return Float.valueOf(txt);
    }

    public static Double getDouble(Map data, String key) {
        String txt = getString(data, key);
        if (StringUtils.isBlank(txt)) {
            return 0d;
        }
        return Double.valueOf(txt);
    }

    /**
     * 取值 [转为 bool]
     */
    public static Boolean getBoolean(Map data, String key) {
        return Boolean.valueOf(getString(data, key));
    }

    /**
     * 取值 [为空返回默认值]
     */
    public static Object get_default(Map data, String key, Object defaultValue) {
        Object value = data.get(key);
        if (ObjectUtil.isNull(value)) {
            return defaultValue;
        }
        return value;
    }

    /**
     * 取值 [为空返回默认字符串]
     */
    public static String getString_default(Map data, String key, String defaultValue) {
        String value = getString(data, key);
        if (StringUtils.isBlank(value)) {
            return defaultValue;
        }
        return value;
    }

    /**
     * 取值 [未定key, 取第一个命中]
     */
    public static Object get_first(Map data, String... keys) {
        Object value = null;
        for (String key : keys) {
            if (data.containsKey(key)) {
                value = data.get(key);
                break;
            }
        }
        return value;
    }

    /**
     * 取值 String [未定key, 取第一个命中]
     */
    public static String getString_first(Map data, String... keys) {
        String value = "";
        for (String key : keys) {
            // 字段 + 值判定
            if (data.containsKey(key) && StringUtils.isNotBlank(getString(data, key))) {
                value = UtilString.stringFormatNull(data, key);
                break;
            }
        }
        return value;
    }

    /**
     * 取值 List
     */
    public static List getList(Map data, String key) {
        if (data.containsKey(key)) {
            Object val = data.get(key);
            if (val instanceof List) {
                return (List) val;
            }
        }
        return new ArrayList();
    }

    /**
     * 取值 Map
     */
    public static Map getMap(Map data, String key) {
        if (data.containsKey(key)) {
            Object val = data.get(key);
            if (val instanceof Map) {
                return (Map) val;
            }
            return (Map) data.get(key);
        }
        return new HashedMap();
    }

    /************* 判定 ************/

    /**
     * 是否空字符串
     */
    public static boolean isBlankString(Map data, String key) {
        return StringUtils.isBlank(getString(data, key));
    }

    /**
     * 是否不为空字符串
     */
    public static boolean isNotBlankString(Map data, String key) {
        return StringUtils.isNotBlank(getString(data, key));
    }
}
