// EN: Handler for RegisterMerchantCommand.
// VI: Handler cho RegisterMerchantCommand.

using MediatR;
using MerchantService.Domain.AggregatesModel.MerchantAggregate;
using MerchantService.Domain.Exceptions;

namespace MerchantService.API.Application.Commands.Merchants;

/// <summary>
/// EN: Handler for registering a new merchant.
/// VI: Handler để đăng ký merchant mới.
/// </summary>
public class RegisterMerchantCommandHandler : IRequestHandler<RegisterMerchantCommand, RegisterMerchantResult>
{
    private readonly IMerchantRepository _merchantRepository;
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly ILogger<RegisterMerchantCommandHandler> _logger;

    public RegisterMerchantCommandHandler(
        IMerchantRepository merchantRepository,
        IHttpContextAccessor httpContextAccessor,
        ILogger<RegisterMerchantCommandHandler> logger)
    {
        _merchantRepository = merchantRepository;
        _httpContextAccessor = httpContextAccessor;
        _logger = logger;
    }

    public async Task<RegisterMerchantResult> Handle(RegisterMerchantCommand request, CancellationToken cancellationToken)
    {
        // EN: Get current user ID from claims
        // VI: Lấy user ID hiện tại từ claims
        var userIdClaim = _httpContextAccessor.HttpContext?.User.FindFirst("sub")?.Value
            ?? _httpContextAccessor.HttpContext?.User.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value;
        
        if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
        {
            throw new DomainException("User not authenticated");
        }

        // EN: Check if user already has a merchant account
        // VI: Kiểm tra user đã có tài khoản merchant chưa
        var existingMerchant = await _merchantRepository.ExistsByUserIdAsync(userId, cancellationToken);
        if (existingMerchant)
        {
            throw new DomainException("User already has a merchant account");
        }

        // EN: Parse merchant type
        // VI: Parse loại merchant
        var merchantType = request.Type.ToLowerInvariant() switch
        {
            "individual" => MerchantType.Individual,
            "company" => MerchantType.Company,
            _ => MerchantType.Individual
        };

        // EN: Create merchant aggregate
        // VI: Tạo merchant aggregate
        var merchant = Merchant.Register(userId, request.BusinessName, merchantType);

        // EN: Update business info if provided
        // VI: Cập nhật thông tin doanh nghiệp nếu có
        if (!string.IsNullOrWhiteSpace(request.TaxId) || !string.IsNullOrWhiteSpace(request.BusinessLicenseNumber))
        {
            merchant.UpdateBusinessInfo(new BusinessInfo
            {
                TaxId = request.TaxId,
                BusinessLicenseNumber = request.BusinessLicenseNumber
            });
        }

        // EN: Save to repository
        // VI: Lưu vào repository
        _merchantRepository.Add(merchant);
        await _merchantRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "Merchant registered: {MerchantId} for user {UserId}",
            merchant.Id, userId);

        return new RegisterMerchantResult(
            merchant.Id,
            merchant.BusinessName,
            merchant.Status.Name
        );
    }
}
