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

namespace ERPCore.Controllers.Hrm;

/// <summary>Staff document-type catalog ("DocType") endpoints (docs/13-BACKEND-HRM-API.md §2).</summary>
[Route("api/v1/hr-document-types")]
public sealed class HrDocumentTypesController : ApiControllerBase
{
    private readonly IHrDocumentTypeService _types;

    public HrDocumentTypesController(IHrDocumentTypeService types) => _types = types;

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

    [HttpGet("{hrDocumentTypeId:int}")]
    [ProducesResponseType(typeof(HrDocumentTypeDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<HrDocumentTypeDto>> GetById(int hrDocumentTypeId, CancellationToken ct)
    {
        var result = await _types.GetAsync(hrDocumentTypeId, ct);
        if (result is null) return NotFound();
        SetETag(result.RowVersion);
        return Ok(result.Value);
    }

    [HttpPost]
    [ProducesResponseType(typeof(HrDocumentTypeDto), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status409Conflict)]
    public async Task<ActionResult<HrDocumentTypeDto>> Create([FromBody] CreateHrDocumentTypeRequest request, CancellationToken ct)
    {
        var result = await _types.CreateAsync(request, ct);
        SetETag(result.RowVersion);
        return Created($"/api/v1/hr-document-types/{result.Value.HrDocumentTypeId}", result.Value);
    }

    [HttpPut("{hrDocumentTypeId:int}")]
    [ProducesResponseType(typeof(HrDocumentTypeDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status412PreconditionFailed)]
    public async Task<ActionResult<HrDocumentTypeDto>> Update(int hrDocumentTypeId, [FromBody] UpdateHrDocumentTypeRequest request, CancellationToken ct)
    {
        var expected = RequireIfMatch();
        var result = await _types.UpdateAsync(hrDocumentTypeId, request, expected, ct);
        SetETag(result.RowVersion);
        return Ok(result.Value);
    }

    [HttpPatch("{hrDocumentTypeId:int}/status")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> SetStatus(int hrDocumentTypeId, [FromBody] UpdateHrMasterStatusRequest request, CancellationToken ct)
    {
        await _types.SetStatusAsync(hrDocumentTypeId, request.Status, ct);
        return NoContent();
    }
}
