// EN: Handler for Disable2FACommand
// VI: Handler cho Disable2FACommand

using MediatR;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using IamService.Domain.AggregatesModel.UserAggregate;
using IamService.Infrastructure.TwoFactor;

namespace IamService.API.Application.Commands.Auth;

/// <summary>
/// EN: Handler for Disable2FACommand.
/// VI: Handler cho Disable2FACommand.
/// </summary>
public class Disable2FACommandHandler : IRequestHandler<Disable2FACommand, Disable2FAResult>
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly ITwoFactorService _twoFactorService;
    private readonly ILogger<Disable2FACommandHandler> _logger;

    public Disable2FACommandHandler(
        UserManager<ApplicationUser> userManager,
        ITwoFactorService twoFactorService,
        ILogger<Disable2FACommandHandler> logger)
    {
        _userManager = userManager;
        _twoFactorService = twoFactorService;
        _logger = logger;
    }

    public async Task<Disable2FAResult> Handle(
        Disable2FACommand request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation("Disabling 2FA for user {UserId}", request.UserId);

        // EN: Find user by ID
        // VI: Tìm user theo ID
        var user = await _userManager.FindByIdAsync(request.UserId.ToString());
        if (user == null)
        {
            _logger.LogWarning("User not found with ID {UserId}", request.UserId);
            return new Disable2FAResult(false, "User not found.");
        }

        // EN: Check if 2FA is enabled
        // VI: Kiểm tra xem 2FA có được bật không
        if (!await _userManager.GetTwoFactorEnabledAsync(user))
        {
            _logger.LogInformation("2FA is not enabled for user {UserId}", request.UserId);
            return new Disable2FAResult(false, "Two-factor authentication is not enabled.");
        }

        // EN: Get secret key and validate code
        // VI: Lấy secret key và xác minh mã
        var secretKey = await _userManager.GetAuthenticationTokenAsync(
            user,
            "[TwoFactor]",
            "SecretKey");

        if (string.IsNullOrEmpty(secretKey))
        {
            _logger.LogWarning("No 2FA secret key found for user {UserId}", request.UserId);
            return new Disable2FAResult(false, "2FA configuration not found.");
        }

        // EN: Validate the code before disabling
        // VI: Xác minh mã trước khi tắt
        var isValid = _twoFactorService.ValidateCode(secretKey, request.Code);

        if (!isValid)
        {
            _logger.LogWarning("Invalid 2FA code for user {UserId}", request.UserId);
            return new Disable2FAResult(false, "Invalid verification code.");
        }

        // EN: Disable 2FA for user
        // VI: Tắt 2FA cho user
        var result = await _userManager.SetTwoFactorEnabledAsync(user, false);

        if (!result.Succeeded)
        {
            var errors = string.Join(", ", result.Errors.Select(e => e.Description));
            _logger.LogWarning("Failed to disable 2FA for user {UserId}: {Errors}", request.UserId, errors);
            return new Disable2FAResult(false, $"Failed to disable 2FA: {errors}");
        }

        // EN: Remove secret key and recovery codes
        // VI: Xóa secret key và mã khôi phục
        await _userManager.RemoveAuthenticationTokenAsync(user, "[TwoFactor]", "SecretKey");
        await _userManager.RemoveAuthenticationTokenAsync(user, "[TwoFactor]", "RecoveryCodes");

        _logger.LogInformation("2FA disabled successfully for user {UserId}", request.UserId);

        return new Disable2FAResult(true, "Two-factor authentication disabled successfully.");
    }
}
