using ERPCore.Domain.Enums;
using ERPCore.Dtos.Common;
using ERPCore.Dtos.Stock;
using ERPCore.Services.Interfaces;
using Microsoft.AspNetCore.Mvc;

namespace ERPCore.Controllers;

/// <summary>Stock-transfer endpoints (docs/11 §5.4).</summary>
[Route("api/v1/stock-transfers")]
public sealed class StockTransfersController : ApiControllerBase
{
    private readonly ITransferService _transfers;

    public StockTransfersController(ITransferService transfers) => _transfers = transfers;

    /// <summary>List transfers, newest first.</summary>
    [HttpGet]
    [ProducesResponseType(typeof(PagedResponse<TransferSummaryDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<PagedResponse<TransferSummaryDto>>> List(
        [FromQuery] PageQuery query, [FromQuery] TransferStatus? status,
        [FromQuery] int? srcWarehouseId, [FromQuery] int? destWarehouseId, CancellationToken ct)
        => Ok(await _transfers.ListAsync(query, status, srcWarehouseId, destWarehouseId, ct));

    [HttpGet("{transferId:int}")]
    [ProducesResponseType(typeof(TransferDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<TransferDto>> GetById(int transferId, CancellationToken ct)
    {
        var dto = await _transfers.GetAsync(transferId, ct);
        return dto is null ? NotFound() : Ok(dto);
    }

    [HttpPost]
    [ProducesResponseType(typeof(TransferDto), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
    public async Task<ActionResult<TransferDto>> Create([FromBody] CreateTransferRequest request, CancellationToken ct)
    {
        var dto = await _transfers.CreateAsync(request, ct);
        return Created($"/api/v1/stock-transfers/{dto.TransferId}", dto);
    }

    /// <summary>Dispatch: consume source FIFO layers into in-transit. 409 STOCK_NEGATIVE_BLOCKED if short.</summary>
    [HttpPost("{transferId:int}/dispatch")]
    [ProducesResponseType(typeof(DispatchResultDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status409Conflict)]
    public async Task<ActionResult<DispatchResultDto>> Dispatch(int transferId, CancellationToken ct)
        => Ok(await _transfers.DispatchAsync(transferId, ct));

    /// <summary>Receive: create the destination layer at the inherited cost (cost-preserving).</summary>
    [HttpPost("{transferId:int}/receive")]
    [ProducesResponseType(typeof(ReceiveResultDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status409Conflict)]
    [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
    public async Task<ActionResult<ReceiveResultDto>> Receive(int transferId, [FromBody] ReceiveTransferRequest request, CancellationToken ct)
        => Ok(await _transfers.ReceiveAsync(transferId, request, ct));
}
