using MediatR;
using TakeoutSaaS.Application.App.Orders.Dto;
using TakeoutSaaS.Application.App.Orders.Queries;
using TakeoutSaaS.Domain.Orders.Repositories;
using TakeoutSaaS.Shared.Abstractions.Results;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.App.Orders.Handlers;

/// <summary>
/// 订单列表查询处理器。
/// </summary>
public sealed class SearchOrdersQueryHandler(
    IOrderRepository orderRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<SearchOrdersQuery, PagedResult<OrderDto>>
{
    /// <inheritdoc />
    public async Task<PagedResult<OrderDto>> Handle(SearchOrdersQuery request, CancellationToken cancellationToken)
    {
        // 1. 获取当前租户并查询订单
        var tenantId = tenantProvider.GetCurrentTenantId();
        var orders = await orderRepository.SearchAsync(tenantId, request.Status, request.PaymentStatus, cancellationToken);

        // 2. 可选过滤：门店
        if (request.StoreId.HasValue)
        {
            orders = orders.Where(x => x.StoreId == request.StoreId.Value).ToList();
        }

        // 3. 可选过滤：订单号模糊
        if (!string.IsNullOrWhiteSpace(request.OrderNo))
        {
            var orderNo = request.OrderNo.Trim();
            orders = orders
                .Where(x => x.OrderNo.Contains(orderNo, StringComparison.OrdinalIgnoreCase))
                .ToList();
        }

        // 4. 排序与分页
        var sorted = ApplySorting(orders, request.SortBy, request.SortDescending);
        var paged = sorted
            .Skip((request.Page - 1) * request.PageSize)
            .Take(request.PageSize)
            .ToList();

        // 5. 映射 DTO
        var items = paged.Select(order => new OrderDto
        {
            Id = order.Id,
            TenantId = order.TenantId,
            OrderNo = order.OrderNo,
            StoreId = order.StoreId,
            Channel = order.Channel,
            DeliveryType = order.DeliveryType,
            Status = order.Status,
            PaymentStatus = order.PaymentStatus,
            CustomerName = order.CustomerName,
            CustomerPhone = order.CustomerPhone,
            TableNo = order.TableNo,
            QueueNumber = order.QueueNumber,
            ReservationId = order.ReservationId,
            ItemsAmount = order.ItemsAmount,
            DiscountAmount = order.DiscountAmount,
            PayableAmount = order.PayableAmount,
            PaidAmount = order.PaidAmount,
            PaidAt = order.PaidAt,
            FinishedAt = order.FinishedAt,
            CancelledAt = order.CancelledAt,
            CancelReason = order.CancelReason,
            Remark = order.Remark,
            CreatedAt = order.CreatedAt
        }).ToList();

        // 6. 返回分页结果
        return new PagedResult<OrderDto>(items, request.Page, request.PageSize, orders.Count);
    }

    private static IOrderedEnumerable<Domain.Orders.Entities.Order> ApplySorting(
        IReadOnlyCollection<Domain.Orders.Entities.Order> orders,
        string? sortBy,
        bool sortDescending)
    {
        return sortBy?.ToLowerInvariant() switch
        {
            "paidat" => sortDescending ? orders.OrderByDescending(x => x.PaidAt) : orders.OrderBy(x => x.PaidAt),
            "status" => sortDescending ? orders.OrderByDescending(x => x.Status) : orders.OrderBy(x => x.Status),
            "payableamount" => sortDescending ? orders.OrderByDescending(x => x.PayableAmount) : orders.OrderBy(x => x.PayableAmount),
            _ => sortDescending ? orders.OrderByDescending(x => x.CreatedAt) : orders.OrderBy(x => x.CreatedAt)
        };
    }
}
