using Asp.Versioning;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using IamService.API.Application.Common;
using IamService.API.Application.Commands.Verifications;

namespace IamService.API.Controllers;

/// <summary>
/// EN: Identity verification controller.
/// VI: Controller xác thực danh tính.
/// </summary>
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/verifications")]
[Authorize(AuthenticationSchemes = "Bearer")]
[Authorize(Policy = "RequireAdmin")]
[SwaggerTag("Identity verification endpoints - requires Admin role")]
public class VerificationsController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<VerificationsController> _logger;

    public VerificationsController(
        IMediator mediator,
        ILogger<VerificationsController> logger)
    {
        _mediator = mediator;
        _logger = logger;
    }

    /// <summary>
    /// EN: Request phone verification.
    /// VI: Yêu cầu xác thực số điện thoại.
    /// </summary>
    [HttpPost("phone")]
    [SwaggerOperation(Summary = "Request phone verification", OperationId = "RequestPhoneVerification")]
    [SwaggerResponse(StatusCodes.Status200OK, "Verification requested", typeof(ApiResponse<VerificationResponse>))]
    [SwaggerResponse(StatusCodes.Status400BadRequest, "Active verification exists")]
    public async Task<IActionResult> RequestPhoneVerification(
        [FromBody] PhoneVerificationRequest request,
        CancellationToken cancellationToken = default)
    {
        try
        {
            var command = new RequestPhoneVerificationCommand(request.UserId, request.PhoneNumber);
            var result = await _mediator.Send(command, cancellationToken);

            return Ok(ApiResponse<VerificationResponse>.Ok(new VerificationResponse
            {
                VerificationId = result.VerificationId,
                VerificationType = result.VerificationType,
                ExpiresAt = result.ExpiresAt,
                Message = result.Message
            }));
        }
        catch (Exception ex) when (ex.Message.Contains("pending"))
        {
            return BadRequest(ApiResponse<VerificationResponse>.Fail("VERIFICATION_PENDING", ex.Message));
        }
    }

    /// <summary>
    /// EN: Request email verification.
    /// VI: Yêu cầu xác thực email.
    /// </summary>
    [HttpPost("email")]
    [SwaggerOperation(Summary = "Request email verification", OperationId = "RequestEmailVerification")]
    [SwaggerResponse(StatusCodes.Status200OK, "Verification requested", typeof(ApiResponse<VerificationResponse>))]
    [SwaggerResponse(StatusCodes.Status400BadRequest, "Active verification exists")]
    public async Task<IActionResult> RequestEmailVerification(
        [FromBody] EmailVerificationRequest request,
        CancellationToken cancellationToken = default)
    {
        try
        {
            var command = new RequestEmailVerificationCommand(request.UserId, request.Email);
            var result = await _mediator.Send(command, cancellationToken);

            return Ok(ApiResponse<VerificationResponse>.Ok(new VerificationResponse
            {
                VerificationId = result.VerificationId,
                VerificationType = result.VerificationType,
                ExpiresAt = result.ExpiresAt,
                Message = result.Message
            }));
        }
        catch (Exception ex) when (ex.Message.Contains("pending"))
        {
            return BadRequest(ApiResponse<VerificationResponse>.Fail("VERIFICATION_PENDING", ex.Message));
        }
    }

    /// <summary>
    /// EN: Confirm verification with code.
    /// VI: Xác nhận verification với mã.
    /// </summary>
    [HttpPost("{id:guid}/confirm")]
    [SwaggerOperation(Summary = "Confirm verification", OperationId = "ConfirmVerification")]
    [SwaggerResponse(StatusCodes.Status200OK, "Verification result", typeof(ApiResponse<ConfirmVerificationResponse>))]
    [SwaggerResponse(StatusCodes.Status404NotFound, "Verification not found")]
    public async Task<IActionResult> ConfirmVerification(
        [FromRoute] Guid id,
        [FromBody] ConfirmVerificationRequest request,
        CancellationToken cancellationToken = default)
    {
        try
        {
            var command = new ConfirmVerificationCommand(id, request.Code);
            var result = await _mediator.Send(command, cancellationToken);

            return Ok(ApiResponse<ConfirmVerificationResponse>.Ok(new ConfirmVerificationResponse
            {
                VerificationId = result.VerificationId,
                IsVerified = result.IsVerified,
                Status = result.Status,
                VerifiedAt = result.VerifiedAt
            }));
        }
        catch (Exception ex) when (ex.Message.Contains("not found"))
        {
            return NotFound(ApiResponse<ConfirmVerificationResponse>.Fail("VERIFICATION_NOT_FOUND", ex.Message));
        }
    }
}

#region Request/Response Models

public class PhoneVerificationRequest
{
    public Guid UserId { get; set; }
    /// <example>+84912345678</example>
    public string PhoneNumber { get; set; } = string.Empty;
}

public class EmailVerificationRequest
{
    public Guid UserId { get; set; }
    /// <example>user@example.com</example>
    public string Email { get; set; } = string.Empty;
}

public class ConfirmVerificationRequest
{
    /// <example>123456</example>
    public string Code { get; set; } = string.Empty;
}

public class VerificationResponse
{
    public Guid VerificationId { get; set; }
    public string VerificationType { get; set; } = string.Empty;
    public DateTime ExpiresAt { get; set; }
    public string Message { get; set; } = string.Empty;
}

public class ConfirmVerificationResponse
{
    public Guid VerificationId { get; set; }
    public bool IsVerified { get; set; }
    public string Status { get; set; } = string.Empty;
    public DateTime? VerifiedAt { get; set; }
}

#endregion
