using MediatR;
using Microsoft.Extensions.Logging;
using WhatsAppService.Domain.AggregatesModel.WhatsAppAccountAggregate;
using WhatsAppService.Infrastructure.Security;

namespace WhatsAppService.API.Application.Commands;

/// <summary>
/// EN: Handler for ConnectWhatsAppAccountCommand.
/// VI: Handler cho ConnectWhatsAppAccountCommand.
/// </summary>
public class ConnectWhatsAppAccountCommandHandler : IRequestHandler<ConnectWhatsAppAccountCommand, ConnectWhatsAppAccountResult>
{
    private readonly IWhatsAppAccountRepository _repository;
    private readonly IAccessTokenEncryptionService _encryptionService;
    private readonly ILogger<ConnectWhatsAppAccountCommandHandler> _logger;

    public ConnectWhatsAppAccountCommandHandler(
        IWhatsAppAccountRepository repository,
        IAccessTokenEncryptionService encryptionService,
        ILogger<ConnectWhatsAppAccountCommandHandler> logger)
    {
        _repository = repository ?? throw new ArgumentNullException(nameof(repository));
        _encryptionService = encryptionService ?? throw new ArgumentNullException(nameof(encryptionService));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<ConnectWhatsAppAccountResult> Handle(
        ConnectWhatsAppAccountCommand request,
        CancellationToken cancellationToken)
    {
        try
        {
            // Check if account already exists for this shop
            var existing = await _repository.GetByShopIdAsync(request.ShopId, cancellationToken);
            if (existing != null)
            {
                return new ConnectWhatsAppAccountResult(false, null, "Shop already has a connected WhatsApp account");
            }

            // Check if phone number is already in use
            var existingPhone = await _repository.GetByPhoneNumberIdAsync(request.PhoneNumberId, cancellationToken);
            if (existingPhone != null)
            {
                return new ConnectWhatsAppAccountResult(false, null, "Phone number is already connected to another shop");
            }

            var encryptedToken = _encryptionService.Encrypt(request.AccessToken);

            var account = new WhatsAppAccount(
                request.ShopId,
                request.PhoneNumberId,
                encryptedToken,
                request.WebhookUrl);

            await _repository.AddAsync(account, cancellationToken);
            await _repository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

            _logger.LogInformation(
                "WhatsApp account connected for shop {ShopId}. AccountId: {AccountId}",
                request.ShopId, account.Id);

            return new ConnectWhatsAppAccountResult(true, account.Id, null);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to connect WhatsApp account for shop {ShopId}", request.ShopId);
            return new ConnectWhatsAppAccountResult(false, null, ex.Message);
        }
    }
}
