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

namespace FnbEngine.API.Application.Commands;

public class CreateRecipeCommandHandler : IRequestHandler<CreateRecipeCommand, Guid>
{
    private readonly IRecipeRepository _repo;
    public CreateRecipeCommandHandler(IRecipeRepository repo) => _repo = repo;

    public async Task<Guid> Handle(CreateRecipeCommand req, CancellationToken ct)
    {
        var recipe = new Recipe(req.ShopId, req.ProductId, req.Name, req.Instructions, req.PrepTimeMinutes);
        if (req.Ingredients != null)
        {
            foreach (var ing in req.Ingredients)
                recipe.AddIngredient(ing.IngredientName, ing.Quantity, ing.Unit, ing.CostPerUnit, ing.InventoryItemId, ing.QuantityPerServing);
        }
        _repo.Add(recipe);
        await _repo.UnitOfWork.SaveEntitiesAsync(ct);
        return recipe.Id;
    }
}

public class UpdateRecipeCommandHandler : IRequestHandler<UpdateRecipeCommand, bool>
{
    private readonly IRecipeRepository _repo;
    public UpdateRecipeCommandHandler(IRecipeRepository repo) => _repo = repo;

    public async Task<bool> Handle(UpdateRecipeCommand req, CancellationToken ct)
    {
        var recipe = await _repo.GetByIdAsync(req.RecipeId, ct);
        if (recipe == null) return false;

        recipe.Update(req.ProductId, req.Name, req.Instructions, req.PrepTimeMinutes);
        recipe.ClearIngredients();
        if (req.Ingredients != null)
        {
            foreach (var ing in req.Ingredients)
                recipe.AddIngredient(ing.IngredientName, ing.Quantity, ing.Unit, ing.CostPerUnit, ing.InventoryItemId, ing.QuantityPerServing);
        }
        _repo.Update(recipe);
        await _repo.UnitOfWork.SaveEntitiesAsync(ct);
        return true;
    }
}

public class DeleteRecipeCommandHandler : IRequestHandler<DeleteRecipeCommand, bool>
{
    private readonly IRecipeRepository _repo;
    public DeleteRecipeCommandHandler(IRecipeRepository repo) => _repo = repo;

    public async Task<bool> Handle(DeleteRecipeCommand req, CancellationToken ct)
    {
        var recipe = await _repo.GetByIdAsync(req.RecipeId, ct);
        if (recipe == null) return false;
        recipe.Deactivate();
        _repo.Update(recipe);
        await _repo.UnitOfWork.SaveEntitiesAsync(ct);
        return true;
    }
}
