package com.haha.admin.task;

import com.haha.common.enums.PayScoreState;
import com.haha.common.utils.TraceIdUtils;
import com.haha.entity.Order;
import com.haha.service.OrderService;
import com.haha.service.payment.payscore.PayScoreResult;
import com.haha.service.payment.payscore.PayScoreService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;

/**
 * 支付分状态同步定时任务
 * 定期查询处于 USER_PAYING 状态的订单，主动从微信侧同步最新支付状态
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class PayScoreSyncTask {

    private final OrderService orderService;
    private final PayScoreService payScoreService;

    /**
     * 支付分状态同步阈值：服务结束后 30 分钟才开始同步
     */
    private static final int SYNC_DELAY_MINUTES = 30;

    /**
     * 超时警告阈值：处于 USER_PAYING 状态超过 24 小时
     */
    private static final int OVERDUE_HOURS = 24;

    /**
     * 每 5 分钟执行一次，同步处于 USER_PAYING 和 DOING 状态的支付分订单
     */
    @Scheduled(cron = "0 */5 * * * ?")
    public void syncPayingOrders() {
        String traceId = TraceIdUtils.generateTraceId();
        TraceIdUtils.setTraceId(traceId);

        try {
            log.info("[支付分同步] 开始同步 USER_PAYING 状态订单");

            // 查询 payScoreState = USER_PAYING 且 serviceEndTime 超过 SYNC_DELAY_MINUTES 分钟的订单
            List<Order> payingOrders = orderService.lambdaQuery()
                    .eq(Order::getPayScoreState, PayScoreState.USER_PAYING.getCode())
                    .lt(Order::getServiceEndTime, LocalDateTime.now().minusMinutes(SYNC_DELAY_MINUTES))
                    .list();

            if (!payingOrders.isEmpty()) {
                log.info("[支付分同步] 找到 {} 个 USER_PAYING 订单", payingOrders.size());
                processSyncOrders(payingOrders);
            } else {
                log.info("[支付分同步] 无待同步的 USER_PAYING 订单");
            }

            // 同步 DOING 状态订单（兜底防止回调丢失）
            syncDoingOrders();

        } catch (Exception e) {
            log.error("[支付分同步] 定时任务执行失败", e);
        } finally {
            TraceIdUtils.removeTraceId();
        }
    }

    /**
     * 同步 CREATED 和 DOING 状态订单（兜底防止回调丢失）
     */
    private void syncDoingOrders() {
        // 同步 CREATED 状态订单（等待用户确认的回调可能丢失）
        syncCreatedOrders();

        // 同步 DOING 状态订单
        syncDoingOrdersInternal();
    }

    private void syncCreatedOrders() {
        try {
            List<Order> createdOrders = orderService.lambdaQuery()
                    .eq(Order::getPayScoreState, PayScoreState.CREATED.getCode())
                    .lt(Order::getServiceStartTime, LocalDateTime.now().minusMinutes(SYNC_DELAY_MINUTES))
                    .list();

            if (!createdOrders.isEmpty()) {
                log.info("[支付分同步] 找到 {} 个 CREATED 状态订单，开始同步", createdOrders.size());
                processSyncOrders(createdOrders);
            }
        } catch (Exception e) {
            log.error("[支付分同步] 同步 CREATED 状态订单失败", e);
        }
    }

    private void syncDoingOrdersInternal() {
        try {
            List<Order> doingOrders = orderService.lambdaQuery()
                    .eq(Order::getPayScoreState, PayScoreState.DOING.getCode())
                    .lt(Order::getServiceStartTime, LocalDateTime.now().minusMinutes(SYNC_DELAY_MINUTES))
                    .list();

            if (doingOrders.isEmpty()) {
                log.info("[支付分同步] 无待同步的 DOING 状态订单");
                return;
            }

            log.info("[支付分同步] 找到 {} 个 DOING 状态订单，开始同步", doingOrders.size());
            processSyncOrders(doingOrders);
        } catch (Exception e) {
            log.error("[支付分同步] 同步 DOING 状态订单失败", e);
        }
    }

    /**
     * 批量同步订单状态
     */
    private void processSyncOrders(List<Order> orders) {
        int syncedCount = 0;
        int stillPayingCount = 0;

        for (Order order : orders) {
            try {
                PayScoreResult result = payScoreService.syncPayScoreStatus(order.getId());
                if (result != null && result.isSuccess()) {
                    syncedCount++;
                }

                // 重新查询订单确认最新状态
                Order updatedOrder = orderService.getById(order.getId());
                if (updatedOrder != null) {
                    String state = updatedOrder.getPayScoreState();
                    if (PayScoreState.isPaying(state)) {
                        stillPayingCount++;
                        checkOverdueWarning(updatedOrder);
                    } else if (PayScoreState.isExpired(state)) {
                        log.info("[支付分同步] 订单已过期 - orderId: {}", updatedOrder.getId());
                    }
                }
            } catch (Exception e) {
                log.error("[支付分同步] 同步订单状态异常 - orderId: {}", order.getId(), e);
            }
        }

        log.info("[支付分同步] 同步完成 - 共处理 {} 单, 状态变更 {} 单, 仍待支付 {} 单",
                orders.size(), syncedCount, stillPayingCount);
    }

    /**
     * 检查订单逾期告警
     */
    private void checkOverdueWarning(Order order) {
        if (order.getServiceEndTime() != null) {
            long hoursElapsed = ChronoUnit.HOURS.between(
                    order.getServiceEndTime(), LocalDateTime.now());
            if (hoursElapsed >= OVERDUE_HOURS) {
                log.warn("[支付分同步] 订单长时间未支付 - orderId: {}, 已过 {} 小时, failReason: {}",
                        order.getId(), hoursElapsed, order.getPayScoreFailReason());
            }
        }
    }
}
