namespace WalletService.API.Controllers;

using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using WalletService.API.Application.Commands;
using WalletService.API.Application.Queries;

/// <summary>
/// EN: Controller for wallet management operations
/// VI: Controller cho các thao tác quản lý ví
/// </summary>
[ApiController]
[Route("api/v1/[controller]")]
[Authorize]
[SwaggerTag("Wallet management endpoints / Các endpoint quản lý ví")]
public class WalletsController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<WalletsController> _logger;

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

    /// <summary>
    /// EN: Get wallet by user ID
    /// VI: Lấy ví theo user ID
    /// </summary>
    [HttpGet("{userId:guid}")]
    [SwaggerOperation(Summary = "Get wallet", Description = "Get wallet information by user ID")]
    [SwaggerResponse(200, "Success", typeof(ApiResponse<WalletDto>))]
    [SwaggerResponse(404, "Wallet not found")]
    public async Task<IActionResult> GetWallet(Guid userId)
    {
        var result = await _mediator.Send(new GetWalletQuery(userId));

        if (result == null)
            return NotFound(new ApiResponse<object>(false, "Wallet not found"));

        return Ok(new ApiResponse<WalletDto>(true, "Success", result));
    }

    /// <summary>
    /// EN: Create a new wallet
    /// VI: Tạo ví mới
    /// </summary>
    [HttpPost]
    [SwaggerOperation(Summary = "Create wallet", Description = "Create a new wallet for a user")]
    [SwaggerResponse(201, "Wallet created", typeof(ApiResponse<CreateWalletResult>))]
    [SwaggerResponse(400, "Invalid request")]
    [SwaggerResponse(409, "Wallet already exists")]
    public async Task<IActionResult> CreateWallet([FromBody] CreateWalletRequest request)
    {
        var command = new CreateWalletCommand(request.UserId, request.Currency ?? "VND");
        var result = await _mediator.Send(command);

        return CreatedAtAction(
            nameof(GetWallet),
            new { userId = result.UserId },
            new ApiResponse<CreateWalletResult>(true, "Wallet created", result));
    }

    /// <summary>
    /// EN: Deposit money into wallet
    /// VI: Nạp tiền vào ví
    /// </summary>
    [HttpPost("{userId:guid}/deposit")]
    [SwaggerOperation(Summary = "Deposit", Description = "Deposit money into wallet")]
    [SwaggerResponse(200, "Deposit successful", typeof(ApiResponse<TransactionResult>))]
    [SwaggerResponse(400, "Invalid request")]
    [SwaggerResponse(404, "Wallet not found")]
    public async Task<IActionResult> Deposit(Guid userId, [FromBody] DepositRequest request)
    {
        var command = new DepositCommand(userId, request.Amount, request.Description, request.ReferenceId);
        var result = await _mediator.Send(command);

        return Ok(new ApiResponse<TransactionResult>(true, "Deposit successful", result));
    }

    /// <summary>
    /// EN: Withdraw money from wallet
    /// VI: Rút tiền từ ví
    /// </summary>
    [HttpPost("{userId:guid}/withdraw")]
    [SwaggerOperation(Summary = "Withdraw", Description = "Withdraw money from wallet")]
    [SwaggerResponse(200, "Withdrawal successful", typeof(ApiResponse<TransactionResult>))]
    [SwaggerResponse(400, "Insufficient balance")]
    [SwaggerResponse(404, "Wallet not found")]
    public async Task<IActionResult> Withdraw(Guid userId, [FromBody] WithdrawRequest request)
    {
        var command = new WithdrawCommand(userId, request.Amount, request.Description, request.ReferenceId);
        var result = await _mediator.Send(command);

        return Ok(new ApiResponse<TransactionResult>(true, "Withdrawal successful", result));
    }

    /// <summary>
    /// EN: Get wallet transactions
    /// VI: Lấy lịch sử giao dịch ví
    /// </summary>
    [HttpGet("{userId:guid}/transactions")]
    [SwaggerOperation(Summary = "Get transactions", Description = "Get wallet transaction history")]
    [SwaggerResponse(200, "Success", typeof(ApiResponse<WalletTransactionsDto>))]
    [SwaggerResponse(404, "Wallet not found")]
    public async Task<IActionResult> GetTransactions(
        Guid userId,
        [FromQuery] int page = 1,
        [FromQuery] int pageSize = 20)
    {
        var query = new GetWalletTransactionsQuery(userId, page, pageSize);
        var result = await _mediator.Send(query);

        return Ok(new ApiResponse<WalletTransactionsDto>(true, "Success", result));
    }
}

#region Request DTOs

public record CreateWalletRequest(Guid UserId, string? Currency = "VND");
public record DepositRequest(decimal Amount, string Description, string? ReferenceId = null);
public record WithdrawRequest(decimal Amount, string Description, string? ReferenceId = null);

#endregion

#region API Response

public record ApiResponse<T>(bool Success, string Message, T? Data = default);

#endregion
