package org.jeecg.modules.quartz.job;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.rabbitmq.DelayedMessageService;
import org.jeecg.modules.system.app.entity.AppOrder;
import org.jeecg.modules.system.app.entity.AppOrderProInfo;
import org.jeecg.modules.system.app.mapper.AppGmtInfoMapper;
import org.jeecg.modules.system.app.service.IAppOrderProInfoService;
import org.jeecg.modules.system.app.service.IAppOrderService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author wzq
 * @date 2025/9/8 15:18
 * @description 统计即将今日过期的子订单，发送延迟队列，在过期时修改订单过期状态，排除过期自动退款（无固定场）的订单
 */
@Slf4j
@AllArgsConstructor
@Component
public class TodayExpireOrderJobService {

    @Resource
    private IAppOrderProInfoService appOrderProInfoService;
    @Resource
    private DelayedMessageService delayedMessageService;

    /**
     * @Description 统计24小时内即将过期的订单，并发送过期订单延迟消息
     */
    @Scheduled(cron = "0 0 4 * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void execute() {
        log.info("开始执行统计24小时内即将过期的订单，并发送过期订单延迟消息定时任务");
        try {
            // 查询24小时内即将过期的子订单
            List<AppOrderProInfo> orderProInfoList = appOrderProInfoService.list(Wrappers.lambdaQuery(AppOrderProInfo.class).eq(AppOrderProInfo::getOrderStatus, 1));
            for (AppOrderProInfo orderProInfo : orderProInfoList) {
                String expireTime = orderProInfo.getExpireTime();
                //判断字符串是yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss 或 yyyy-MM-dd HH:mm
                Date date = adjustDate(expireTime);
                long differenceIfWithin24Hours = getDifferenceIfWithin24Hours(date);
                if (differenceIfWithin24Hours > 0) {
                    // 发送延迟消息
                    log.info("即将过期的子订单：{}", orderProInfo);
                    delayedMessageService.sendOrderExpireMessage(orderProInfo.getId(), (int) differenceIfWithin24Hours);
                }
            }
        } catch (Exception e) {
            log.error("统计24小时内即将过期的订单，并发送过期订单延迟消息异常", e);
        }
    }

    /**
     * 判断传入时间是否在当前时间之后的24小时内
     * @param targetDate 传入的时间
     * @return 相差毫秒数（若在24小时内）或 0
     */
    public static long getDifferenceIfWithin24Hours(Date targetDate) {
        if (targetDate == null) {
            return 0L;
        }

        Date currentDate = new Date(); // 当前时间
        long currentTimeMillis = currentDate.getTime();
        long targetTimeMillis = targetDate.getTime();

        // 如果传入时间在当前时间之后
        if (targetTimeMillis > currentTimeMillis) {
            long difference = targetTimeMillis - currentTimeMillis;
            long twentyFourHoursInMillis = 24 * 60 * 60 * 1000L; // 24小时的毫秒数

            // 判断是否在24小时以内
            if (difference <= twentyFourHoursInMillis) {
                return difference;
            }
        }

        return 0L;
    }

    // 正则表达式与格式化器
    private static final String DATE_REGEX = "^\\d{4}-\\d{2}-\\d{2}$";
    private static final String DATE_HOUR_MINUTE_REGEX = "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$";
    private static final String DATE_HOUR_MINUTE_SECOND_REGEX = "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$";

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter DATE_HOUR_MINUTE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    private static final DateTimeFormatter DATE_HOUR_MINUTE_SECOND_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    // 预编译正则表达式
    private static final Pattern DATE_PATTERN = Pattern.compile(DATE_REGEX);
    private static final Pattern DATE_HOUR_MINUTE_PATTERN = Pattern.compile(DATE_HOUR_MINUTE_REGEX);
    private static final Pattern DATE_HOUR_MINUTE_SECOND_PATTERN = Pattern.compile(DATE_HOUR_MINUTE_SECOND_REGEX);

    public static Date adjustDate(String input) {
        if (input == null || input.isEmpty()) {
            throw new IllegalArgumentException("输入字符串不能为空");
        }

        try {
            if (DATE_PATTERN.matcher(input).matches()) {
                LocalDate localDate = LocalDate.parse(input, DATE_FORMATTER);
                LocalDateTime adjustedDateTime = localDate.atTime(23, 59, 59);
                return toDate(adjustedDateTime);
            } else if (DATE_HOUR_MINUTE_PATTERN.matcher(input).matches()) {
                LocalDateTime localDateTime = LocalDateTime.parse(input, DATE_HOUR_MINUTE_FORMATTER);
                LocalDateTime adjustedDateTime = localDateTime.plusSeconds(1);
                return toDate(adjustedDateTime);
            } else if (DATE_HOUR_MINUTE_SECOND_PATTERN.matcher(input).matches()) {
                LocalDateTime localDateTime = LocalDateTime.parse(input, DATE_HOUR_MINUTE_SECOND_FORMATTER);
                return toDate(localDateTime);
            } else {
                throw new DateTimeParseException("不支持的日期格式", input, 0);
            }
        } catch (DateTimeParseException e) {
            throw new IllegalArgumentException("日期格式无效: " + e.getMessage());
        }
    }

    private static Date toDate(LocalDateTime localDateTime) {
        return Date.from(
                localDateTime.atZone(ZoneId.systemDefault())
                        .toInstant()
        );
    }

}