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

namespace ERPCore.Controllers;

/// <summary>Item master endpoints (docs/11-BACKEND-PHASE1.md §2.1–2.2).</summary>
[Route("api/v1/items")]
public sealed class ItemsController : ApiControllerBase
{
    private readonly IItemService _items;

    public ItemsController(IItemService items) => _items = items;

    /// <summary>List items with optional filters and paging.</summary>
    [HttpGet]
    [ProducesResponseType(typeof(PagedResponse<ItemListItemDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<PagedResponse<ItemListItemDto>>> List(
        [FromQuery] PageQuery query,
        [FromQuery] EntityStatus? status,
        [FromQuery] int? categoryId,
        [FromQuery] int? subCategoryId,
        [FromQuery] int? brandId,
        [FromQuery] TrackingMode? trackingMode,
        CancellationToken ct)
        => Ok(await _items.ListAsync(query, status, categoryId, subCategoryId, brandId, trackingMode, ct));

    /// <summary>Get a single item; returns an <c>ETag</c> for optimistic concurrency.</summary>
    [HttpGet("{itemId:int}")]
    [ProducesResponseType(typeof(ItemDetailDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<ItemDetailDto>> GetById(int itemId, CancellationToken ct)
    {
        var result = await _items.GetAsync(itemId, ct);
        if (result is null) return NotFound();

        SetETag(result.RowVersion);
        return Ok(result.Value);
    }

    /// <summary>Create an item (SKU unique). Server sets status and timestamps.</summary>
    [HttpPost]
    [ProducesResponseType(typeof(ItemDetailDto), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
    public async Task<ActionResult<ItemDetailDto>> Create([FromBody] CreateItemRequest request, CancellationToken ct)
    {
        var result = await _items.CreateAsync(request, ct);
        SetETag(result.RowVersion);
        return Created($"/api/v1/items/{result.Value.ItemId}", result.Value);
    }

    /// <summary>Full update; requires <c>If-Match</c> (412 on stale ETag).</summary>
    [HttpPut("{itemId:int}")]
    [ProducesResponseType(typeof(ItemDetailDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status412PreconditionFailed)]
    public async Task<ActionResult<ItemDetailDto>> Update(int itemId, [FromBody] UpdateItemRequest request, CancellationToken ct)
    {
        var expected = RequireIfMatch();
        var result = await _items.UpdateAsync(itemId, request, expected, ct);
        SetETag(result.RowVersion);
        return Ok(result.Value);
    }

    /// <summary>Activate / deactivate the item (FR-MD-08 — deactivate, not delete).</summary>
    [HttpPatch("{itemId:int}/status")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> SetStatus(int itemId, [FromBody] UpdateItemStatusRequest request, CancellationToken ct)
    {
        await _items.SetStatusAsync(itemId, request.Status, ct);
        return NoContent();
    }

    /// <summary>Replace the item's per-warehouse reorder settings (FR-MD-05).</summary>
    [HttpPut("{itemId:int}/reorder")]
    [ProducesResponseType(typeof(ItemReorderSettingsDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<ItemReorderSettingsDto>> UpdateReorder(int itemId, [FromBody] UpdateReorderRequest request, CancellationToken ct)
        => Ok(await _items.UpdateReorderAsync(itemId, request, ct));
}
