package com.aps.common.util;

import com.aps.service.plan.SceneService;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@UtilityClass
public class ParamValidator {

    // ========== 基本参数验证 ==========

    public static void requireNonNull(Object value, String fieldName) {
        if (value == null) {
            throw new IllegalArgumentException(fieldName + "不能为空");
        }
    }

    public static void requireNotBlank(String value, String fieldName) {
        if (value == null || value.trim().isEmpty()) {
            throw new IllegalArgumentException(fieldName + "不能为空");
        }
    }

    public static void requireNotEmpty(List<?> list, String fieldName) {
        if (list == null || list.isEmpty()) {
            throw new IllegalArgumentException(fieldName + "不能为空");
        }
    }

    public static void requirePositive(Number number, String fieldName) {
        if (number == null) {
            throw new IllegalArgumentException(fieldName + "不能为空");
        }
        if (number.doubleValue() <= 0) {
            throw new IllegalArgumentException(fieldName + "必须大于0");
        }
    }

    public static void requireNonNegative(Number number, String fieldName) {
        if (number == null) {
            throw new IllegalArgumentException(fieldName + "不能为空");
        }
        if (number.doubleValue() < 0) {
            throw new IllegalArgumentException(fieldName + "不能为负数");
        }
    }

    // ========== Map参数提取 ==========

    public static String getString(Map<String, Object> params, String key, String fieldName) {
        Object value = params.get(key);
        requireNonNull(value, fieldName);

        if (value instanceof String) {
            String strValue = ((String) value).trim();
            if (strValue.isEmpty()) {
                throw new IllegalArgumentException(fieldName + "不能为空字符串");
            }
            return strValue;
        } else if (value instanceof Integer || value instanceof Long) {
            return String.valueOf(value);
        }

        throw new IllegalArgumentException(fieldName + "必须是字符串、整数或长整数类型");
    }

