package cn.sikey.mcdisk.util;

import cn.sikey.framework.common.exception.ServiceException;
import lombok.experimental.UtilityClass;
import org.apache.http.HttpStatus;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;

/**
 * @Author: qin
 * @Date: 2025/3/31
 * @Description: 日期
 */
@UtilityClass
public class DateToolUtil {

    public static final int DAY_SECOND = 24 * 60 * 60;

    /**
     * 剩余天数计算
     *
     * @param now            now
     * @param expireDateTime 过期日期时间
     * @return 剩余天数
     */
    public static long calculateRemainingDays(LocalDateTime expireDateTime, LocalDateTime now) {
        if (expireDateTime == null) {
            return 0;
        }

        LocalDateTime expireStart = expireDateTime.truncatedTo(ChronoUnit.DAYS);
        LocalDateTime nowStart = now.truncatedTo(ChronoUnit.DAYS);

        long days = ChronoUnit.DAYS.between(nowStart, expireStart);

        return Math.max(days, 0);
    }

    /**
     * 剩余秒数计算
     *
     * @param now            now
     * @param expireDateTime 过期日期时间
     * @return 剩余秒
     */
    public static long calculateRemainingSeconds(LocalDateTime expireDateTime, LocalDateTime now) {
        if (expireDateTime == null) {
            return 0;
        }

        long seconds = ChronoUnit.SECONDS.between(now, expireDateTime);

        return Math.max(seconds, 0);
    }


    /**
     * 几年后时间
     *
     * @param now  当前时间
     * @param year 年
     * @return
     */
    public static Instant fewYearsLater(Instant now, long year) {
        ZonedDateTime zonedDateTime = now.atZone(ZoneId.systemDefault());
        return zonedDateTime.plusYears(year).toInstant();
    }

    /**
     * 计算几天后的未来日期
     *
     * @param remainingSecond 秒
     * @param localDateTime   当前日期
     * @return
     */
    public static LocalDateTime calculateFutureDate(Long remainingSecond, LocalDateTime localDateTime) {
        if (remainingSecond == null || remainingSecond < 0 || localDateTime == null) {
            throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "参数总免费天数，当前日期有误");
        }

        return localDateTime.plusSeconds(remainingSecond);
    }

    /**
     * 计算最终到期时间
     *
     * @param freeExpireTime  普通用户过期时间
     * @param finalExpireTime 最终过期时间
     * @param now             当前时间
     * @param addSeconds      秒
     * @return
     */
    public static LocalDateTime calculateFinalExpireTime(LocalDateTime freeExpireTime,
                                                         LocalDateTime finalExpireTime,
                                                         LocalDateTime now, Long addSeconds) {
        // 首次购买VIP（通过时间戳相等性判断）
        if (freeExpireTime.isEqual(finalExpireTime)) {
            // 处理普通用户剩余权益
            if (freeExpireTime.isAfter(now)) {
                long remainingSecond = ChronoUnit.SECONDS.between(now, freeExpireTime);
                return now.plusSeconds(addSeconds).plusSeconds(remainingSecond);
            }
            // 统一处理过期逻辑（包含当天过期）
            return now.plusSeconds(addSeconds);
        }

        // 非首次购买VIP（直接续期逻辑）
        return finalExpireTime.isBefore(now)
                ? now.plusSeconds(addSeconds)                // 已过期：从当前时间续期
                : finalExpireTime.plusSeconds(addSeconds);    // 未过期：延续原有效期
    }

}
