using MediatR;
using TakeoutSaaS.Application.App.Merchants.Dto;
using TakeoutSaaS.Application.App.Merchants.Queries;
using TakeoutSaaS.Domain.Merchants.Enums;
using TakeoutSaaS.Domain.Merchants.Repositories;
using TakeoutSaaS.Domain.Tenants.Repositories;
using TakeoutSaaS.Shared.Abstractions.Results;

namespace TakeoutSaaS.Application.App.Merchants.Handlers;

/// <summary>
/// 待审核商户列表处理器。
/// </summary>
public sealed class GetPendingReviewListQueryHandler(
    IMerchantRepository merchantRepository,
    ITenantRepository tenantRepository)
    : IRequestHandler<GetPendingReviewListQuery, PagedResult<MerchantReviewListItemDto>>
{
    /// <inheritdoc />
    public async Task<PagedResult<MerchantReviewListItemDto>> Handle(
        GetPendingReviewListQuery request,
        CancellationToken cancellationToken)
    {
        var merchants = await merchantRepository.SearchAsync(
            request.TenantId,
            MerchantStatus.Pending,
            request.OperatingMode,
            request.Keyword,
            cancellationToken);

        var total = merchants.Count;
        var paged = merchants
            .OrderByDescending(x => x.CreatedAt)
            .Skip((request.Page - 1) * request.PageSize)
            .Take(request.PageSize)
            .ToList();

        var tenantIds = paged.Select(x => x.TenantId).Distinct().ToArray();
        var tenants = await tenantRepository.FindByIdsAsync(tenantIds, cancellationToken);
        var tenantLookup = tenants.ToDictionary(x => x.Id, x => x.Name);

        var items = paged.Select(merchant => new MerchantReviewListItemDto
        {
            Id = merchant.Id,
            TenantId = merchant.TenantId,
            TenantName = tenantLookup.TryGetValue(merchant.TenantId, out var name) ? name : null,
            Name = merchant.BrandName,
            OperatingMode = merchant.OperatingMode,
            LicenseNumber = merchant.BusinessLicenseNumber,
            Status = merchant.Status,
            ClaimedByName = merchant.ClaimedByName,
            ClaimedAt = merchant.ClaimedAt,
            ClaimExpiresAt = merchant.ClaimExpiresAt,
            CreatedAt = merchant.CreatedAt
        }).ToList();

        return new PagedResult<MerchantReviewListItemDto>(items, request.Page, request.PageSize, total);
    }
}
