using ERPCore.Dtos.Common;
using ERPCore.Dtos.Warehouses;
using ERPCore.Services.Interfaces;
using Microsoft.AspNetCore.Mvc;

namespace ERPCore.Controllers;

/// <summary>Warehouse &amp; bin endpoints (docs/11-BACKEND-PHASE1.md §2.5).</summary>
[Route("api/v1/warehouses")]
public sealed class WarehousesController : ApiControllerBase
{
    private readonly IWarehouseService _warehouses;

    public WarehousesController(IWarehouseService warehouses) => _warehouses = warehouses;

    [HttpGet]
    [ProducesResponseType(typeof(PagedResponse<WarehouseDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<PagedResponse<WarehouseDto>>> List([FromQuery] PageQuery query, CancellationToken ct)
        => Ok(await _warehouses.ListAsync(query, ct));

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

    [HttpPost]
    [ProducesResponseType(typeof(WarehouseDto), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status409Conflict)]
    public async Task<ActionResult<WarehouseDto>> Create([FromBody] CreateWarehouseRequest request, CancellationToken ct)
    {
        var dto = await _warehouses.CreateAsync(request, ct);
        return Created($"/api/v1/warehouses/{dto.WarehouseId}", dto);
    }

    [HttpGet("{warehouseId:int}/bins")]
    [ProducesResponseType(typeof(IReadOnlyList<BinDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<IReadOnlyList<BinDto>>> ListBins(int warehouseId, CancellationToken ct)
        => Ok(await _warehouses.ListBinsAsync(warehouseId, ct));

    [HttpPost("{warehouseId:int}/bins")]
    [ProducesResponseType(typeof(BinDto), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status409Conflict)]
    public async Task<ActionResult<BinDto>> CreateBin(int warehouseId, [FromBody] CreateBinRequest request, CancellationToken ct)
    {
        var dto = await _warehouses.CreateBinAsync(warehouseId, request, ct);
        return Created($"/api/v1/warehouses/{warehouseId}/bins/{dto.BinId}", dto);
    }
}
