using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using WebClientTpos.Server.Infrastructure;

namespace WebClientTpos.Server.Controllers;

/// <summary>
/// EN: F&B controller — proxies to FnbEngine for tables, kitchen tickets, and recipes.
/// VI: Controller F&B — proxy đến FnbEngine cho bàn ăn, phiếu bếp và công thức.
/// </summary>
[ApiController]
[Route("api/bff")]
public class FnbController : ControllerBase
{
    private readonly HttpClient _fnb;

    public FnbController(IHttpClientFactory httpClientFactory)
    {
        _fnb = httpClientFactory.CreateClient("FnbEngine");
    }

    /// <summary>
    /// EN: Get tables for a specific shop.
    /// VI: Lấy danh sách bàn của một cửa hàng.
    /// </summary>
    [HttpGet("shops/{shopId}/tables")]
    public Task<IActionResult> GetTables(Guid shopId) =>
        _fnb.GetAsync($"/api/v1/tables?shopId={shopId}").ProxyAsync();

    /// <summary>
    /// EN: Create a table.
    /// VI: Tạo bàn.
    /// </summary>
    [HttpPost("tables")]
    public Task<IActionResult> CreateTable([FromBody] JsonElement body) =>
        _fnb.PostAsJsonAsync("/api/v1/tables", body).ProxyAsync();

    /// <summary>
    /// EN: Update a table.
    /// VI: Cập nhật bàn.
    /// </summary>
    [HttpPut("tables/{tableId:guid}")]
    public Task<IActionResult> UpdateTable(Guid tableId, [FromBody] JsonElement body) =>
        _fnb.PutAsJsonAsync($"/api/v1/tables/{tableId}", body).ProxyAsync();

    /// <summary>
    /// EN: Delete a table.
    /// VI: Xóa bàn.
    /// </summary>
    [HttpDelete("tables/{tableId:guid}")]
    public Task<IActionResult> DeleteTable(Guid tableId) =>
        _fnb.DeleteAsync($"/api/v1/tables/{tableId}").ProxyAsync();

    /// <summary>
    /// EN: Get kitchen tickets for a shop — optionally filtered by status.
    /// VI: Lấy phiếu bếp của shop — tùy chọn lọc theo trạng thái.
    /// </summary>
    [HttpGet("shops/{shopId}/kitchen-tickets")]
    public Task<IActionResult> GetKitchenTickets(Guid shopId, [FromQuery] string status = "Pending") =>
        _fnb.GetAsync($"/api/v1/kitchen/tickets?shopId={shopId}&status={Uri.EscapeDataString(status)}").ProxyAsync();

    /// <summary>
    /// EN: Update kitchen ticket status.
    /// VI: Cập nhật trạng thái phiếu bếp.
    /// </summary>
    [HttpPatch("kitchen/tickets/{ticketId:guid}/status")]
    public Task<IActionResult> UpdateTicketStatus(Guid ticketId, [FromBody] JsonElement body)
    {
        var request = new HttpRequestMessage(HttpMethod.Patch, $"/api/v1/kitchen/tickets/{ticketId}/status")
        {
            Content = JsonContent.Create(body)
        };
        return _fnb.SendAsync(request).ProxyAsync();
    }

    /// <summary>
    /// EN: Get recipes for a specific shop.
    /// VI: Lấy công thức của một cửa hàng.
    /// </summary>
    [HttpGet("shops/{shopId}/recipes")]
    public Task<IActionResult> GetRecipes(Guid shopId) =>
        _fnb.GetAsync($"/api/v1/kitchen/recipes?shopId={shopId}").ProxyAsync();

    /// <summary>
    /// EN: Create a recipe with ingredients.
    /// VI: Tạo công thức với nguyên liệu.
    /// </summary>
    [HttpPost("recipes")]
    public Task<IActionResult> CreateRecipe([FromBody] JsonElement body) =>
        _fnb.PostAsJsonAsync("/api/v1/kitchen/recipes", body).ProxyAsync();

    /// <summary>
    /// EN: Update a recipe.
    /// VI: Cập nhật công thức.
    /// </summary>
    [HttpPut("recipes/{recipeId:guid}")]
    public Task<IActionResult> UpdateRecipe(Guid recipeId, [FromBody] JsonElement body) =>
        _fnb.PutAsJsonAsync($"/api/v1/kitchen/recipes/{recipeId}", body).ProxyAsync();

    /// <summary>
    /// EN: Soft-delete a recipe.
    /// VI: Xóa mềm công thức.
    /// </summary>
    [HttpDelete("recipes/{recipeId:guid}")]
    public Task<IActionResult> DeleteRecipe(Guid recipeId) =>
        _fnb.DeleteAsync($"/api/v1/kitchen/recipes/{recipeId}").ProxyAsync();

    // ═══ RESERVATIONS ═══

    [HttpGet("shops/{shopId}/reservations")]
    public Task<IActionResult> GetReservations(Guid shopId, [FromQuery] string? date = null)
    {
        var url = $"/api/v1/reservations?shopId={shopId}";
        if (!string.IsNullOrEmpty(date)) url += $"&date={Uri.EscapeDataString(date)}";
        return _fnb.GetAsync(url).ProxyAsync();
    }

    [HttpPost("reservations")]
    public Task<IActionResult> CreateReservation([FromBody] JsonElement body) =>
        _fnb.PostAsJsonAsync("/api/v1/reservations", body).ProxyAsync();

    // ═══ TABLE QR ═══

    [HttpPost("tables/{tableId:guid}/generate-qr")]
    public Task<IActionResult> GenerateTableQr(Guid tableId) =>
        _fnb.PostAsJsonAsync($"/api/v1/tables/{tableId}/generate-qr", new { }).ProxyAsync();

    [HttpGet("tables/by-token/{token}")]
    public Task<IActionResult> GetTableByToken(string token) =>
        _fnb.GetAsync($"/api/v1/tables/by-token/{token}").ProxyAsync();

    [HttpPatch("reservations/{id:guid}/status")]
    public Task<IActionResult> UpdateReservationStatus(Guid id, [FromBody] JsonElement body)
    {
        var request = new HttpRequestMessage(HttpMethod.Patch, $"/api/v1/reservations/{id}/status")
        {
            Content = JsonContent.Create(body)
        };
        return _fnb.SendAsync(request).ProxyAsync();
    }

    // ═══ TABLE STATUS ═══

    [HttpPatch("tables/{tableId:guid}/status")]
    public Task<IActionResult> UpdateTableStatus(Guid tableId, [FromBody] JsonElement body)
    {
        var request = new HttpRequestMessage(HttpMethod.Patch, $"/api/v1/tables/{tableId}/status")
        {
            Content = JsonContent.Create(body)
        };
        return _fnb.SendAsync(request).ProxyAsync();
    }

    // ═══ SESSIONS ═══

    [HttpPost("sessions")]
    public Task<IActionResult> OpenSession([FromBody] JsonElement body) =>
        _fnb.PostAsJsonAsync("/api/v1/sessions", body).ProxyAsync();

    [HttpGet("sessions/{id:guid}")]
    public Task<IActionResult> GetSession(Guid id) =>
        _fnb.GetAsync($"/api/v1/sessions/{id}").ProxyAsync();

    [HttpPost("sessions/{id:guid}/close")]
    public Task<IActionResult> CloseSession(Guid id) =>
        _fnb.PostAsJsonAsync($"/api/v1/sessions/{id}/close", new { }).ProxyAsync();
}
