using MediatR;
using TakeoutSaaS.Application.App.Deliveries.Dto;
using TakeoutSaaS.Application.App.Deliveries.Queries;
using TakeoutSaaS.Domain.Deliveries.Entities;
using TakeoutSaaS.Domain.Deliveries.Repositories;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.App.Deliveries.Handlers;

/// <summary>
/// 配送单详情查询处理器。
/// </summary>
public sealed class GetDeliveryOrderByIdQueryHandler(
    IDeliveryRepository deliveryRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<GetDeliveryOrderByIdQuery, DeliveryOrderDto?>
{
    /// <inheritdoc />
    public async Task<DeliveryOrderDto?> Handle(GetDeliveryOrderByIdQuery request, CancellationToken cancellationToken)
    {
        // 1. 读取当前租户标识
        var tenantId = tenantProvider.GetCurrentTenantId();

        // 2. 查询配送单主体
        var order = await deliveryRepository.FindByIdAsync(request.DeliveryOrderId, tenantId, cancellationToken);
        if (order == null)
        {
            return null;
        }

        // 3. 查询配送事件明细
        var events = await deliveryRepository.GetEventsAsync(order.Id, tenantId, cancellationToken);

        // 4. 映射为 DTO 返回
        return MapToDto(order, events);
    }

    private static DeliveryOrderDto MapToDto(DeliveryOrder deliveryOrder, IReadOnlyList<DeliveryEvent> events) => new()
    {
        Id = deliveryOrder.Id,
        TenantId = deliveryOrder.TenantId,
        OrderId = deliveryOrder.OrderId,
        Provider = deliveryOrder.Provider,
        ProviderOrderId = deliveryOrder.ProviderOrderId,
        Status = deliveryOrder.Status,
        DeliveryFee = deliveryOrder.DeliveryFee,
        CourierName = deliveryOrder.CourierName,
        CourierPhone = deliveryOrder.CourierPhone,
        DispatchedAt = deliveryOrder.DispatchedAt,
        PickedUpAt = deliveryOrder.PickedUpAt,
        DeliveredAt = deliveryOrder.DeliveredAt,
        FailureReason = deliveryOrder.FailureReason,
        CreatedAt = deliveryOrder.CreatedAt,
        Events = events.Select(x => new DeliveryEventDto
        {
            Id = x.Id,
            DeliveryOrderId = x.DeliveryOrderId,
            EventType = x.EventType,
            Message = x.Message,
            OccurredAt = x.OccurredAt,
            Payload = x.Payload
        }).ToList()
    };
}
