using ERPCore.Dtos.Categories;
using ERPCore.Services.Interfaces;
using Microsoft.AspNetCore.Mvc;

namespace ERPCore.Controllers;

/// <summary>
/// Subcategory endpoints addressed by their own id (docs/11-BACKEND-PHASE1.md §2.3).
/// Listing and creation live under the parent category on <see cref="CategoriesController"/>,
/// since a subcategory only exists in the context of one.
/// </summary>
[Route("api/v1/subcategories")]
public sealed class SubCategoriesController : ApiControllerBase
{
    private readonly ICategoryService _categories;

    public SubCategoriesController(ICategoryService categories) => _categories = categories;

    [HttpGet("{subCategoryId:int}")]
    [ProducesResponseType(typeof(SubCategoryDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<SubCategoryDto>> GetById(int subCategoryId, CancellationToken ct)
    {
        var result = await _categories.GetSubCategoryAsync(subCategoryId, ct);
        if (result is null) return NotFound();

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

    /// <summary>Renames a subcategory. It cannot be moved to another category — see the request DTO.</summary>
    [HttpPut("{subCategoryId:int}")]
    [ProducesResponseType(typeof(SubCategoryDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status409Conflict)]
    [ProducesResponseType(StatusCodes.Status412PreconditionFailed)]
    public async Task<ActionResult<SubCategoryDto>> Update(
        int subCategoryId, [FromBody] UpdateSubCategoryRequest request, CancellationToken ct)
    {
        var expected = RequireIfMatch();
        var result = await _categories.UpdateSubCategoryAsync(subCategoryId, request, expected, ct);
        SetETag(result.RowVersion);
        return Ok(result.Value);
    }

    /// <summary>Deactivate/reactivate. Masters are never hard-deleted (FR-MD-08).</summary>
    [HttpPatch("{subCategoryId:int}/status")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> SetStatus(
        int subCategoryId, [FromBody] UpdateSubCategoryStatusRequest request, CancellationToken ct)
    {
        await _categories.SetSubCategoryStatusAsync(subCategoryId, request.Status, ct);
        return NoContent();
    }
}
