package com.ycwl.basic.integration.common.manager;

import com.ycwl.basic.utils.JacksonUtil;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 通用配置管理器基类
 * 提供配置查找、类型转换等通用功能
 * 
 * @param <T> 配置DTO类型
 */
public abstract class ConfigManager<T> {
    
    protected List<T> configs;
    
    public ConfigManager(List<T> configs) {
        this.configs = configs != null ? configs : new ArrayList<>();
    }
    
    /**
     * 获取配置项的键
     * 子类需要实现此方法来提取配置键
     */
    protected abstract String getConfigKey(T config);
    
    /**
     * 获取配置项的值
     * 子类需要实现此方法来提取配置值
     */
    protected abstract Object getConfigValue(T config);
    
    /**
     * 根据键查找配置项
     */
    protected T findConfigByKey(String key) {
        if (key == null || configs == null) {
            return null;
        }
        
        return configs.stream()
                .filter(config -> key.equals(getConfigKey(config)))
                .findFirst()
                .orElse(null);
    }
    
    /**
     * 获取字符串配置值
     */
    public String getString(String key) {
        T config = findConfigByKey(key);
        if (config == null) {
            return null;
        }
        Object value = getConfigValue(config);
        return value != null ? value.toString() : null;
    }
    
    /**
     * 获取字符串配置值，如果不存在则返回默认值
     */
    public String getString(String key, String defaultValue) {
        String value = getString(key);
        return value != null ? value : defaultValue;
    }
    
