using MediatR;
using FnbEngine.Domain.AggregatesModel.RecipeAggregate;

namespace FnbEngine.API.Application.Queries;

public record GetRecipesByShopQuery(Guid ShopId) : IRequest<IEnumerable<RecipeDto>>;
public record GetRecipeByProductQuery(Guid ProductId, Guid ShopId) : IRequest<RecipeDto?>;

public record RecipeDto(Guid Id, Guid ProductId, Guid ShopId, string Name, string? Instructions,
    int PrepTimeMinutes, bool IsActive, DateTime CreatedAt, List<RecipeIngredientDto> Ingredients);

// EN: Recipe ingredient DTO — includes optional inventory item link for COGS.
// VI: DTO nguyên liệu — bao gồm liên kết tùy chọn đến mặt hàng tồn kho để tính giá vốn.
public record RecipeIngredientDto(Guid Id, string IngredientName, decimal Quantity, string Unit, decimal CostPerUnit,
    Guid? InventoryItemId = null, decimal QuantityPerServing = 0);

public class GetRecipesByShopQueryHandler : IRequestHandler<GetRecipesByShopQuery, IEnumerable<RecipeDto>>
{
    private readonly IRecipeRepository _repo;
    public GetRecipesByShopQueryHandler(IRecipeRepository repo) => _repo = repo;

    public async Task<IEnumerable<RecipeDto>> Handle(GetRecipesByShopQuery req, CancellationToken ct)
    {
        var recipes = await _repo.GetByShopIdAsync(req.ShopId, ct);
        return recipes.Select(r => new RecipeDto(
            r.Id, r.ProductId, r.ShopId, r.Name, r.Instructions, r.PrepTimeMinutes, r.IsActive, r.CreatedAt,
            r.Ingredients.Select(i => new RecipeIngredientDto(i.Id, i.IngredientName, i.Quantity, i.Unit, i.CostPerUnit, i.InventoryItemId, i.QuantityPerServing)).ToList()
        ));
    }
}

public class GetRecipeByProductQueryHandler : IRequestHandler<GetRecipeByProductQuery, RecipeDto?>
{
    private readonly IRecipeRepository _repo;
    public GetRecipeByProductQueryHandler(IRecipeRepository repo) => _repo = repo;

    public async Task<RecipeDto?> Handle(GetRecipeByProductQuery req, CancellationToken ct)
    {
        var r = await _repo.GetByProductIdAndShopAsync(req.ProductId, req.ShopId, ct);
        if (r == null) return null;
        return new RecipeDto(
            r.Id, r.ProductId, r.ShopId, r.Name, r.Instructions, r.PrepTimeMinutes, r.IsActive, r.CreatedAt,
            r.Ingredients.Select(i => new RecipeIngredientDto(i.Id, i.IngredientName, i.Quantity, i.Unit, i.CostPerUnit, i.InventoryItemId, i.QuantityPerServing)).ToList()
        );
    }
}
