namespace MealPlan.Api.Services.Generators;

public static class IngredientScalingHelper
{
    private const decimal CountAmountThreshold = 10m;

    public static (decimal? AmountGrams, string? Unit) ScaleForDietPlan(
        decimal? amountGrams,
        string? unit,
        decimal portions)
    {
        if (IsNonQuantifiedUnit(unit))
        {
            return (amountGrams, unit);
        }

        if (amountGrams is not > 0)
        {
            return (null, unit);
        }

        if (IsCountUnit(unit) && amountGrams.Value <= CountAmountThreshold)
        {
            var gramsPerUnit = GramsPerCountUnit(unit!);
            var totalGrams = amountGrams.Value * gramsPerUnit * portions;
            return (Math.Round(totalGrams, 1), null);
        }

        // AmountGrams stores weight in grams (even when the display unit says szt./ząbek).
        return (Math.Round(amountGrams.Value * portions, 1), null);
    }

    public static bool IsNonQuantifiedUnit(string? unit)
    {
        if (string.IsNullOrWhiteSpace(unit)) return false;
        var u = unit.Trim().ToLowerInvariant();
        return u is "do smaku" or "optional" or "opcjonalnie" or "szczypta" or "to taste";
    }

    private static bool IsCountUnit(string? unit)
    {
        if (string.IsNullOrWhiteSpace(unit)) return false;
        var u = NormalizeUnit(unit);
        return u is "szt" or "sztuka" or "sztuki"
            or "ząbek" or "zabek" or "zabki" or "clove" or "cloves"
            or "łyżka" or "lyzka" or "łyżeczka" or "lyzeczka"
            or "jajko" or "jajka" or "egg" or "eggs";
    }

    private static decimal GramsPerCountUnit(string unit)
    {
        var u = NormalizeUnit(unit);
        return u switch
        {
            "ząbek" or "zabek" or "zabki" or "clove" or "cloves" => 4m,
            "łyżka" or "lyzka" => 15m,
            "łyżeczka" or "lyzeczka" => 5m,
            _ => 60m, // szt., jajko — typical single egg / piece default
        };
    }

    private static string NormalizeUnit(string unit) =>
        unit.Trim().ToLowerInvariant().TrimEnd('.');
}