    /**
     * 获取整型配置值
     */
    public Integer getInteger(String key) {
        T config = findConfigByKey(key);
        if (config == null) {
            return null;
        }
        Object value = getConfigValue(config);
        if (value == null) return null;
        if (value instanceof Integer) return (Integer) value;
        if (value instanceof Number) return ((Number) value).intValue();
        if (value instanceof String) {
            try {
                return Integer.parseInt((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
    
    /**
     * 获取整型配置值，如果不存在则返回默认值
     */
    public Integer getInteger(String key, Integer defaultValue) {
        Integer value = getInteger(key);
        return value != null ? value : defaultValue;
    }
    
    /**
     * 获取长整型配置值
     */
    public Long getLong(String key) {
        T config = findConfigByKey(key);
        if (config == null) {
            return null;
        }
        Object value = getConfigValue(config);
        if (value == null) return null;
        if (value instanceof Long) return (Long) value;
        if (value instanceof Number) return ((Number) value).longValue();
        if (value instanceof String) {
            try {
                return Long.parseLong((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
    
    /**
     * 获取长整型配置值，如果不存在则返回默认值
     */
    public Long getLong(String key, Long defaultValue) {
        Long value = getLong(key);
        return value != null ? value : defaultValue;
    }
    
    /**
     * 获取布尔型配置值
     */
    public Boolean getBoolean(String key) {
        T config = findConfigByKey(key);
        if (config == null) {
            return null;
        }
        Object value = getConfigValue(config);
        if (value == null) return null;
        if (value instanceof Boolean) return (Boolean) value;
        if (value instanceof String) {
            String str = ((String) value).toLowerCase().trim();
            return "true".equals(str) || "1".equals(str) || "yes".equals(str);
        }
        if (value instanceof Number) {
            return ((Number) value).intValue() != 0;
        }
        return null;
    }
    
    /**
     * 获取布尔型配置值，如果不存在则返回默认值
     */
    public Boolean getBoolean(String key, Boolean defaultValue) {
        Boolean value = getBoolean(key);
        return value != null ? value : defaultValue;
    }
    
    /**
     * 获取浮点型配置值
     */
    public Float getFloat(String key) {
        T config = findConfigByKey(key);
        if (config == null) {
            return null;
        }
        Object value = getConfigValue(config);
        if (value == null) return null;
        if (value instanceof Float) return (Float) value;
        if (value instanceof Number) return ((Number) value).floatValue();
        if (value instanceof String) {
            try {
                return Float.parseFloat((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
    
    /**
     * 获取浮点型配置值，如果不存在则返回默认值
     */
    public Float getFloat(String key, Float defaultValue) {
        Float value = getFloat(key);
        return value != null ? value : defaultValue;
    }
    
    /**
     * 获取BigDecimal配置值
     */
    public BigDecimal getBigDecimal(String key) {
        T config = findConfigByKey(key);
        if (config == null) {
            return null;
        }
        Object value = getConfigValue(config);
        if (value == null) return null;
        if (value instanceof BigDecimal) return (BigDecimal) value;
        if (value instanceof Number) return new BigDecimal(value.toString());
        if (value instanceof String) {
            try {
                return new BigDecimal((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
    
    /**
     * 获取BigDecimal配置值，如果不存在则返回默认值
     */
    public BigDecimal getBigDecimal(String key, BigDecimal defaultValue) {
        BigDecimal value = getBigDecimal(key);
        return value != null ? value : defaultValue;
    }
    
    /**
     * 获取枚举配置值
     */
    public <E extends Enum<E>> E getEnum(String key, Class<E> enumClass) {
        T config = findConfigByKey(key);
        if (config == null) {
            return null;
        }
        Object value = getConfigValue(config);
        return parseEnum(value, enumClass);
    }
    
    /**
     * 解析枚举值
     */
    private <E extends Enum<E>> E parseEnum(Object value, Class<E> enumClass) {
        if (value == null) return null;
        try {
            if (value instanceof String) {
                return Enum.valueOf(enumClass, (String) value);
            }
            return Enum.valueOf(enumClass, value.toString());
        } catch (IllegalArgumentException e) {
            return null;
        }
    }
    
    /**
     * 获取枚举配置值，如果不存在则返回默认值
     */
    public <E extends Enum<E>> E getEnum(String key, Class<E> enumClass, E defaultValue) {
        E value = getEnum(key, enumClass);
        return value != null ? value : defaultValue;
    }
    
    /**
     * 检查指定键的配置是否存在
     */
    public boolean hasConfig(String key) {
        return findConfigByKey(key) != null;
    }
    
    /**
     * 获取所有配置项的数量
     */
    public int size() {
        return configs.size();
    }
    
    /**
     * 获取所有配置项
     */
    public List<T> getAllConfigs() {
        return new ArrayList<>(configs);
    }
    
    /**
     * 获取原始对象配置值
     */
    public Object getObject(String key) {
        T config = findConfigByKey(key);
        if (config == null) {
            return null;
        }
        return getConfigValue(config);
    }
    
    /**
     * 获取并转换为指定类型的对象
     * 支持JSON字符串自动反序列化
     */
    @SuppressWarnings("unchecked")
    public <R> R getObject(String key, Class<R> clazz) {
        T config = findConfigByKey(key);
        if (config == null) {
            return null;
        }
        Object value = getConfigValue(config);
        if (value == null) return null;
        
        // 如果类型匹配，直接返回
        if (clazz.isInstance(value)) {
            return (R) value;
        }
        
        // 如果是String类型的JSON，尝试反序列化
        if (value instanceof String && !clazz.equals(String.class)) {
            try {
                return JacksonUtil.parseObject((String) value, clazz);
            } catch (Exception e) {
                return null;
            }
        }
        
        // 如果目标是String，直接转换
        if (clazz.equals(String.class)) {
            return (R) value.toString();
        }
        
        // 其他情况尝试JSON转换
        try {
            String json = JacksonUtil.toJSONString(value);
            return JacksonUtil.parseObject(json, clazz);
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 获取Map类型的配置值
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> getMap(String key) {
        T config = findConfigByKey(key);
        if (config == null) {
            return null;
        }
        Object value = getConfigValue(config);
        if (value == null) return null;
        
        if (value instanceof Map) {
            return (Map<String, Object>) value;
        }
        
        if (value instanceof String) {
            try {
                return JacksonUtil.parseObject((String) value, Map.class);
            } catch (Exception e) {
                return null;
            }
        }
        
        return null;
    }
    
    /**
     * 获取List类型的配置值
     */
    @SuppressWarnings("unchecked")
    public List<Object> getList(String key) {
        T config = findConfigByKey(key);
        if (config == null) {
            return null;
        }
        Object value = getConfigValue(config);
        if (value == null) return null;
        
        if (value instanceof List) {
            return (List<Object>) value;
        }
        
        if (value instanceof String) {
            try {
                return JacksonUtil.parseObject((String) value, List.class);
            } catch (Exception e) {
                return null;
            }
        }
        
        return null;
    }
    
    /**
     * 获取指定元素类型的List配置值
     */
    public <R> List<R> getList(String key, Class<R> elementClass) {
        T config = findConfigByKey(key);
        if (config == null) {
            return null;
        }
        Object value = getConfigValue(config);
        if (value == null) return null;
        
        if (value instanceof String) {
            try {
                return JacksonUtil.parseArray((String) value, elementClass);
            } catch (Exception e) {
                return null;
            }
        }
        
        try {
            String json = JacksonUtil.toJSONString(value);
            return JacksonUtil.parseArray(json, elementClass);
        } catch (Exception e) {
            return null;
        }
    }
}