// EN: Query to get merchant's shops with pagination and filtering.
// VI: Query để lấy danh sách shops của merchant với phân trang và lọc.

using MediatR;
using MerchantService.Domain.AggregatesModel.MerchantAggregate;
using MerchantService.Domain.AggregatesModel.ShopAggregate;
using MerchantService.Domain.Exceptions;
using MerchantService.Domain.SeedWork;
using static MerchantService.API.Application.Queries.Shops.EnumResolverHelper;

namespace MerchantService.API.Application.Queries.Shops;

/// <summary>
/// EN: Query to get a merchant's shops with pagination and optional status filter.
/// VI: Query để lấy shops của merchant với phân trang và lọc theo trạng thái (tùy chọn).
/// </summary>
public record GetMerchantShopsQuery(
    Guid MerchantId,
    string? Status,
    int PageNumber = 1,
    int PageSize = 20
) : IRequest<GetMerchantShopsQueryResult>;

/// <summary>
/// EN: Result of GetMerchantShopsQuery with pagination metadata.
/// VI: Kết quả của GetMerchantShopsQuery với thông tin phân trang.
/// </summary>
public record GetMerchantShopsQueryResult(
    IReadOnlyList<MerchantShopDto> Items,
    int TotalCount,
    int PageNumber,
    int PageSize
);

/// <summary>
/// EN: DTO for merchant shop listing.
/// VI: DTO cho danh sách shop của merchant.
/// </summary>
public record MerchantShopDto
{
    public Guid Id { get; init; }
    public string Name { get; init; } = null!;
    public string Slug { get; init; } = null!;
    public string Type { get; init; } = null!;
    public string Category { get; init; } = null!;
    public string Status { get; init; } = null!;
    public string? LogoUrl { get; init; }
    public string? Description { get; init; }
    public bool IsDefault { get; init; }
    public int BranchCount { get; init; }
    public DateTime CreatedAt { get; init; }
    public DateTime? UpdatedAt { get; init; }
}

/// <summary>
/// EN: Handler for GetMerchantShopsQuery.
/// VI: Handler cho GetMerchantShopsQuery.
/// </summary>
public class GetMerchantShopsQueryHandler : IRequestHandler<GetMerchantShopsQuery, GetMerchantShopsQueryResult>
{
    private readonly IMerchantRepository _merchantRepository;
    private readonly IShopRepository _shopRepository;
    private readonly ILogger<GetMerchantShopsQueryHandler> _logger;

    public GetMerchantShopsQueryHandler(
        IMerchantRepository merchantRepository,
        IShopRepository shopRepository,
        ILogger<GetMerchantShopsQueryHandler> logger)
    {
        _merchantRepository = merchantRepository;
        _shopRepository = shopRepository;
        _logger = logger;
    }

    public async Task<GetMerchantShopsQueryResult> Handle(GetMerchantShopsQuery request, CancellationToken cancellationToken)
    {
        // EN: Verify merchant exists
        // VI: Xác minh merchant tồn tại
        var merchant = await _merchantRepository.GetByIdAsync(request.MerchantId, cancellationToken);
        if (merchant == null)
        {
            throw new DomainException("Merchant not found / Không tìm thấy merchant");
        }

        // EN: Parse status filter if provided
        // VI: Parse bộ lọc trạng thái nếu có
        int? statusId = null;
        if (!string.IsNullOrWhiteSpace(request.Status))
        {
            statusId = request.Status.ToLowerInvariant() switch
            {
                "draft" => ShopStatus.Draft.Id,
                "active" => ShopStatus.Active.Id,
                "inactive" => ShopStatus.Inactive.Id,
                "closed" => ShopStatus.Closed.Id,
                _ => throw new DomainException($"Invalid status filter '{request.Status}'. Valid values: Draft, Active, Inactive, Closed / Giá trị lọc trạng thái không hợp lệ '{request.Status}'. Giá trị hợp lệ: Draft, Active, Inactive, Closed")
            };
        }

        // EN: Get paginated shops
        // VI: Lấy shops có phân trang
        var (items, totalCount) = await _shopRepository.GetByMerchantIdPagedAsync(
            request.MerchantId, statusId, request.PageNumber, request.PageSize, cancellationToken);

        _logger.LogInformation(
            "EN: Retrieved {Count} shops for merchant {MerchantId} (page {Page}/{TotalPages}) / VI: Đã lấy {Count} shops cho merchant {MerchantId} (trang {Page}/{TotalPages})",
            items.Count, request.MerchantId, request.PageNumber,
            (int)Math.Ceiling((double)totalCount / request.PageSize));

        var dtos = items.Select(s => new MerchantShopDto
        {
            Id = s.Id,
            Name = s.Name,
            Slug = s.Slug,
            Type = ResolveEnumName<ShopType>(s.TypeId, "Unknown"),
            Category = ResolveEnumName<BusinessCategory>(s.CategoryId, "Other"),
            Status = ResolveEnumName<ShopStatus>(s.StatusId, "Unknown"),
            LogoUrl = s.LogoUrl,
            Description = s.Description,
            IsDefault = s.IsDefault,
            BranchCount = s.Branches?.Count ?? 0,
            CreatedAt = s.CreatedAt,
            UpdatedAt = s.UpdatedAt
        }).ToList();

        return new GetMerchantShopsQueryResult(dtos, totalCount, request.PageNumber, request.PageSize);
    }
}
