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

namespace TakeoutSaaS.Application.App.Products.Handlers;

/// <summary>
/// 商品全量详情查询处理器。
/// </summary>
public sealed class GetProductDetailQueryHandler(
    IProductRepository productRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<GetProductDetailQuery, ProductDetailDto?>
{
    /// <inheritdoc />
    public async Task<ProductDetailDto?> Handle(GetProductDetailQuery request, CancellationToken cancellationToken)
    {
        // 1. 读取 SPU
        var tenantId = tenantProvider.GetCurrentTenantId();
        var product = await productRepository.FindByIdAsync(request.ProductId, tenantId, cancellationToken);
        if (product is null)
        {
            return null;
        }

        // 2. 查询子项
        var skusTask = productRepository.GetSkusAsync(product.Id, tenantId, cancellationToken);
        var attrGroupsTask = productRepository.GetAttributeGroupsAsync(product.Id, tenantId, cancellationToken);
        var attrOptionsTask = productRepository.GetAttributeOptionsAsync(product.Id, tenantId, cancellationToken);
        var addonGroupsTask = productRepository.GetAddonGroupsAsync(product.Id, tenantId, cancellationToken);
        var addonOptionsTask = productRepository.GetAddonOptionsAsync(product.Id, tenantId, cancellationToken);
        var mediaTask = productRepository.GetMediaAssetsAsync(product.Id, tenantId, cancellationToken);
        var pricingTask = productRepository.GetPricingRulesAsync(product.Id, tenantId, cancellationToken);

        await Task.WhenAll(skusTask, attrGroupsTask, attrOptionsTask, addonGroupsTask, addonOptionsTask, mediaTask, pricingTask);

        // 3. 组装 DTO
        var skus = await skusTask;
        var attrGroups = await attrGroupsTask;
        var attrOptions = (await attrOptionsTask).ToLookup(x => x.AttributeGroupId);
        var addonGroups = await addonGroupsTask;
        var addonOptions = (await addonOptionsTask).ToLookup(x => x.AddonGroupId);
        var mediaAssets = await mediaTask;
        var pricingRules = await pricingTask;
        var detail = new ProductDetailDto
        {
            Product = ProductMapping.ToDto(product),
            Skus = skus.Select(ProductMapping.ToDto).ToList(),
            AttributeGroups = attrGroups
                .Select(g => ProductMapping.ToDto(g, attrOptions[g.Id].ToList()))
                .ToList(),
            AddonGroups = addonGroups
                .Select(g => ProductMapping.ToDto(g, addonOptions[g.Id].ToList()))
                .ToList(),
            MediaAssets = mediaAssets.Select(ProductMapping.ToDto).ToList(),
            PricingRules = pricingRules.Select(ProductMapping.ToDto).ToList()
        };

        return detail;
    }
}
