// EN: Controller for barista drink preparation queue.
// VI: Controller cho hang doi pha che barista.

using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using FnbEngine.API.Application.Commands;
using FnbEngine.API.Application.Queries;

namespace FnbEngine.API.Controllers;

/// <summary>
/// EN: Controller for managing the barista drink preparation queue.
/// VI: Controller de quan ly hang doi pha che barista.
/// </summary>
[ApiController]
[Route("api/v1/fnb/barista")]
[Authorize]
public class BaristaController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<BaristaController> _logger;

    public BaristaController(IMediator mediator, ILogger<BaristaController> logger)
    {
        _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    /// <summary>
    /// EN: Get current barista queue for a shop (active items sorted by priority).
    /// VI: Lay hang doi barista hien tai cho shop (item dang hoat dong sap xep theo uu tien).
    /// </summary>
    [HttpGet("queue")]
    [ProducesResponseType(typeof(ApiResponse<IEnumerable<BaristaQueueItemDto>>), 200)]
    public async Task<ActionResult<ApiResponse<IEnumerable<BaristaQueueItemDto>>>> GetQueue(
        [FromQuery] Guid shopId,
        CancellationToken cancellationToken)
    {
        var result = await _mediator.Send(new GetBaristaQueueQuery(shopId), cancellationToken);
        return Ok(new ApiResponse<IEnumerable<BaristaQueueItemDto>> { Success = true, Data = result });
    }

    /// <summary>
    /// EN: Get queue statistics for a shop.
    /// VI: Lay thong ke hang doi cho shop.
    /// </summary>
    [HttpGet("stats")]
    [ProducesResponseType(typeof(ApiResponse<QueueStatsDto>), 200)]
    public async Task<ActionResult<ApiResponse<QueueStatsDto>>> GetStats(
        [FromQuery] Guid shopId,
        CancellationToken cancellationToken)
    {
        var result = await _mediator.Send(new GetQueueStatsQuery(shopId), cancellationToken);
        return Ok(new ApiResponse<QueueStatsDto> { Success = true, Data = result });
    }

    /// <summary>
    /// EN: Add a drink to the barista queue.
    /// VI: Them do uong vao hang doi barista.
    /// </summary>
    [HttpPost("queue")]
    [ProducesResponseType(typeof(ApiResponse<QueueDrinkResult>), 200)]
    [ProducesResponseType(400)]
    public async Task<ActionResult<ApiResponse<QueueDrinkResult>>> QueueDrink(
        [FromBody] QueueDrinkCommand command,
        CancellationToken cancellationToken)
    {
        var result = await _mediator.Send(command, cancellationToken);
        return Ok(new ApiResponse<QueueDrinkResult> { Success = true, Data = result });
    }

    /// <summary>
    /// EN: Start preparing a queued drink.
    /// VI: Bat dau pha che do uong dang cho.
    /// </summary>
    [HttpPut("queue/{id}/start")]
    [ProducesResponseType(typeof(ApiResponse<bool>), 200)]
    [ProducesResponseType(404)]
    [ProducesResponseType(400)]
    public async Task<ActionResult<ApiResponse<bool>>> StartPreparing(
        Guid id,
        [FromBody] StartPreparingRequest request,
        CancellationToken cancellationToken)
    {
        try
        {
            var result = await _mediator.Send(
                new StartPreparingCommand(id, request.BaristaName), cancellationToken);
            return Ok(new ApiResponse<bool> { Success = true, Data = result });
        }
        catch (KeyNotFoundException ex)
        {
            return NotFound(new ApiResponse<bool> { Success = false, Error = ex.Message });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new ApiResponse<bool> { Success = false, Error = ex.Message });
        }
    }

    /// <summary>
    /// EN: Mark a drink as ready for pickup.
    /// VI: Danh dau do uong san sang de lay.
    /// </summary>
    [HttpPut("queue/{id}/ready")]
    [ProducesResponseType(typeof(ApiResponse<bool>), 200)]
    [ProducesResponseType(404)]
    [ProducesResponseType(400)]
    public async Task<ActionResult<ApiResponse<bool>>> MarkReady(
        Guid id,
        CancellationToken cancellationToken)
    {
        try
        {
            var result = await _mediator.Send(new MarkDrinkReadyCommand(id), cancellationToken);
            return Ok(new ApiResponse<bool> { Success = true, Data = result });
        }
        catch (KeyNotFoundException ex)
        {
            return NotFound(new ApiResponse<bool> { Success = false, Error = ex.Message });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new ApiResponse<bool> { Success = false, Error = ex.Message });
        }
    }

    /// <summary>
    /// EN: Mark a drink as delivered to the customer.
    /// VI: Danh dau do uong da giao cho khach.
    /// </summary>
    [HttpPut("queue/{id}/delivered")]
    [ProducesResponseType(typeof(ApiResponse<bool>), 200)]
    [ProducesResponseType(404)]
    [ProducesResponseType(400)]
    public async Task<ActionResult<ApiResponse<bool>>> MarkDelivered(
        Guid id,
        CancellationToken cancellationToken)
    {
        try
        {
            var result = await _mediator.Send(new MarkDrinkDeliveredCommand(id), cancellationToken);
            return Ok(new ApiResponse<bool> { Success = true, Data = result });
        }
        catch (KeyNotFoundException ex)
        {
            return NotFound(new ApiResponse<bool> { Success = false, Error = ex.Message });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new ApiResponse<bool> { Success = false, Error = ex.Message });
        }
    }

    /// <summary>
    /// EN: Cancel a drink in the barista queue.
    /// VI: Huy do uong trong hang doi barista.
    /// </summary>
    [HttpDelete("queue/{id}")]
    [ProducesResponseType(typeof(ApiResponse<bool>), 200)]
    [ProducesResponseType(404)]
    [ProducesResponseType(400)]
    public async Task<ActionResult<ApiResponse<bool>>> CancelQueueItem(
        Guid id,
        CancellationToken cancellationToken)
    {
        try
        {
            var result = await _mediator.Send(new CancelQueueItemCommand(id), cancellationToken);
            return Ok(new ApiResponse<bool> { Success = true, Data = result });
        }
        catch (KeyNotFoundException ex)
        {
            return NotFound(new ApiResponse<bool> { Success = false, Error = ex.Message });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new ApiResponse<bool> { Success = false, Error = ex.Message });
        }
    }
}

/// <summary>
/// EN: Request body for starting preparation.
/// VI: Request body de bat dau pha che.
/// </summary>
public record StartPreparingRequest(string BaristaName);
