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

namespace ERPCore.Controllers;

/// <summary>Stock enquiry, ledger, valuation and reorder-alert endpoints (docs/11 §5.1–5.3, §5.7).</summary>
[Route("api/v1/stock")]
public sealed class StockController : ApiControllerBase
{
    private readonly IStockService _stock;
    private readonly IReorderService _reorder;

    public StockController(IStockService stock, IReorderService reorder)
    {
        _stock = stock;
        _reorder = reorder;
    }

    [HttpGet("on-hand")]
    [ProducesResponseType(typeof(StockOnHandDto), StatusCodes.Status200OK)]
    public async Task<ActionResult<StockOnHandDto>> OnHand([FromQuery] int itemId, [FromQuery] int warehouseId, CancellationToken ct)
        => Ok(await _stock.GetOnHandAsync(itemId, warehouseId, ct));

    /// <summary>On-hand across every stocked (item, warehouse) pair; both filters optional.</summary>
    [HttpGet("on-hand/list")]
    [ProducesResponseType(typeof(PagedResponse<StockOnHandDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<PagedResponse<StockOnHandDto>>> OnHandList(
        [FromQuery] int? itemId, [FromQuery] int? warehouseId, [FromQuery] PageQuery query, CancellationToken ct)
        => Ok(await _stock.GetOnHandListAsync(itemId, warehouseId, query, ct));

    /// <summary>
    /// Immutable movement history. <c>sourceDocType</c>/<c>sourceDocId</c> answer "what did
    /// this document post?" — the ledger's document reference is polymorphic, so there is
    /// no FK to navigate instead (docs/10 C.9).
    /// </summary>
    [HttpGet("ledger")]
    [ProducesResponseType(typeof(PagedResponse<StockLedgerRowDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<PagedResponse<StockLedgerRowDto>>> Ledger(
        [FromQuery] int? itemId, [FromQuery] int? warehouseId,
        [FromQuery] DateOnly? from, [FromQuery] DateOnly? to,
        [FromQuery] string? sourceDocType, [FromQuery] int? sourceDocId,
        [FromQuery] PageQuery query, CancellationToken ct)
        => Ok(await _stock.GetLedgerAsync(itemId, warehouseId, from, to, sourceDocType, sourceDocId, query, ct));

    [HttpGet("valuation")]
    [ProducesResponseType(typeof(StockValuationDto), StatusCodes.Status200OK)]
    public async Task<ActionResult<StockValuationDto>> Valuation([FromQuery] int itemId, [FromQuery] int warehouseId, CancellationToken ct)
        => Ok(await _stock.GetValuationAsync(itemId, warehouseId, ct));

    /// <summary>Items at/below their reorder point (FR-STK-10), computed on read.</summary>
    [HttpGet("reorder-alerts")]
    [ProducesResponseType(typeof(PagedResponse<ReorderAlertDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<PagedResponse<ReorderAlertDto>>> ReorderAlerts(
        [FromQuery] int? warehouseId, [FromQuery] PageQuery query, CancellationToken ct)
        => Ok(await _reorder.GetAlertsAsync(warehouseId, query, ct));

    /// <summary>Create a draft requisition for an item's suggested reorder quantity.</summary>
    [HttpPost("reorder-alerts/{itemId:int}/requisition")]
    [ProducesResponseType(typeof(RequisitionDto), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
    public async Task<ActionResult<RequisitionDto>> SuggestRequisition(
        int itemId, [FromQuery] int warehouseId, CancellationToken ct)
    {
        var dto = await _reorder.CreateSuggestedRequisitionAsync(itemId, warehouseId, ct);
        return Created($"/api/v1/requisitions/{dto.RequisitionId}", dto);
    }
}
