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

namespace DoliMiddlewareApi.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class SupplierInvoicesController(SupplierInvoiceService service) : ControllerBase
{
    [HttpGet]
    [ProducesResponseType(typeof(List<SupplierInvoiceDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<ActionResult<List<SupplierInvoiceDto>>> GetInvoices(
        [FromQuery] int limit = 50,
        [FromQuery] [Range(1, int.MaxValue)] int page = 1,
        [FromQuery] string? status = null)
    {
        var invoices = await service.GetInvoicesAsync(limit, page, status);
        return Ok(invoices);
    }

    [HttpPost]
    [ProducesResponseType(typeof(int), StatusCodes.Status201Created)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<ActionResult<int>> CreateInvoice([FromBody] CreateSupplierInvoiceDto dto)
    {
        var id = await service.CreateInvoiceAsync(dto);
        return CreatedAtAction(nameof(GetInvoice), new { id }, id);
    }

    [HttpGet("{id:int}")]
    [ProducesResponseType(typeof(SupplierInvoiceDetailDto), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<ActionResult<SupplierInvoiceDetailDto>> GetInvoice([Range(1, int.MaxValue)] int id)
    {
        var invoice = await service.GetInvoiceAsync(id);
        return Ok(invoice);
    }

    [HttpPut("{id:int}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> UpdateInvoice([Range(1, int.MaxValue)] int id, [FromBody] UpdateSupplierInvoiceDto dto)
    {
        await service.UpdateInvoiceAsync(id, dto);
        return NoContent();
    }

    [HttpDelete("{id:int}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status403Forbidden)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> DeleteInvoice([Range(1, int.MaxValue)] int id)
    {
        await service.DeleteInvoiceAsync(id);
        return NoContent();
    }

    [HttpPost("{id:int}/status")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> ChangeStatus([Range(1, int.MaxValue)] int id, [FromBody] UpdateInvoiceStatusDto dto)
    {
        await service.ChangeStatusAsync(id, dto.Status);
        return NoContent();
    }

    [HttpPost("{id:int}/lines")]
    [ProducesResponseType(typeof(string), StatusCodes.Status201Created)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status403Forbidden)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<ActionResult<string>> AddLine([Range(1, int.MaxValue)] int id, [FromBody] CreateInvoiceLineDto dto)
    {
        var result = await service.AddLineAsync(id, dto);
        return StatusCode(StatusCodes.Status201Created, result);
    }

    [HttpPut("{id:int}/lines/{lineId:int}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status403Forbidden)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> UpdateLine([Range(1, int.MaxValue)] int id, [Range(1, int.MaxValue)] int lineId, [FromBody] UpdateInvoiceLineDto dto)
    {
        await service.UpdateLineAsync(id, lineId, dto);
        return NoContent();
    }

    [HttpDelete("{id:int}/lines/{lineId:int}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status403Forbidden)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> DeleteLine([Range(1, int.MaxValue)] int id, [Range(1, int.MaxValue)] int lineId)
    {
        await service.DeleteLineAsync(id, lineId);
        return NoContent();
    }

    [HttpGet("{id:int}/payments")]
    [ProducesResponseType(typeof(List<InvoicePaymentDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<ActionResult<List<InvoicePaymentDto>>> GetPayments([Range(1, int.MaxValue)] int id)
    {
        var payments = await service.GetPaymentsAsync(id);
        return Ok(payments);
    }

    [HttpPost("{id:int}/payments")]
    [ProducesResponseType(typeof(int), StatusCodes.Status201Created)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)]
    public async Task<ActionResult<int>> AddPayment([Range(1, int.MaxValue)] int id, [FromBody] CreateInvoicePaymentDto dto)
    {
        var paymentId = await service.AddPaymentAsync(id, dto);
        return StatusCode(StatusCodes.Status201Created, paymentId);
    }
}