    public static Integer getInteger(Map<String, Object> params, String key, String fieldName) {
        Object value = params.get(key);
        requireNonNull(value, fieldName);

        try {
            if (value instanceof Number) {
                return ((Number) value).intValue();
            } else if (value instanceof String) {
                String str = ((String) value).trim();
                if (str.isEmpty()) {
                    throw new IllegalArgumentException(fieldName + "不能为空字符串");
                }
                return Integer.parseInt(str);
            } else {
                throw new IllegalArgumentException(fieldName + "格式不正确，必须是数字或字符串");
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(fieldName + "格式不正确: " + value);
        }
    }


    public static Double getDouble(Map<String, Object> params, String key, String fieldName) {
        Object value = params.get(key);
        requireNonNull(value, fieldName);

        try {
            if (value instanceof Number) {
                return ((Number) value).doubleValue();
            } else if (value instanceof String) {
                String str = ((String) value).trim();
                if (str.isEmpty()) {
                    throw new IllegalArgumentException(fieldName + "不能为空字符串");
                }
                return Double.parseDouble(str);
            } else {
                throw new IllegalArgumentException(fieldName + "格式不正确，必须是数字或字符串");
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(fieldName + "格式不正确: " + value);
        }
    }
    public static Long getLong(Map<String, Object> params, String key, String fieldName) {
        Object value = params.get(key);
        requireNonNull(value, fieldName);

        try {
            if (value instanceof Number) {
                return ((Number) value).longValue();
            } else if (value instanceof String) {
                String str = ((String) value).trim();
                if (str.isEmpty()) {
                    throw new IllegalArgumentException(fieldName + "不能为空字符串");
                }
                return Long.parseLong(str);
            } else {
                throw new IllegalArgumentException(fieldName + "格式不正确，必须是数字或字符串");
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(fieldName + "格式不正确: " + value);
        }
    }

    public static Boolean getBoolean(Map<String, Object> params, String key, String fieldName) {
        Object value = params.get(key);
        requireNonNull(value, fieldName);

        if (value instanceof Boolean) {
            return (Boolean) value;
        } else if (value instanceof String) {
            String str = ((String) value).trim().toLowerCase();
            if ("true".equals(str) || "1".equals(str) || "yes".equals(str)) {
                return true;
            } else if ("false".equals(str) || "0".equals(str) || "no".equals(str)) {
                return false;
            } else {
                throw new IllegalArgumentException(fieldName + "格式不正确: " + value);
            }
        } else if (value instanceof Number) {
            int intValue = ((Number) value).intValue();
            if (intValue == 1) return true;
            if (intValue == 0) return false;
            throw new IllegalArgumentException(fieldName + "必须是0或1");
        } else {
            throw new IllegalArgumentException(fieldName + "格式不正确");
        }
    }

    public static List<?> getList(Map<String, Object> params, String key, String fieldName) {
        Object value = params.get(key);
        requireNonNull(value, fieldName);

        if (value instanceof List) {
            return (List<?>) value;
        }

        throw new IllegalArgumentException(fieldName + "必须是列表类型");
    }

    public static LocalDateTime getDateTime(Map<String, Object> params, String key, String fieldName) {
        String dateTimeStr = getString(params, key, fieldName);
        return parseDateTime(dateTimeStr, fieldName);
    }

    // ========== 日期时间解析 ==========

    public static LocalDateTime parseDateTime(String dateTimeStr, String fieldName) {
        try {
            if (dateTimeStr == null || dateTimeStr.trim().isEmpty()) {
                throw new IllegalArgumentException(fieldName + "不能为空");
            }

            String trimmed = dateTimeStr.trim();

            // 支持ISO格式（带时区）
            if (trimmed.endsWith("Z") || trimmed.contains("+") || trimmed.contains("-")) {
                try {
                    OffsetDateTime offsetDateTime = OffsetDateTime.parse(trimmed);
                    return offsetDateTime.toLocalDateTime();
                } catch (DateTimeParseException e) {
                    // 继续尝试其他格式
                }
            }

            // 尝试标准ISO格式
            try {
                return LocalDateTime.parse(trimmed);
            } catch (DateTimeParseException e) {
                // 继续尝试其他格式
            }

            // 尝试常用格式
            DateTimeFormatter[] formatters = {
                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"),
                    DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"),
                    DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")
            };

            for (DateTimeFormatter formatter : formatters) {
                try {
                    return LocalDateTime.parse(trimmed, formatter);
                } catch (DateTimeParseException e) {
                    // 继续尝试下一个格式
                }
            }

            throw new IllegalArgumentException(fieldName + "格式不正确: " + trimmed);

        } catch (DateTimeParseException e) {
            throw new IllegalArgumentException(fieldName + "格式不正确: " + dateTimeStr);
        }
    }

    // ========== 批量参数验证 ==========

    public static void validateSceneExists(SceneService sceneService, String sceneId) {
        if (sceneId == null || sceneId.trim().isEmpty()) {
            throw new IllegalArgumentException("场景ID不能为空");
        }

        if (sceneService == null) {
            throw new IllegalArgumentException("sceneService不能为空");
        }

        if (sceneService.loadChromosomeFromFile(sceneId) == null) {
            throw new RuntimeException("未找到对应的场景文件: " + sceneId);
        }
    }

    public static Double[] convertToDoubleArray(List<?> sourceList, String fieldName) {
        requireNotEmpty(sourceList, fieldName);

        return sourceList.stream()
                .map(item -> {
                    if (item instanceof Number) {
                        return ((Number) item).doubleValue();
                    } else if (item instanceof String) {
                        try {
                            return Double.parseDouble(((String) item).trim());
                        } catch (NumberFormatException e) {
                            throw new IllegalArgumentException(fieldName + "包含无效的数字: " + item);
                        }
                    } else {
                        throw new IllegalArgumentException(fieldName + "包含不支持的数据类型: " +
                                (item != null ? item.getClass().getSimpleName() : "null"));
                    }
                })
                .toArray(Double[]::new);
    }

    public static List<Integer> convertToIntArray(List<?> sourceList, String fieldName) {
        requireNotEmpty(sourceList, fieldName);

        return sourceList.stream()
                .map(item -> {
                    if (item instanceof Number) {
                        return ((Integer) item);
                    } else if (item instanceof String) {
                        try {
                            return Integer.parseInt(((String) item).trim());
                        } catch (NumberFormatException e) {
                            throw new IllegalArgumentException(fieldName + "包含无效的数字: " + item);
                        }
                    } else {
                        throw new IllegalArgumentException(fieldName + "包含不支持的数据类型: " +
                                (item != null ? item.getClass().getSimpleName() : "null"));
                    }
                })
                .collect(Collectors.toList());
    }
}