using AdsBillingService.API.Application.Commands;
using AdsBillingService.API.Application.Queries;
using MediatR;
using Microsoft.AspNetCore.Mvc;

namespace AdsBillingService.API.Controllers;

/// <summary>
/// EN: API Controller for managing billing accounts.
/// VI: API Controller quản lý tài khoản billing.
/// </summary>
[ApiController]
[Route("api/v1/ads-billing/accounts")]
[Produces("application/json")]
public class BillingAccountsController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<BillingAccountsController> _logger;

    public BillingAccountsController(IMediator mediator, ILogger<BillingAccountsController> logger)
    {
        _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    /// <summary>
    /// EN: Create a new billing account.
    /// VI: Tạo tài khoản billing mới.
    /// </summary>
    [HttpPost]
    [ProducesResponseType(StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<ActionResult<Guid>> CreateBillingAccount([FromBody] CreateBillingAccountCommand command)
    {
        _logger.LogInformation("Creating billing account for advertiser {AdvertiserId}", command.AdvertiserId);

        var accountId = await _mediator.Send(command);

        return CreatedAtAction(nameof(GetBillingAccount), new { id = accountId }, accountId);
    }

    /// <summary>
    /// EN: Get billing account by ID.
    /// VI: Lấy tài khoản billing theo ID.
    /// </summary>
    [HttpGet("{id}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetBillingAccount(Guid id)
    {
        _logger.LogInformation("Getting billing account {AccountId}", id);

        var query = new GetBillingAccountQuery(id);
        var account = await _mediator.Send(query);

        if (account == null)
        {
            return NotFound(new { message = $"Billing account {id} not found" });
        }

        return Ok(account);
    }

    /// <summary>
    /// EN: Add funds to billing account.
    /// VI: Nạp tiền vào tài khoản billing.
    /// </summary>
    [HttpPost("{id}/add-funds")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> AddFunds(Guid id, [FromBody] AddFundsRequest request)
    {
        _logger.LogInformation("Adding {Amount} funds to account {AccountId}", request.Amount, id);

        if (request.Amount <= 0)
        {
            return BadRequest(new { message = "Amount must be positive" });
        }

        var command = new AddFundsCommand(id, request.Amount);
        var success = await _mediator.Send(command);

        if (!success)
        {
            return NotFound(new { message = $"Billing account {id} not found" });
        }

        return Ok(new { accountId = id, amountAdded = request.Amount });
    }

    /// <summary>
    /// EN: Get billing account balance.
    /// VI: Lấy số dư tài khoản billing.
    /// </summary>
    [HttpGet("{id}/balance")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetBalance(Guid id)
    {
        _logger.LogInformation("Getting balance for account {AccountId}", id);

        var query = new GetBillingAccountBalanceQuery(id);
        var balance = await _mediator.Send(query);

        if (balance == null)
        {
            return NotFound(new { message = $"Billing account {id} not found" });
        }

        return Ok(new { accountId = id, balance = balance.Value });
    }
}

/// <summary>
/// EN: Request model for adding funds.
/// VI: Request model cho việc nạp tiền.
/// </summary>
public record AddFundsRequest(decimal Amount);
