using MediatR;
using MktXService.Domain.AggregatesModel.TwitterAccountAggregate;
using MktXService.Infrastructure.ExternalServices.Twitter;

namespace MktXService.API.Application.Commands;

/// <summary>
/// EN: Handler for ConnectTwitterAccountCommand.
/// VI: Handler cho ConnectTwitterAccountCommand.
/// </summary>
public class ConnectTwitterAccountCommandHandler : IRequestHandler<ConnectTwitterAccountCommand, ConnectTwitterAccountResult>
{
    private readonly ITwitterAccountRepository _accountRepository;
    private readonly ITwitterApiClient _twitterClient;
    private readonly ILogger<ConnectTwitterAccountCommandHandler> _logger;

    public ConnectTwitterAccountCommandHandler(
        ITwitterAccountRepository accountRepository,
        ITwitterApiClient twitterClient,
        ILogger<ConnectTwitterAccountCommandHandler> logger)
    {
        _accountRepository = accountRepository;
        _twitterClient = twitterClient;
        _logger = logger;
    }

    public async Task<ConnectTwitterAccountResult> Handle(
        ConnectTwitterAccountCommand request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation("Connecting Twitter account {Username} for merchant {MerchantId}",
            request.Username, request.MerchantId);

        try
        {
            // EN: Check if account already exists
            // VI: Kiểm tra xem tài khoản đã tồn tại chưa
            var existingAccount = await _accountRepository.GetByTwitterUserIdAsync(request.TwitterUserId);
            if (existingAccount != null)
            {
                return new ConnectTwitterAccountResult(false, null, "Twitter account already connected");
            }

            // EN: Create new account
            // VI: Tạo tài khoản mới
            var account = new TwitterAccount(
                request.MerchantId,
                request.TwitterUserId,
                request.Username,
                request.OAuthToken,
                request.OAuthTokenSecret,
                request.DisplayName,
                request.ProfileImageUrl);

            _accountRepository.Add(account);
            await _accountRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

            _logger.LogInformation("Twitter account {AccountId} connected successfully", account.Id);
            return new ConnectTwitterAccountResult(true, account.Id, null);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to connect Twitter account {Username}", request.Username);
            return new ConnectTwitterAccountResult(false, null, ex.Message);
        }
    }
}

/// <summary>
/// EN: Handler for DisconnectTwitterAccountCommand.
/// VI: Handler cho DisconnectTwitterAccountCommand.
/// </summary>
public class DisconnectTwitterAccountCommandHandler : IRequestHandler<DisconnectTwitterAccountCommand, bool>
{
    private readonly ITwitterAccountRepository _accountRepository;
    private readonly ILogger<DisconnectTwitterAccountCommandHandler> _logger;

    public DisconnectTwitterAccountCommandHandler(
        ITwitterAccountRepository accountRepository,
        ILogger<DisconnectTwitterAccountCommandHandler> logger)
    {
        _accountRepository = accountRepository;
        _logger = logger;
    }

    public async Task<bool> Handle(
        DisconnectTwitterAccountCommand request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation("Disconnecting Twitter account {AccountId}", request.AccountId);

        var account = await _accountRepository.GetByIdAsync(request.AccountId);
        if (account == null)
        {
            _logger.LogWarning("Account {AccountId} not found", request.AccountId);
            return false;
        }

        account.Disconnect();
        await _accountRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation("Twitter account {AccountId} disconnected", request.AccountId);
        return true;
    }
}

/// <summary>
/// EN: Handler for RefreshTwitterAccountTokensCommand.
/// VI: Handler cho RefreshTwitterAccountTokensCommand.
/// </summary>
public class RefreshTwitterAccountTokensCommandHandler : IRequestHandler<RefreshTwitterAccountTokensCommand, bool>
{
    private readonly ITwitterAccountRepository _accountRepository;
    private readonly ILogger<RefreshTwitterAccountTokensCommandHandler> _logger;

    public RefreshTwitterAccountTokensCommandHandler(
        ITwitterAccountRepository accountRepository,
        ILogger<RefreshTwitterAccountTokensCommandHandler> logger)
    {
        _accountRepository = accountRepository;
        _logger = logger;
    }

    public async Task<bool> Handle(
        RefreshTwitterAccountTokensCommand request,
        CancellationToken cancellationToken)
    {
        var account = await _accountRepository.GetByIdAsync(request.AccountId);
        if (account == null) return false;

        account.UpdateCredentials(request.NewOAuthToken, request.NewOAuthTokenSecret);
        await _accountRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        return true;
    }
}
