// EN: Controller for kitchen display system.
// VI: Controller cho hệ thống hiển thị bếp.

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

namespace FnbEngine.API.Controllers;

[ApiController]
[Route("api/v1/kitchen")]
[Authorize]
public class KitchenController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ISessionRepository _sessionRepository;

    public KitchenController(IMediator mediator, ISessionRepository sessionRepository)
    {
        _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
        _sessionRepository = sessionRepository ?? throw new ArgumentNullException(nameof(sessionRepository));
    }

    /// <summary>
    /// EN: Get kitchen tickets. Filter by shopId+status or by station (pending only).
    /// VI: Lấy phiếu bếp. Lọc theo shopId+status hoặc theo station (chỉ pending).
    /// </summary>
    [HttpGet("tickets")]
    [ProducesResponseType(typeof(ApiResponse<IEnumerable<KitchenTicketDto>>), 200)]
    public async Task<ActionResult<ApiResponse<IEnumerable<KitchenTicketDto>>>> GetTickets(
        [FromQuery] Guid? shopId = null,
        [FromQuery] string? status = null,
        [FromQuery] string? station = null,
        CancellationToken ct = default)
    {
        IEnumerable<KitchenTicketDto> result;

        if (shopId.HasValue && shopId.Value != Guid.Empty)
        {
            result = await _mediator.Send(new GetTicketsByShopQuery(shopId.Value, status), ct);
        }
        else
        {
            result = await _mediator.Send(new GetPendingTicketsQuery(station), ct);
        }

        return Ok(new ApiResponse<IEnumerable<KitchenTicketDto>> { Success = true, Data = result });
    }

    /// <summary>
    /// EN: Update ticket status.
    /// VI: Cập nhật trạng thái phiếu.
    /// </summary>
    [HttpPatch("tickets/{id}/status")]
    [ProducesResponseType(typeof(ApiResponse<bool>), 200)]
    [ProducesResponseType(404)]
    public async Task<ActionResult<ApiResponse<bool>>> UpdateStatus(
        Guid id,
        [FromBody] UpdateStatusRequest request,
        CancellationToken ct = default)
    {
        var result = await _mediator.Send(new UpdateTicketStatusCommand(id, request.Status), ct);
        return Ok(new ApiResponse<bool> { Success = true, Data = result });
    }

    /// <summary>
    /// EN: Create a kitchen ticket from order-service.
    /// VI: Tạo phiếu bếp từ order-service.
    /// </summary>
    [HttpPost("tickets")]
    [ProducesResponseType(typeof(CreateTicketResponse), 200)]
    public async Task<ActionResult<CreateTicketResponse>> CreateTicket(
        [FromBody] CreateTicketRequest request,
        CancellationToken ct = default)
    {
        // EN: Find or create an active session for this shop
        // VI: Tìm hoặc tạo session hoạt động cho shop này
        var sessions = await _sessionRepository.GetByShopAsync(request.ShopId, ct);
        var activeSession = sessions.FirstOrDefault(s => s.Status == "Active");

        if (activeSession == null)
        {
            activeSession = new Session(request.ShopId, request.ShopId, 1);
            await _sessionRepository.AddAsync(activeSession, ct);
            await _sessionRepository.UnitOfWork.SaveEntitiesAsync(ct);
        }

        // EN: Create kitchen ticket via MediatR (with ProductId and Quantity for inventory deduction)
        // VI: Tạo phiếu bếp qua MediatR (với ProductId và Quantity cho trừ kho)
        var ticketId = await _mediator.Send(new CreateKitchenTicketCommand(
            activeSession.Id,
            request.ProductId,
            request.ProductName,
            null,
            0,
            request.ProductId,
            request.Quantity
        ), ct);

        return Ok(new CreateTicketResponse(ticketId));
    }

    // ═══ RECIPE ENDPOINTS ═══

    [HttpGet("recipes")]
    [ProducesResponseType(typeof(ApiResponse<IEnumerable<RecipeDto>>), 200)]
    public async Task<ActionResult<ApiResponse<IEnumerable<RecipeDto>>>> GetRecipes(
        [FromQuery] Guid shopId, CancellationToken ct = default)
    {
        var result = await _mediator.Send(new GetRecipesByShopQuery(shopId), ct);
        return Ok(new ApiResponse<IEnumerable<RecipeDto>> { Success = true, Data = result });
    }

    /// <summary>
    /// EN: Get recipe by product ID and shop ID (for inventory deduction).
    /// VI: Lấy công thức theo product ID và shop ID (cho trừ kho).
    /// </summary>
    [HttpGet("recipes/by-product")]
    [ProducesResponseType(typeof(ApiResponse<RecipeDto>), 200)]
    [ProducesResponseType(404)]
    public async Task<ActionResult<ApiResponse<RecipeDto>>> GetRecipeByProduct(
        [FromQuery] Guid productId, [FromQuery] Guid shopId, CancellationToken ct = default)
    {
        var result = await _mediator.Send(new GetRecipeByProductQuery(productId, shopId), ct);
        if (result == null)
            return NotFound(new ApiResponse<RecipeDto> { Success = false, Error = "No recipe found for this product" });
        return Ok(new ApiResponse<RecipeDto> { Success = true, Data = result });
    }

    [HttpPost("recipes")]
    [ProducesResponseType(typeof(ApiResponse<Guid>), 200)]
    public async Task<ActionResult<ApiResponse<Guid>>> CreateRecipe(
        [FromBody] CreateRecipeCommand command, CancellationToken ct = default)
    {
        var id = await _mediator.Send(command, ct);
        return Ok(new ApiResponse<Guid> { Success = true, Data = id });
    }

    [HttpPut("recipes/{id}")]
    [ProducesResponseType(typeof(ApiResponse<bool>), 200)]
    public async Task<ActionResult<ApiResponse<bool>>> UpdateRecipe(
        Guid id, [FromBody] UpdateRecipeCommand command, CancellationToken ct = default)
    {
        var cmd = command with { RecipeId = id };
        var result = await _mediator.Send(cmd, ct);
        return Ok(new ApiResponse<bool> { Success = true, Data = result });
    }

    [HttpDelete("recipes/{id}")]
    [ProducesResponseType(typeof(ApiResponse<bool>), 200)]
    public async Task<ActionResult<ApiResponse<bool>>> DeleteRecipe(Guid id, CancellationToken ct = default)
    {
        var result = await _mediator.Send(new DeleteRecipeCommand(id), ct);
        return Ok(new ApiResponse<bool> { Success = true, Data = result });
    }
}

public record UpdateStatusRequest(string Status);

public record CreateTicketRequest(
    Guid ProductId,
    string ProductName,
    Guid ShopId,
    int Quantity,
    string? Notes);

public record CreateTicketResponse(Guid TicketId);
