using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using TakeoutSaaS.Application.Messaging;
using TakeoutSaaS.Application.Messaging.Abstractions;
using TakeoutSaaS.Application.Messaging.Events;
using TakeoutSaaS.Domain.Orders.Entities;
using TakeoutSaaS.Domain.Orders.Enums;
using TakeoutSaaS.Domain.Orders.Repositories;
using TakeoutSaaS.Module.Scheduler.Options;
using TakeoutSaaS.Shared.Abstractions.Ids;

namespace TakeoutSaaS.Module.Scheduler.Jobs;

/// <summary>
/// 订单超时自动取消任务。
/// </summary>
public sealed class OrderTimeoutJob(
    IOrderRepository orderRepository,
    IEventPublisher eventPublisher,
    IIdGenerator idGenerator,
    IOptionsMonitor<OrderTimeoutOptions> options,
    ILogger<OrderTimeoutJob> logger)
{
    /// <summary>
    /// 执行超时订单检查与自动取消。
    /// </summary>
    public async Task ExecuteAsync()
    {
        var config = options.CurrentValue;
        var cutoff = DateTime.UtcNow.AddMinutes(-config.AutoCancelMinutes);

        // 1. 查询所有超时待接单订单
        var pendingOrders = await orderRepository.SearchAsync(
            tenantId: 0, // 跨租户查询，由仓储层处理
            status: OrderStatus.AwaitingPreparation,
            paymentStatus: null);

        var timedOutOrders = pendingOrders
            .Where(o => o.CreatedAt < cutoff)
            .ToList();

        if (timedOutOrders.Count == 0)
        {
            logger.LogDebug("无超时待接单订单");
            return;
        }

        logger.LogInformation("发现 {Count} 笔超时待接单订单，开始自动取消", timedOutOrders.Count);

        // 2. 逐笔取消
        foreach (var order in timedOutOrders)
        {
            var oldStatus = order.Status;
            order.Status = OrderStatus.Cancelled;
            order.CancelledAt = DateTime.UtcNow;
            order.CancelReason = "超时未接单，系统自动取消";

            // 3. 写入状态流转记录
            var history = new OrderStatusHistory
            {
                Id = idGenerator.NextId(),
                OrderId = order.Id,
                TenantId = order.TenantId,
                Status = OrderStatus.Cancelled,
                Notes = "超时未接单，系统自动取消",
                OccurredAt = DateTime.UtcNow
            };

            await orderRepository.UpdateOrderAsync(order);
            await orderRepository.AddStatusHistoryAsync(history);
            await orderRepository.SaveChangesAsync();

            // 4. 发布状态变更事件
            await eventPublisher.PublishAsync(EventRoutingKeys.OrderStatusChanged, new OrderStatusChangedEvent
            {
                OrderId = order.Id,
                OrderNo = order.OrderNo,
                TenantId = order.TenantId,
                StoreId = order.StoreId,
                OldStatus = (int)oldStatus,
                NewStatus = (int)OrderStatus.Cancelled,
                Channel = (int)order.Channel,
                DeliveryType = (int)order.DeliveryType,
                CustomerName = order.CustomerName,
                PaidAmount = order.PaidAmount,
                OccurredAt = DateTime.UtcNow
            });

            logger.LogInformation("自动取消超时订单 {OrderNo} ({OrderId})", order.OrderNo, order.Id);
        }
    }
}
