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

namespace ERPCore.Controllers;

[Route("api/v1/bundle-sales")]
public sealed class BundleSalesController : ApiControllerBase
{
    private readonly IBundleSaleService _bundles;

    public BundleSalesController(IBundleSaleService bundles) => _bundles = bundles;

    [HttpGet("templates")]
    [ProducesResponseType(typeof(PagedResponse<BundleSaleTemplateSummaryDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<PagedResponse<BundleSaleTemplateSummaryDto>>> ListTemplates(
        [FromQuery] PageQuery query,
        CancellationToken ct)
        => Ok(await _bundles.ListTemplatesAsync(query, ct));

    [HttpGet("templates/{bundleSaleTemplateId:int}")]
    [ProducesResponseType(typeof(BundleSaleTemplateDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<BundleSaleTemplateDto>> GetTemplate(int bundleSaleTemplateId, CancellationToken ct)
    {
        var result = await _bundles.GetTemplateAsync(bundleSaleTemplateId, ct);
        return result is null ? NotFound() : Ok(result);
    }

    [HttpGet]
    [ProducesResponseType(typeof(PagedResponse<BundleSaleSummaryDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<PagedResponse<BundleSaleSummaryDto>>> List(
        [FromQuery] PageQuery query,
        [FromQuery] BundleSaleStatus? status,
        [FromQuery] int? customerId,
        [FromQuery] int? warehouseId,
        CancellationToken ct)
        => Ok(await _bundles.ListAsync(query, status, customerId, warehouseId, ct));

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

    [HttpGet("{bundleSaleId:int}/posting-check")]
    [ProducesResponseType(typeof(BundleSalePostingCheckDto), StatusCodes.Status200OK)]
    public async Task<ActionResult<BundleSalePostingCheckDto>> PostingCheck(int bundleSaleId, CancellationToken ct)
        => Ok(await _bundles.CheckPostingAsync(bundleSaleId, ct));

    [HttpPost]
    [ProducesResponseType(typeof(BundleSaleDto), StatusCodes.Status201Created)]
    public async Task<ActionResult<BundleSaleDto>> Create([FromBody] CreateBundleSaleRequest request, CancellationToken ct)
    {
        var result = await _bundles.CreateAsync(request, ct);
        return Created($"/api/v1/bundle-sales/{result.BundleSaleId}", result);
    }

    [HttpPut("{bundleSaleId:int}")]
    [ProducesResponseType(typeof(BundleSaleDto), StatusCodes.Status200OK)]
    public async Task<ActionResult<BundleSaleDto>> Update(int bundleSaleId, [FromBody] UpdateBundleSaleRequest request, CancellationToken ct)
    {
        return Ok(await _bundles.UpdateAsync(bundleSaleId, request, ct));
    }

    [HttpPost("{bundleSaleId:int}/post")]
    [ProducesResponseType(typeof(BundleSaleDto), StatusCodes.Status200OK)]
    public async Task<ActionResult<BundleSaleDto>> Post(int bundleSaleId, CancellationToken ct)
        => Ok(await _bundles.PostAsync(bundleSaleId, ct));

    [HttpPost("{bundleSaleId:int}/cancel")]
    [ProducesResponseType(typeof(BundleSaleDto), StatusCodes.Status200OK)]
    public async Task<ActionResult<BundleSaleDto>> Cancel(int bundleSaleId, CancellationToken ct)
        => Ok(await _bundles.CancelAsync(bundleSaleId, ct));
}
