using System.ComponentModel.DataAnnotations;
using DoliMiddlewareApi.Dtos.command;
using DoliMiddlewareApi.Dtos.query;
using DoliMiddlewareApi.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace DoliMiddlewareApi.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class BankController(BankService bankService) : ControllerBase
{
    [HttpGet("accounts")]
    [ProducesResponseType(typeof(List<BankAccountDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<ActionResult<List<BankAccountDto>>> GetAccounts()
    {
        var accounts = await bankService.GetAccountsAsync();
        return Ok(accounts);
    }

    [HttpGet("accounts/{id:int}")]
    [ProducesResponseType(typeof(BankAccountDto), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<ActionResult<BankAccountDto>> GetAccount([Range(1, int.MaxValue)] int id)
    {
        var account = await bankService.GetAccountAsync(id);
        return Ok(account);
    }

    [HttpGet("accounts/{id:int}/balance")]
    [ProducesResponseType(typeof(double), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<ActionResult<double>> GetBalance([Range(1, int.MaxValue)] int id)
    {
        var balance = await bankService.GetBalanceAsync(id);
        return Ok(balance);
    }

    [HttpGet("accounts/{id:int}/lines")]
    [ProducesResponseType(typeof(List<BankLineDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<ActionResult<List<BankLineDto>>> GetAccountLines([Range(1, int.MaxValue)] int id)
    {
        var lines = await bankService.GetAccountLinesAsync(id);
        return Ok(lines);
    }

    [HttpGet("movements")]
    [ProducesResponseType(typeof(List<BankLineDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<ActionResult<List<BankLineDto>>> GetMovements([FromQuery] int limit = 20)
    {
        var movements = await bankService.GetMovementsAsync(limit);
        return Ok(movements);
    }

    [HttpPut("accounts/{id:int}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> UpdateAccount([Range(1, int.MaxValue)] int id, [FromBody] UpdateBankAccountDto dto)
    {
        await bankService.UpdateAccountAsync(id, dto);
        return NoContent();
    }

    [HttpPost("accounts")]
    [ProducesResponseType(typeof(int), StatusCodes.Status201Created)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<ActionResult<int>> CreateAccount([FromBody] CreateBankAccountDto dto)
    {
        var id = await bankService.CreateAccountAsync(dto);
        return CreatedAtAction(nameof(GetAccount), new { id }, id);
    }
}
