
package com.zsElectric.boot.common.util;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.format.annotation.DateTimeFormat;

import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

/**
 * 日期工具类
 *
 * @author haoxr
 * @since 2.4.2
 */
public class DateUtils {

    /**
     * 区间日期格式化为数据库日期格式
     * <p>
     * eg：2021-01-01 → 2021-01-01 00:00:00
     *
     * @param obj                要处理的对象
     * @param startTimeFieldName 起始时间字段名
     * @param endTimeFieldName   结束时间字段名
     */
    public static void toDatabaseFormat(Object obj, String startTimeFieldName, String endTimeFieldName) {
        Field startTimeField = ReflectUtil.getField(obj.getClass(), startTimeFieldName);
        Field endTimeField = ReflectUtil.getField(obj.getClass(), endTimeFieldName);

        if (startTimeField != null) {
            processDateTimeField(obj, startTimeField, startTimeFieldName, "yyyy-MM-dd 00:00:00");
        }

        if (endTimeField != null) {
            processDateTimeField(obj, endTimeField, endTimeFieldName, "yyyy-MM-dd 23:59:59");
        }
    }

    /**
     * 处理日期字段
     *
     * @param obj           要处理的对象
     * @param field         字段
     * @param fieldName     字段名
     * @param targetPattern 目标数据库日期格式
     */
    private static void processDateTimeField(Object obj, Field field, String fieldName, String targetPattern) {
        Object fieldValue = ReflectUtil.getFieldValue(obj, fieldName);
        if (fieldValue != null) {
            // 得到原始的日期格式
            String pattern = field.isAnnotationPresent(DateTimeFormat.class) ? field.getAnnotation(DateTimeFormat.class).pattern() : "yyyy-MM-dd";
            // 转换为日期对象
            DateTime dateTime = DateUtil.parse(StrUtil.toString(fieldValue), pattern);
            // 转换为目标数据库日期格式
            ReflectUtil.setFieldValue(obj, fieldName, dateTime.toString(targetPattern));
        }
    }

    /**
     * 计算两个时间之间的持续时间（秒）
     * 支持多种常见的日期时间格式
     *
     * @param startTime 开始时间字符串
     * @param endTime   结束时间字符串
     * @return 持续时间（秒），如果任一参数为空则返回0
     */
    public static Integer getDuration(String startTime, String endTime) {
        if (StrUtil.isBlank(startTime) || StrUtil.isBlank(endTime)) {
            return 0;
        }

        try {
            // 定义支持的日期时间格式
            DateTimeFormatter[] formatters = {
                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
                    DateTimeFormatter.ofPattern("yyyyMMddHHmmss"),
                    DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"),
                    DateTimeFormatter.ISO_LOCAL_DATE_TIME
            };

            LocalDateTime start = parseDateTime(startTime, formatters);
            LocalDateTime end = parseDateTime(endTime, formatters);

            if (start == null || end == null) {
                return 0;
            }

            // 计算秒数差
            long seconds = ChronoUnit.SECONDS.between(start, end);
            return (int) seconds;
        } catch (Exception e) {
            // 解析失败，返回0
            return 0;
        }
    }

    /**
     * 尝试使用多种格式解析时间字符串
     *
     * @param dateTimeStr 时间字符串
     * @param formatters  格式化器数组
     * @return 解析后的LocalDateTime对象，解析失败返回null
     */
    private static LocalDateTime parseDateTime(String dateTimeStr, DateTimeFormatter[] formatters) {
        for (DateTimeFormatter formatter : formatters) {
            try {
                return LocalDateTime.parse(dateTimeStr, formatter);
            } catch (Exception ignored) {
                // 尝试下一个格式
            }
        }
        return null;
    }
}
