// EN: Query to get merchant details for admin.
// VI: Query để lấy chi tiết merchant cho admin.

using MediatR;
using Microsoft.EntityFrameworkCore;
using MerchantService.Domain.Exceptions;
using MerchantService.Infrastructure;

namespace MerchantService.API.Application.Queries.Admin;

/// <summary>
/// EN: Query to get detailed merchant information (Admin only).
/// VI: Query để lấy thông tin chi tiết merchant (chỉ Admin).
/// </summary>
public record GetMerchantDetailQuery(Guid MerchantId) : IRequest<AdminMerchantDetailDto>;

/// <summary>
/// EN: Handler for GetMerchantDetailQuery.
/// VI: Handler cho GetMerchantDetailQuery.
/// </summary>
public class GetMerchantDetailQueryHandler : IRequestHandler<GetMerchantDetailQuery, AdminMerchantDetailDto>
{
    private readonly MerchantServiceContext _context;

    public GetMerchantDetailQueryHandler(MerchantServiceContext context)
    {
        _context = context;
    }

    public async Task<AdminMerchantDetailDto> Handle(
        GetMerchantDetailQuery request,
        CancellationToken cancellationToken)
    {
        var merchant = await _context.Merchants
            .AsNoTracking()
            .Where(m => m.Id == request.MerchantId && !m.IsDeleted)
            .FirstOrDefaultAsync(cancellationToken)
            ?? throw new DomainException($"Merchant {request.MerchantId} not found");

        var shopsCount = await _context.Shops
            .CountAsync(s => s.MerchantId == request.MerchantId && !s.IsDeleted, cancellationToken);

        var staffCount = await _context.MerchantStaff
            .CountAsync(s => s.MerchantId == request.MerchantId, cancellationToken);

        var businessInfo = merchant.BusinessInfo != null
            ? new AdminBusinessInfoDto(
                merchant.BusinessInfo.TaxId,
                merchant.BusinessInfo.BusinessLicenseNumber,
                merchant.BusinessInfo.CompanyRegistrationNumber,
                null,
                null,
                null)
            : null;

        var settlementConfig = merchant.SettlementConfig != null
            ? new AdminSettlementConfigDto(
                merchant.SettlementConfig.CommissionRate,
                merchant.SettlementConfig.SettlementCycleId.ToString(),
                merchant.SettlementConfig.BankAccount?.ToString())
            : null;

        return new AdminMerchantDetailDto(
            merchant.Id,
            merchant.UserId,
            merchant.BusinessName,
            merchant.Type.Name,
            merchant.Status.Name,
            merchant.VerificationStatus.Name,
            businessInfo,
            settlementConfig,
            shopsCount,
            staffCount,
            merchant.CreatedAt,
            merchant.UpdatedAt,
            merchant.VerifiedAt,
            merchant.VerifiedBy);
    }
}
