using IdokladSdk.Models.PriceListItem;
using IdokladSdk.Models.StockMovement;
using IdokladSdk.Models.Tag;
using Microsoft.AspNetCore.Mvc;
using Idoklad.Services;

namespace Idoklad.Controllers;

/// <summary>
/// Price list items, stock movements and tags. Requires iDoklad credentials (headers or environment defaults).
/// </summary>
[ApiController]
[Produces("application/json")]
[Tags("Catalog")]
public sealed class CatalogController : ControllerBase
{
    private readonly CatalogService _service;

    public CatalogController(CatalogService service) => _service = service;

    // ---- Price list items ----

    /// <summary>List price list items (paged).</summary>
    [HttpGet("price-list-items")]
    public async Task<IActionResult> ListPriceListItems(int page = 1, int pageSize = 20, CancellationToken ct = default)
        => Ok(await _service.ListPriceListItemsAsync(page, pageSize, ct));

    /// <summary>Get a pre-filled default model for creating a new price list item.</summary>
    [HttpGet("price-list-items/default")]
    public async Task<IActionResult> PriceListItemDefault(CancellationToken ct)
        => Ok(await _service.PriceListItemDefaultAsync(ct));

    /// <summary>Get a price list item detail by id.</summary>
    [HttpGet("price-list-items/{id:int}")]
    public async Task<IActionResult> PriceListItemDetail(int id, CancellationToken ct)
        => Ok(await _service.PriceListItemDetailAsync(id, ct));

    /// <summary>Create a new price list item.</summary>
    [HttpPost("price-list-items")]
    public async Task<IActionResult> CreatePriceListItem([FromBody] PriceListItemPostModel model, CancellationToken ct)
        => Ok(await _service.CreatePriceListItemAsync(model, ct));

    /// <summary>Update an existing price list item (the model id identifies the item).</summary>
    [HttpPatch("price-list-items")]
    public async Task<IActionResult> UpdatePriceListItem([FromBody] PriceListItemPatchModel model, CancellationToken ct)
        => Ok(await _service.UpdatePriceListItemAsync(model, ct));

    // ---- Stock movements ----

    /// <summary>List stock movements (paged).</summary>
    [HttpGet("stock-movements")]
    public async Task<IActionResult> ListStockMovements(int page = 1, int pageSize = 20, CancellationToken ct = default)
        => Ok(await _service.ListStockMovementsAsync(page, pageSize, ct));

    /// <summary>Get a pre-filled default stock movement model for the given price list item id.</summary>
    [HttpGet("stock-movements/default/{priceListItemId:int}")]
    public async Task<IActionResult> StockMovementDefault(int priceListItemId, CancellationToken ct)
        => Ok(await _service.StockMovementDefaultAsync(priceListItemId, ct));

    /// <summary>Get a stock movement detail by id.</summary>
    [HttpGet("stock-movements/{id:int}")]
    public async Task<IActionResult> StockMovementDetail(int id, CancellationToken ct)
        => Ok(await _service.StockMovementDetailAsync(id, ct));

    /// <summary>Create a new stock movement.</summary>
    [HttpPost("stock-movements")]
    public async Task<IActionResult> CreateStockMovement([FromBody] StockMovementPostModel model, CancellationToken ct)
        => Ok(await _service.CreateStockMovementAsync(model, ct));

    /// <summary>Update an existing stock movement (the model id identifies the movement).</summary>
    [HttpPatch("stock-movements")]
    public async Task<IActionResult> UpdateStockMovement([FromBody] StockMovementPatchModel model, CancellationToken ct)
        => Ok(await _service.UpdateStockMovementAsync(model, ct));

    /// <summary>Delete a stock movement by id.</summary>
    [HttpDelete("stock-movements/{id:int}")]
    public async Task<IActionResult> DeleteStockMovement(int id, CancellationToken ct)
        => Ok(await _service.DeleteStockMovementAsync(id, ct));

    // ---- Tags ----

    /// <summary>List tags (paged).</summary>
    [HttpGet("tags")]
    public async Task<IActionResult> ListTags(int page = 1, int pageSize = 20, CancellationToken ct = default)
        => Ok(await _service.ListTagsAsync(page, pageSize, ct));

    /// <summary>Create a new tag.</summary>
    [HttpPost("tags")]
    public async Task<IActionResult> CreateTag([FromBody] TagPostModel model, CancellationToken ct)
        => Ok(await _service.CreateTagAsync(model, ct));

    /// <summary>Update an existing tag (the model id identifies the tag).</summary>
    [HttpPatch("tags")]
    public async Task<IActionResult> UpdateTag([FromBody] TagPatchModel model, CancellationToken ct)
        => Ok(await _service.UpdateTagAsync(model, ct));

    /// <summary>Delete a tag by id.</summary>
    [HttpDelete("tags/{id:int}")]
    public async Task<IActionResult> DeleteTag(int id, CancellationToken ct)
        => Ok(await _service.DeleteTagAsync(id, ct));
}
