// EN: Authentication controller with Duende IdentityServer integration.
// VI: Controller xác thực với Duende IdentityServer integration.

using System.Security.Claims;
using Asp.Versioning;
using Duende.IdentityServer;
using Duende.IdentityServer.Events;
using Duende.IdentityServer.Services;
using MediatR;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using IamService.API.Application.Commands.Auth;
using IamService.API.Application.Common;
using IamService.Domain.AggregatesModel.UserAggregate;

namespace IamService.API.Controllers;

/// <summary>
/// EN: Authentication controller with Duende IdentityServer integration.
/// VI: Controller xác thực với Duende IdentityServer integration.
/// </summary>
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/auth")]
[SwaggerTag("Authentication endpoints - OAuth2/OIDC")]
public class AuthController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly SignInManager<ApplicationUser> _signInManager;
    private readonly IIdentityServerInteractionService _interaction;
    private readonly IEventService _events;
    private readonly ILogger<AuthController> _logger;

    public AuthController(
        IMediator mediator,
        UserManager<ApplicationUser> userManager,
        SignInManager<ApplicationUser> signInManager,
        IIdentityServerInteractionService interaction,
        IEventService events,
        ILogger<AuthController> logger)
    {
        _mediator = mediator;
        _userManager = userManager;
        _signInManager = signInManager;
        _interaction = interaction;
        _events = events;
        _logger = logger;
    }

    /// <summary>
    /// EN: Register a new user.
    /// VI: Đăng ký user mới.
    /// </summary>
    /// <param name="command">User registration data</param>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>Registered user information</returns>
    [HttpPost("register")]
    [SwaggerOperation(
        Summary = "Register a new user",
        Description = "Creates a new user account with email and password.",
        OperationId = "RegisterUser")]
    [SwaggerResponse(StatusCodes.Status201Created, "User successfully registered", typeof(ApiResponse<RegisterUserCommandResult>))]
    [SwaggerResponse(StatusCodes.Status400BadRequest, "Invalid registration data")]
    [SwaggerResponse(StatusCodes.Status409Conflict, "User with this email already exists")]
    [ProducesResponseType(typeof(ApiResponse<RegisterUserCommandResult>), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status409Conflict)]
    public async Task<IActionResult> Register(
        [FromBody, SwaggerRequestBody("User registration details", Required = true)] RegisterUserCommand command,
        CancellationToken cancellationToken)
    {
        var result = await _mediator.Send(command, cancellationToken);
        return CreatedAtAction(nameof(Register), new { id = result.UserId }, ApiResponse<RegisterUserCommandResult>.Ok(result));
    }


    /// <summary>
    /// EN: Change user password.
    /// VI: Đổi mật khẩu user.
    /// </summary>
    /// <param name="request">Change password request data</param>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>Result of password change operation</returns>
    [HttpPost("change-password")]
    [Microsoft.AspNetCore.Authorization.Authorize(AuthenticationSchemes = "Bearer")]
    [SwaggerOperation(
        Summary = "Change password",
        Description = "Changes the password for the currently authenticated user. Requires current password verification.",
        OperationId = "ChangePassword")]
    [SwaggerResponse(StatusCodes.Status200OK, "Password changed successfully", typeof(ChangePasswordResponse))]
    [SwaggerResponse(StatusCodes.Status400BadRequest, "Invalid request (current password incorrect)")]
    [SwaggerResponse(StatusCodes.Status401Unauthorized, "Authentication required")]
    [ProducesResponseType(typeof(ChangePasswordResponse), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> ChangePassword(
        [FromBody, SwaggerRequestBody("Password change data", Required = true)] ChangePasswordRequest request,
        CancellationToken cancellationToken)
    {
        var userIdClaim = User.FindFirst("sub")?.Value ?? User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
        {
            return Unauthorized();
        }

        var command = new ChangePasswordCommand(userId, request.CurrentPassword, request.NewPassword);
        var result = await _mediator.Send(command, cancellationToken);

        if (!result.Success)
        {
            return BadRequest(new ChangePasswordResponse { Success = false, Message = result.Message });
        }

        return Ok(new ChangePasswordResponse { Success = true, Message = result.Message });
    }

    /// <summary>
    /// EN: Logout user and revoke tokens.
    /// VI: Logout user và thu hồi tokens.
    /// </summary>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>Result of logout operation</returns>
    [HttpPost("logout")]
    [Microsoft.AspNetCore.Authorization.Authorize(AuthenticationSchemes = "Bearer")]
    [SwaggerOperation(
        Summary = "Logout",
        Description = "Logs out the current user and revokes all associated tokens.",
        OperationId = "Logout")]
    [SwaggerResponse(StatusCodes.Status200OK, "User logged out successfully", typeof(LogoutResponse))]
    [SwaggerResponse(StatusCodes.Status401Unauthorized, "Authentication required")]
    [ProducesResponseType(typeof(LogoutResponse), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> Logout(CancellationToken cancellationToken)
    {
        var userIdClaim = User.FindFirst("sub")?.Value ?? User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
        {
            return Unauthorized();
        }

        var command = new LogoutCommand(userId);
        var result = await _mediator.Send(command, cancellationToken);

        await _signInManager.SignOutAsync();

        return Ok(new LogoutResponse { Success = result.Success, Message = result.Message });
    }

    #region Email Verification Endpoints

    /// <summary>
    /// EN: Send email verification link.
    /// VI: Gửi link xác thực email.
    /// </summary>
    /// <param name="request">Email address to verify</param>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>Result of sending verification email</returns>
    [HttpPost("send-verification-email")]
    [SwaggerOperation(
        Summary = "Send verification email",
        Description = "Sends an email verification link to the specified email address.",
        OperationId = "SendVerificationEmail")]
    [SwaggerResponse(StatusCodes.Status200OK, "Verification email sent")]
    [SwaggerResponse(StatusCodes.Status400BadRequest, "Invalid email")]
    [ProducesResponseType(typeof(ApiResponse<SendVerificationEmailResult>), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> SendVerificationEmail(
        [FromBody, SwaggerRequestBody("Email address", Required = true)] SendVerificationEmailRequest request,
        CancellationToken cancellationToken)
    {
        var command = new SendVerificationEmailCommand(request.Email);
        var result = await _mediator.Send(command, cancellationToken);
        return Ok(ApiResponse<SendVerificationEmailResult>.Ok(result));
    }

    /// <summary>
    /// EN: Confirm email with token.
    /// VI: Xác nhận email với token.
    /// </summary>
    /// <param name="request">Email and token</param>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>Result of email confirmation</returns>
    [HttpPost("confirm-email")]
    [SwaggerOperation(
        Summary = "Confirm email",
        Description = "Confirms user email with the provided token.",
        OperationId = "ConfirmEmail")]
    [SwaggerResponse(StatusCodes.Status200OK, "Email confirmed successfully")]
    [SwaggerResponse(StatusCodes.Status400BadRequest, "Invalid or expired token")]
    [ProducesResponseType(typeof(ApiResponse<ConfirmEmailResult>), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> ConfirmEmail(
        [FromBody, SwaggerRequestBody("Email and token", Required = true)] ConfirmEmailRequest request,
        CancellationToken cancellationToken)
    {
        var command = new ConfirmEmailCommand(request.Email, request.Token);
        var result = await _mediator.Send(command, cancellationToken);

        if (!result.Success)
        {
            return BadRequest(ApiResponse<ConfirmEmailResult>.Fail("INVALID_TOKEN", result.Message));
        }

        return Ok(ApiResponse<ConfirmEmailResult>.Ok(result));
    }

    #endregion

    #region Two-Factor Authentication Endpoints

    /// <summary>
    /// EN: Enable 2FA for current user.
    /// VI: Bật 2FA cho user hiện tại.
    /// </summary>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>QR code and recovery codes</returns>
    [HttpPost("2fa/enable")]
    [Microsoft.AspNetCore.Authorization.Authorize(AuthenticationSchemes = "Bearer")]
    [SwaggerOperation(
        Summary = "Enable 2FA",
        Description = "Initiates 2FA setup. Returns QR code and recovery codes. Must be verified with /2fa/verify.",
        OperationId = "Enable2FA")]
    [SwaggerResponse(StatusCodes.Status200OK, "2FA setup initiated", typeof(Enable2FAResponse))]
    [SwaggerResponse(StatusCodes.Status401Unauthorized, "Authentication required")]
    [SwaggerResponse(StatusCodes.Status400BadRequest, "2FA already enabled")]
    [ProducesResponseType(typeof(ApiResponse<Enable2FAResponse>), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> Enable2FA(CancellationToken cancellationToken)
    {
        var userIdClaim = User.FindFirst("sub")?.Value ?? User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
        {
            return Unauthorized();
        }

        try
        {
            var command = new Enable2FACommand(userId);
            var result = await _mediator.Send(command, cancellationToken);

            return Ok(ApiResponse<Enable2FAResponse>.Ok(new Enable2FAResponse
            {
                QrCodeBase64 = result.QrCodeBase64,
                ManualEntryKey = result.ManualEntryKey,
                RecoveryCodes = result.RecoveryCodes
            }));
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(ApiResponse<Enable2FAResponse>.Fail("2FA_ALREADY_ENABLED", ex.Message));
        }
    }

    /// <summary>
    /// EN: Verify 2FA code and complete setup.
    /// VI: Xác minh mã 2FA và hoàn tất cài đặt.
    /// </summary>
    /// <param name="request">2FA verification code</param>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>Result of 2FA verification</returns>
    [HttpPost("2fa/verify")]
    [Microsoft.AspNetCore.Authorization.Authorize(AuthenticationSchemes = "Bearer")]
    [SwaggerOperation(
        Summary = "Verify 2FA code",
        Description = "Verifies the TOTP code and completes 2FA setup.",
        OperationId = "Verify2FA")]
    [SwaggerResponse(StatusCodes.Status200OK, "2FA enabled successfully")]
    [SwaggerResponse(StatusCodes.Status400BadRequest, "Invalid code")]
    [SwaggerResponse(StatusCodes.Status401Unauthorized, "Authentication required")]
    [ProducesResponseType(typeof(ApiResponse<Verify2FAResult>), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> Verify2FA(
        [FromBody, SwaggerRequestBody("2FA code", Required = true)] Verify2FARequest request,
        CancellationToken cancellationToken)
    {
        var userIdClaim = User.FindFirst("sub")?.Value ?? User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
        {
            return Unauthorized();
        }

        var command = new Verify2FACommand(userId, request.Code);
        var result = await _mediator.Send(command, cancellationToken);

        if (!result.Success)
        {
            return BadRequest(ApiResponse<Verify2FAResult>.Fail("INVALID_CODE", result.Message));
        }

        return Ok(ApiResponse<Verify2FAResult>.Ok(result));
    }

    /// <summary>
    /// EN: Disable 2FA for current user.
    /// VI: Tắt 2FA cho user hiện tại.
    /// </summary>
    /// <param name="request">Current 2FA code for verification</param>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>Result of disabling 2FA</returns>
    [HttpPost("2fa/disable")]
    [Microsoft.AspNetCore.Authorization.Authorize(AuthenticationSchemes = "Bearer")]
    [SwaggerOperation(
        Summary = "Disable 2FA",
        Description = "Disables 2FA for the current user. Requires verification with current 2FA code.",
        OperationId = "Disable2FA")]
    [SwaggerResponse(StatusCodes.Status200OK, "2FA disabled successfully")]
    [SwaggerResponse(StatusCodes.Status400BadRequest, "Invalid code or 2FA not enabled")]
    [SwaggerResponse(StatusCodes.Status401Unauthorized, "Authentication required")]
    [ProducesResponseType(typeof(ApiResponse<Disable2FAResult>), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> Disable2FA(
        [FromBody, SwaggerRequestBody("2FA code", Required = true)] Disable2FARequest request,
        CancellationToken cancellationToken)
    {
        var userIdClaim = User.FindFirst("sub")?.Value ?? User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
        {
            return Unauthorized();
        }

        var command = new Disable2FACommand(userId, request.Code);
        var result = await _mediator.Send(command, cancellationToken);

        if (!result.Success)
        {
            return BadRequest(ApiResponse<Disable2FAResult>.Fail("DISABLE_FAILED", result.Message));
        }

        return Ok(ApiResponse<Disable2FAResult>.Ok(result));
    }

    #endregion

    #region Social Login Endpoints

    /// <summary>
    /// EN: Initiate external login with Google or Facebook.
    /// VI: Bắt đầu đăng nhập bên ngoài với Google hoặc Facebook.
    /// </summary>
    /// <param name="provider">Provider name (Google, Facebook)</param>
    /// <param name="returnUrl">URL to redirect after login</param>
    /// <returns>Challenge result for external provider</returns>
    [HttpGet("external-login/{provider}")]
    [SwaggerOperation(
        Summary = "Initiate external login",
        Description = "Redirects user to external OAuth provider (Google or Facebook) for authentication.",
        OperationId = "ExternalLogin")]
    [SwaggerResponse(StatusCodes.Status302Found, "Redirecting to external provider")]
    [SwaggerResponse(StatusCodes.Status400BadRequest, "Invalid provider")]
    public IActionResult ExternalLogin(
        [FromRoute] string provider,
        [FromQuery] string? returnUrl = null)
    {
        var validProviders = new[] { "Google", "Facebook" };
        if (!validProviders.Contains(provider, StringComparer.OrdinalIgnoreCase))
        {
            return BadRequest(ApiResponse<object>.Fail("INVALID_PROVIDER", $"Provider '{provider}' is not supported. Valid providers: Google, Facebook"));
        }

        var redirectUrl = Url.Action(nameof(ExternalLoginCallback), "Auth", new { returnUrl });
        var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);

        return Challenge(properties, provider);
    }

    /// <summary>
    /// EN: Handle callback from external OAuth provider.
    /// VI: Xử lý callback từ OAuth provider bên ngoài.
    /// </summary>
    /// <param name="returnUrl">URL to redirect after login</param>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>External login result with tokens</returns>
    [HttpGet("external-callback")]
    [SwaggerOperation(
        Summary = "External login callback",
        Description = "Handles callback from Google/Facebook OAuth. Creates or links user account.",
        OperationId = "ExternalLoginCallback")]
    [SwaggerResponse(StatusCodes.Status200OK, "Login successful", typeof(ExternalLoginResult))]
    [SwaggerResponse(StatusCodes.Status400BadRequest, "External login failed")]
    public async Task<IActionResult> ExternalLoginCallback(
        [FromQuery] string? returnUrl = null,
        CancellationToken cancellationToken = default)
    {
        var info = await _signInManager.GetExternalLoginInfoAsync();
        if (info == null)
        {
            _logger.LogWarning("EN: External login info is null / VI: External login info là null");
            return BadRequest(ApiResponse<ExternalLoginResult>.Fail("EXTERNAL_LOGIN_FAILED", "Could not get external login information"));
        }

        // EN: Extract user information from claims
        // VI: Trích xuất thông tin user từ claims
        var email = info.Principal.FindFirstValue(ClaimTypes.Email);
        var name = info.Principal.FindFirstValue(ClaimTypes.Name);
        var pictureUrl = info.Principal.FindFirstValue("picture");

        if (string.IsNullOrEmpty(email))
        {
            return BadRequest(ApiResponse<ExternalLoginResult>.Fail("EMAIL_REQUIRED", "Email is required for external login"));
        }

        var command = new ExternalLoginCommand(
            info.LoginProvider,
            info.ProviderKey,
            email,
            name,
            pictureUrl);

        var result = await _mediator.Send(command, cancellationToken);

        if (!result.Success)
        {
            return BadRequest(ApiResponse<ExternalLoginResult>.Fail("EXTERNAL_LOGIN_FAILED", result.Message));
        }

        // EN: If returnUrl is specified, redirect to it with user info as query params
        // VI: Nếu có returnUrl, redirect tới đó với thông tin user dưới dạng query params
        if (!string.IsNullOrEmpty(returnUrl))
        {
            var redirectUrl = $"{returnUrl}?userId={result.UserId}&email={result.Email}&isNewUser={result.IsNewUser}";
            return Redirect(redirectUrl);
        }

        return Ok(ApiResponse<ExternalLoginResult>.Ok(result));
    }

    /// <summary>
    /// EN: Get linked external accounts for current user.
    /// VI: Lấy danh sách tài khoản bên ngoài đã liên kết của user hiện tại.
    /// </summary>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>List of linked providers</returns>
    [HttpGet("linked-accounts")]
    [Microsoft.AspNetCore.Authorization.Authorize(AuthenticationSchemes = "Bearer")]
    [SwaggerOperation(
        Summary = "Get linked accounts",
        Description = "Returns list of external OAuth providers linked to current user's account.",
        OperationId = "GetLinkedAccounts")]
    [SwaggerResponse(StatusCodes.Status200OK, "Linked accounts retrieved")]
    [SwaggerResponse(StatusCodes.Status401Unauthorized, "Authentication required")]
    [ProducesResponseType(typeof(ApiResponse<LinkedAccountsResponse>), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> GetLinkedAccounts(CancellationToken cancellationToken)
    {
        var userIdClaim = User.FindFirst("sub")?.Value ?? User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
        {
            return Unauthorized();
        }

        var user = await _userManager.FindByIdAsync(userId.ToString());
        if (user == null)
        {
            return Unauthorized();
        }

        var logins = await _userManager.GetLoginsAsync(user);
        var providers = logins.Select(l => new LinkedAccountInfo
        {
            Provider = l.LoginProvider,
            ProviderDisplayName = l.ProviderDisplayName ?? l.LoginProvider
        }).ToList();

        return Ok(ApiResponse<LinkedAccountsResponse>.Ok(new LinkedAccountsResponse
        {
            LinkedProviders = providers
        }));
    }

    #endregion
}

#region Request/Response Models

/// <summary>
/// EN: Request body for changing password.
/// VI: Request body để đổi mật khẩu.
/// </summary>
public class ChangePasswordRequest
{
    /// <summary>
    /// EN: Current password.
    /// VI: Mật khẩu hiện tại.
    /// </summary>
    /// <example>OldPassword123!</example>
    public string CurrentPassword { get; set; } = string.Empty;

    /// <summary>
    /// EN: New password.
    /// VI: Mật khẩu mới.
    /// </summary>
    /// <example>NewPassword456!</example>
    public string NewPassword { get; set; } = string.Empty;
}

/// <summary>
/// EN: Response for change password operation.
/// VI: Response cho thao tác đổi mật khẩu.
/// </summary>
public class ChangePasswordResponse
{
    /// <summary>
    /// EN: Whether the operation was successful.
    /// VI: Thao tác có thành công không.
    /// </summary>
    public bool Success { get; set; }

    /// <summary>
    /// EN: Result message.
    /// VI: Thông điệp kết quả.
    /// </summary>
    public string Message { get; set; } = string.Empty;
}

/// <summary>
/// EN: Response for logout operation.
/// VI: Response cho thao tác logout.
/// </summary>
public class LogoutResponse
{
    /// <summary>
    /// EN: Whether the operation was successful.
    /// VI: Thao tác có thành công không.
    /// </summary>
    public bool Success { get; set; }

    /// <summary>
    /// EN: Result message.
    /// VI: Thông điệp kết quả.
    /// </summary>
    public string Message { get; set; } = string.Empty;
}

#endregion

#region Email Verification Request/Response Models

/// <summary>
/// EN: Request body for sending verification email.
/// VI: Request body để gửi email xác thực.
/// </summary>
public class SendVerificationEmailRequest
{
    /// <summary>
    /// EN: Email address to verify.
    /// VI: Địa chỉ email cần xác thực.
    /// </summary>
    /// <example>user@example.com</example>
    public string Email { get; set; } = string.Empty;
}

/// <summary>
/// EN: Request body for confirming email.
/// VI: Request body để xác nhận email.
/// </summary>
public class ConfirmEmailRequest
{
    /// <summary>
    /// EN: Email address.
    /// VI: Địa chỉ email.
    /// </summary>
    /// <example>user@example.com</example>
    public string Email { get; set; } = string.Empty;

    /// <summary>
    /// EN: Verification token from email.
    /// VI: Token xác thực từ email.
    /// </summary>
    public string Token { get; set; } = string.Empty;
}

#endregion

#region 2FA Request/Response Models

/// <summary>
/// EN: Response for enabling 2FA.
/// VI: Response cho việc bật 2FA.
/// </summary>
public class Enable2FAResponse
{
    /// <summary>
    /// EN: QR code as base64 image.
    /// VI: QR code dạng ảnh base64.
    /// </summary>
    public string QrCodeBase64 { get; set; } = string.Empty;

    /// <summary>
    /// EN: Manual entry key for authenticator apps.
    /// VI: Key nhập thủ công cho ứng dụng authenticator.
    /// </summary>
    public string ManualEntryKey { get; set; } = string.Empty;

    /// <summary>
    /// EN: Recovery codes for account recovery.
    /// VI: Mã khôi phục cho tài khoản.
    /// </summary>
    public string[] RecoveryCodes { get; set; } = Array.Empty<string>();
}

/// <summary>
/// EN: Request body for 2FA verification.
/// VI: Request body cho xác minh 2FA.
/// </summary>
public class Verify2FARequest
{
    /// <summary>
    /// EN: TOTP code from authenticator app.
    /// VI: Mã TOTP từ ứng dụng authenticator.
    /// </summary>
    /// <example>123456</example>
    public string Code { get; set; } = string.Empty;
}

/// <summary>
/// EN: Request body for disabling 2FA.
/// VI: Request body cho việc tắt 2FA.
/// </summary>
public class Disable2FARequest
{
    /// <summary>
    /// EN: Current TOTP code for verification.
    /// VI: Mã TOTP hiện tại để xác minh.
    /// </summary>
    /// <example>123456</example>
    public string Code { get; set; } = string.Empty;
}

#endregion

#region Social Login Request/Response Models

/// <summary>
/// EN: Response for linked accounts.
/// VI: Response cho các tài khoản đã liên kết.
/// </summary>
public class LinkedAccountsResponse
{
    /// <summary>
    /// EN: List of linked OAuth providers.
    /// VI: Danh sách các OAuth providers đã liên kết.
    /// </summary>
    public List<LinkedAccountInfo> LinkedProviders { get; set; } = new();
}

/// <summary>
/// EN: Information about a linked account.
/// VI: Thông tin về tài khoản đã liên kết.
/// </summary>
public class LinkedAccountInfo
{
    /// <summary>
    /// EN: Provider name (Google, Facebook).
    /// VI: Tên provider (Google, Facebook).
    /// </summary>
    public string Provider { get; set; } = string.Empty;

    /// <summary>
    /// EN: Display name of the provider.
    /// VI: Tên hiển thị của provider.
    /// </summary>
    public string ProviderDisplayName { get; set; } = string.Empty;
}

#endregion
