using MediatR;
using TakeoutSaaS.Application.App.Orders.Dto;
using TakeoutSaaS.Application.App.Orders.Queries;
using TakeoutSaaS.Domain.Orders.Entities;
using TakeoutSaaS.Domain.Orders.Enums;
using TakeoutSaaS.Domain.Orders.Repositories;

namespace TakeoutSaaS.Application.App.Orders.Handlers;

/// <summary>
/// 获取订单看板数据查询处理器。
/// </summary>
public sealed class GetOrderBoardQueryHandler(IOrderRepository orderRepository)
    : IRequestHandler<GetOrderBoardQuery, OrderBoardResultDto>
{
    /// <inheritdoc />
    public async Task<OrderBoardResultDto> Handle(GetOrderBoardQuery request, CancellationToken cancellationToken)
    {
        // 1. 查询活跃订单
        var activeOrders = await orderRepository.GetActiveOrdersAsync(
            request.TenantId, request.StoreId, cancellationToken);

        // 2. 查询今日已完成订单（限 20 条）
        var todayStart = DateTime.UtcNow.Date;
        var completedOrders = await orderRepository.GetOrdersChangedSinceAsync(
            request.TenantId, request.StoreId, todayStart, cancellationToken);
        var todayCompleted = completedOrders
            .Where(o => o.Status == OrderStatus.Completed)
            .OrderByDescending(o => o.FinishedAt)
            .Take(20)
            .ToList();

        // 3. 合并并按渠道筛选
        var allOrders = activeOrders.Concat(todayCompleted).ToList();
        if (request.Channel.HasValue)
        {
            allOrders = allOrders.Where(o => o.Channel == request.Channel.Value).ToList();
        }

        // 4. 获取商品摘要
        var orderIds = allOrders.Select(o => o.Id).ToList();
        var itemsMap = orderIds.Count > 0
            ? await orderRepository.GetItemsByOrderIdsAsync(orderIds, request.TenantId, cancellationToken)
            : new Dictionary<long, IReadOnlyList<OrderItem>>();

        // 5. 按状态分组
        var cards = allOrders.Select(o => MapToCard(o, itemsMap)).ToList();

        return new OrderBoardResultDto
        {
            Pending = cards.Where(c => c.Status == OrderStatus.AwaitingPreparation)
                .OrderBy(c => c.CreatedAt).ToList(),
            Making = cards.Where(c => c.Status == OrderStatus.InProgress)
                .OrderBy(c => c.AcceptedAt).ToList(),
            Delivering = cards.Where(c => c.Status == OrderStatus.Ready)
                .OrderBy(c => c.ReadyAt).ToList(),
            Completed = cards.Where(c => c.Status == OrderStatus.Completed)
                .OrderByDescending(c => c.CreatedAt).ToList()
        };
    }

    private static OrderBoardCardDto MapToCard(
        Order order,
        IReadOnlyDictionary<long, IReadOnlyList<OrderItem>> itemsMap)
    {
        var items = itemsMap.TryGetValue(order.Id, out var list) ? list : [];
        var summary = items.Count > 0
            ? string.Join("、", items.Take(3).Select(x => x.ProductName))
              + (items.Count > 3 ? $" 等{items.Count}件" : string.Empty)
            : string.Empty;

        return new OrderBoardCardDto
        {
            Id = order.Id,
            OrderNo = order.OrderNo,
            StoreId = order.StoreId,
            Channel = order.Channel,
            DeliveryType = order.DeliveryType,
            Status = order.Status,
            CustomerName = order.CustomerName,
            CustomerPhone = order.CustomerPhone,
            TableNo = order.TableNo,
            QueueNumber = order.QueueNumber,
            ItemsSummary = summary,
            PaidAmount = order.PaidAmount,
            CreatedAt = order.CreatedAt
        };
    }
}
