package com.awspaas.user.apps.donenow_sys;


import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class ObjectEqualsOptimized {
    // 常见日期格式列表（按优先级排序）
    private static final List<DateTimeFormatter> FORMATTERS;

    static {
        List<DateTimeFormatter> formatters = new ArrayList<>();
        // ISO 标准格式
        formatters.add(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        formatters.add(DateTimeFormatter.ISO_LOCAL_DATE);
        formatters.add(DateTimeFormatter.ISO_LOCAL_TIME);
        // 带时区的格式
        formatters.add(DateTimeFormatter.ISO_ZONED_DATE_TIME);
        // 常见格式
        formatters.add(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        formatters.add(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        formatters.add(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"));
        formatters.add(DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss"));
        formatters.add(DateTimeFormatter.ofPattern("dd-MMM-yyyy HH:mm:ss"));
        formatters.add(DateTimeFormatter.ofPattern("MMM dd, yyyy HH:mm:ss"));
        formatters.add(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒"));
        formatters.add(DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu"));

        // 将列表设置为不可变
        FORMATTERS = Collections.unmodifiableList(formatters);
    }


    /**
     * 判断两个对象是否相等
     * @param var1
     * @param var2
     * @return
     */
    public static boolean ObjectEquals(Object var1, Object var2) {
        // 处理两个对象都为 null 的情况
        if (var1 == null && var2 == null) {
            return true;
        }
        // 处理一个对象为 null，另一个对象为空字符串的情况
        if ((var1 == null && var2 != null && Objects.toString(var2, "").isEmpty()) ||
                (var1 != null && Objects.toString(var1, "").isEmpty() && var2 == null)) {
            return true;
        }
        // 处理两个对象都为 Date 类型的情况
        if (var1 instanceof Date && var2 instanceof Date) {
            return formatDate((Date) var1, "yyyy-MM-dd HH:mm:ss").equals(formatDate((Date) var2, "yyyy-MM-dd HH:mm:ss"));
        }
        // 处理数值类型比较
        if (var1 instanceof Number && var2 instanceof Number) {
            return compareNumbers((Number) var1, (Number) var2);
        }
        // 处理日期比较
        if (var1 != null && var2 != null) {
            LocalDateTime ldt1 = tryParseLocalDateTime(var1);
            LocalDateTime ldt2 = tryParseLocalDateTime(var2);
            if (ldt1 != null && ldt2 != null) {
                return compareLocalDateTimes(ldt1, ldt2);
            }

            Date date1 = parseDate(var1.toString());
            Date date2 = parseDate(var2.toString());
            if (date1 != null && date2 != null) {
                if (date1.equals(date2))
                    return true;
                else if (date1.toInstant().equals(date2.toInstant()))
                    return true;
            }
        }
        // 处理其他情况
        return Objects.toString(var1, "").equals(Objects.toString(var2, ""));
    }

    /**
     * 比较两个数值对象是否相等
     * @param num1
     * @param num2
     * @return
     */
    private static boolean compareNumbers(Number num1, Number num2) {
        return Double.compare(num1.doubleValue(), num2.doubleValue()) == 0;
    }

    /**
     * 尝试将对象解析为 LocalDateTime
     * @param obj 待解析的对象
     * @return 解析成功的 LocalDateTime 对象，或 null（如果解析失败）
     */
    private static LocalDateTime tryParseLocalDateTime(Object obj) {
        if (obj instanceof LocalDateTime) {
            return (LocalDateTime) obj;
        }
        if (obj instanceof Date) {
            return ((Date) obj).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        }
        if (obj instanceof String) {
            return parseLocalDateTime((String) obj);
        }
        return null;
    }

    /**
     * 比较两个 LocalDateTime 对象是否相等
     * @param ldt1
     * @param ldt2
     * @return
     */
    private static boolean compareLocalDateTimes(LocalDateTime ldt1, LocalDateTime ldt2) {
        if (ldt1.equals(ldt2)) {
            return true;
        }
        if (ldt1.toLocalDate().equals(ldt2.toLocalDate()) && ldt1.toLocalTime().equals(ldt2.toLocalTime())) {
            return true;
        }
        if (ldt1.toLocalDate().equals(ldt2.toLocalDate()) &&
                ldt1.toLocalTime().equals(LocalTime.of(0, 0, 0)) &&
                ldt2.toLocalTime().equals(LocalTime.of(0, 0, 0))) {
            return true;
        }
        return false;
    }

    /**
     * 尝试将字符串解析为 LocalDateTime 对象，支持多种格式。
     * @param dateStr 待解析的日期字符串
     * @return 解析成功的 LocalDateTime 对象，或 null（如果所有格式均失败）
     */
    public static LocalDateTime parseLocalDateTime(String dateStr) {
        for (DateTimeFormatter formatter : FORMATTERS) {
            try {
                return LocalDateTime.parse(dateStr, formatter);
            } catch (java.time.format.DateTimeParseException e) {
                // 忽略异常，尝试下一个格式
            }
        }
        return null; // 所有格式均无法解析
    }

    /**
     * 尝试将字符串解析为 Date 对象（兼容旧版 Date 类）。
     * @param dateStr 待解析的日期字符串
     * @return 解析成功的 Date 对象，或 null（如果所有格式均失败）
     */
    public static Date parseDate(String dateStr) {
        LocalDateTime localDateTime = parseLocalDateTime(dateStr);
        if (localDateTime != null) {
            return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
        }
        return null;
    }

    /**
     * 格式化日期
     * @param date 日期对象
     * @param pattern 日期格式
     * @return 格式化后的日期字符串
     */
    public static String formatDate(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            return sdf.format(date);
        } catch (IllegalArgumentException e) {
            return null;
        }
    }
}