// EN: Strategy for PreparedFood products (F&B).
// VI: Strategy cho sản phẩm PreparedFood (F&B).

using OrderService.Domain.AggregatesModel.OrderAggregate;
using OrderService.Domain.Strategies;
using OrderService.API.Infrastructure.HttpClients;

namespace OrderService.API.Application.Strategies;

/// <summary>
/// EN: Strategy for PreparedFood products - routes to F&amp;B Engine.
/// VI: Strategy cho sản phẩm PreparedFood - route đến F&amp;B Engine.
/// </summary>
public class FnbStrategy : ILineItemStrategy
{
    private readonly FnbEngineClient _fnbClient;
    private readonly InventoryServiceClient _inventoryClient;
    private readonly ILogger<FnbStrategy> _logger;

    public string SupportedType => "PreparedFood";

    public FnbStrategy(
        FnbEngineClient fnbClient,
        InventoryServiceClient inventoryClient,
        ILogger<FnbStrategy> logger)
    {
        _fnbClient = fnbClient ?? throw new ArgumentNullException(nameof(fnbClient));
        _inventoryClient = inventoryClient ?? throw new ArgumentNullException(nameof(inventoryClient));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public Task<bool> ValidateAsync(
        OrderItem item,
        Guid shopId,
        CancellationToken cancellationToken = default)
    {
        _logger.LogInformation(
            "EN: Validating PreparedFood product / VI: Validate sản phẩm PreparedFood: {ProductName}",
            item.ProductName);

        // EN: F&B items are always valid (no inventory check)
        // VI: F&B items luôn hợp lệ (không cần kiểm tra kho)
        return Task.FromResult(true);
    }

    public async Task ExecuteAsync(
        OrderItem item,
        Guid shopId,
        CancellationToken cancellationToken = default)
    {
        _logger.LogInformation(
            "EN: Executing PreparedFood product / VI: Thực thi sản phẩm PreparedFood: {ProductName}",
            item.ProductName);

        // EN: Create kitchen ticket
        // VI: Tạo phiếu bếp
        var ticketId = await _fnbClient.CreateKitchenTicketAsync(
            item.ProductId,
            item.ProductName,
            shopId,
            item.Quantity,
            null, // Notes can be added later
            cancellationToken);

        if (ticketId == null)
        {
            throw new InvalidOperationException(
                $"EN: Failed to create kitchen ticket / VI: Tạo phiếu bếp thất bại: {item.ProductName}");
        }

        _logger.LogInformation(
            "EN: Kitchen ticket created / VI: Phiếu bếp đã tạo: {ProductName}, TicketId: {TicketId}",
            item.ProductName,
            ticketId);

        // EN: Skip inventory deduction if product doesn't track inventory
        // VI: Bỏ qua trừ kho nếu sản phẩm không theo dõi tồn kho
        if (item.TrackInventory)
        {
            // EN: Look up recipe and deduct raw materials from inventory
            // VI: Tra cứu công thức và trừ nguyên liệu thô từ kho
            var recipe = await _fnbClient.GetRecipeByProductAsync(
                item.ProductId, shopId, cancellationToken);

            if (recipe?.Ingredients != null)
            {
                foreach (var ingredient in recipe.Ingredients)
                {
                    if (ingredient.InventoryItemId == null || ingredient.InventoryItemId == Guid.Empty)
                        continue;

                    // EN: Calculate total quantity needed = quantityPerServing * order quantity
                    // VI: Tính tổng lượng cần = lượng/phần * số lượng order
                    var deductQty = ingredient.QuantityPerServing > 0
                        ? (int)Math.Ceiling(ingredient.QuantityPerServing * item.Quantity)
                        : item.Quantity;

                    var deducted = await _inventoryClient.DeductStockByIdAsync(
                        ingredient.InventoryItemId.Value, deductQty, null, cancellationToken);

                    if (!deducted)
                    {
                        _logger.LogWarning(
                            "EN: Failed to deduct inventory / VI: Trừ kho thất bại: Ingredient={Name}, ItemId={ItemId}, Qty={Qty}",
                            ingredient.IngredientName, ingredient.InventoryItemId, deductQty);
                    }
                    else
                    {
                        _logger.LogInformation(
                            "EN: Inventory deducted / VI: Đã trừ kho: {Name} x{Qty}",
                            ingredient.IngredientName, deductQty);
                    }
                }
            }
        }
        else
        {
            _logger.LogInformation(
                "EN: Skipping inventory deduction (trackInventory=false) / VI: Bỏ qua trừ kho (trackInventory=false): {ProductName}",
                item.ProductName);
        }
    }
}
