using MediatR;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using IamService.Domain.AggregatesModel.UserAggregate;
using IamService.Domain.Exceptions;

namespace IamService.API.Application.Commands.Auth;

/// <summary>
/// EN: Handler for AdminResetPasswordCommand — uses raw SQL to update password hash directly,
///     avoiding DateTime Kind issues with EF Core + Npgsql timestamptz.
/// VI: Handler cho AdminResetPasswordCommand — dùng raw SQL để cập nhật password hash trực tiếp,
///     tránh lỗi DateTime Kind với EF Core + Npgsql timestamptz.
/// </summary>
public class AdminResetPasswordCommandHandler : IRequestHandler<AdminResetPasswordCommand, ChangePasswordCommandResult>
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly ILogger<AdminResetPasswordCommandHandler> _logger;

    public AdminResetPasswordCommandHandler(
        UserManager<ApplicationUser> userManager,
        ILogger<AdminResetPasswordCommandHandler> logger)
    {
        _userManager = userManager;
        _logger = logger;
    }

    public async Task<ChangePasswordCommandResult> Handle(AdminResetPasswordCommand request, CancellationToken cancellationToken)
    {
        _logger.LogInformation("EN: Admin resetting password for user {UserId} / VI: Admin reset mật khẩu cho user {UserId}", request.UserId);

        var user = await _userManager.FindByIdAsync(request.UserId.ToString());
        if (user == null)
            throw new DomainException($"User with ID {request.UserId} not found.");

        // EN: Use RemovePassword + AddPassword to avoid ResetPasswordAsync's DateTime issue
        // VI: Dùng RemovePassword + AddPassword để tránh lỗi DateTime của ResetPasswordAsync
        var removeResult = await _userManager.RemovePasswordAsync(user);
        if (!removeResult.Succeeded)
        {
            var errors = string.Join(", ", removeResult.Errors.Select(e => e.Description));
            _logger.LogWarning("EN: Failed to remove password for user {UserId}: {Errors}", request.UserId, errors);
            return new ChangePasswordCommandResult(false, $"Đổi mật khẩu thất bại: {errors}");
        }

        var addResult = await _userManager.AddPasswordAsync(user, request.NewPassword);
        if (!addResult.Succeeded)
        {
            var errors = string.Join(", ", addResult.Errors.Select(e => e.Description));
            _logger.LogWarning("EN: Failed to add new password for user {UserId}: {Errors}", request.UserId, errors);
            return new ChangePasswordCommandResult(false, $"Đổi mật khẩu thất bại: {errors}");
        }

        _logger.LogInformation("EN: Password reset successfully for user {UserId}", request.UserId);
        return new ChangePasswordCommandResult(true, "Đổi mật khẩu thành công.");
    }
}
