import { Signal } from "@preact/signals";
import type { Ingredient, IngredientGroup } from "@lib/recipeSchema.ts";
import { FunctionalComponent } from "preact";
import { unitsOfMeasure } from "@lib/parseIngredient.ts";

function formatAmount(num: number) {
  if (num === 0) return "";
  return (Math.floor(num * 4) / 4).toString();
}

function formatUnit(unit: string, amount: number) {
  const unitKey = unit.toLowerCase() as keyof typeof unitsOfMeasure;
  if (unitKey in unitsOfMeasure) {
    if (amount > 1 && unitsOfMeasure[unitKey].plural !== undefined) {
      return unitsOfMeasure[unitKey].plural;
    }
    if (unitKey !== "cup") {
      return unitsOfMeasure[unitKey].short;
    }

    return unitKey.toString();
  } else {
    return unit;
  }
}

const Ingredient = (
  { ingredient, amount, key = "", portion = 1 }: {
    ingredient: Ingredient;
    amount: Signal<number>;
    key?: string | number;
    portion?: number;
  },
) => {
  const { name, quantity, unit } = ingredient;

  const parsedQuantity = parseFloat(quantity);

  const finalAmount = (typeof parsedQuantity === "number" && amount)
    ? (parsedQuantity / portion) * (amount?.value || 1)
    : "";

  return (
    <tr key={key}>
      <td class="pr-4 py-2">
        {formatAmount(finalAmount || 0)}
        <span class="ml-0.5 opacity-50">
          {formatUnit(unit, finalAmount || 0)}
        </span>
      </td>
      <td class="px-4 py-2">{name}</td>
    </tr>
  );
};

export const IngredientsList: FunctionalComponent<
  {
    ingredients: (Ingredient | IngredientGroup)[];
    amount: Signal<number>;
    portion?: number;
  }
> = (
  { ingredients, amount, portion },
) => {
  return (
    <table class="w-full border-collapse table-auto">
      <tbody>
        {ingredients.map((item, index) => {
          if ("items" in item) {
            // Render IngredientGroup
            const { name, items: groupIngredients } = item as IngredientGroup;

            return (
              <>
                <tr key={index}>
                  <td colSpan={3} class="pr-4 py-2 font-italic">{name}</td>
                </tr>
                {groupIngredients.map((item, index) => {
                  // Render Ingredient
                  return (
                    <Ingredient
                      key={index}
                      ingredient={item}
                      amount={amount}
                      portion={portion}
                    />
                  );
                })}
              </>
            );
          } else {
            return (
              <Ingredient ingredient={item} amount={amount} portion={portion} />
            );
          }
        })}
      </tbody>
    </table>
  );
};
