import { DateTime, formatDateOnly, getWeekStart } from "@batch-cooking/date-tools";
import type { ShoppingListItemView, ShoppingListView } from "@batch-cooking/shared";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { apiClient } from "../../api/client";
import { WeekNavigator } from "../../features/planning/WeekNavigator";
import {
  CategoryIcon,
  IngredientTypeIcon,
} from "../../features/recipes/ingredients/ingredient-icons";
import { ingredientLabel } from "../../features/recipes/ingredients/ingredient-label";
import { formatShoppingListQuantity, groupShoppingListItems } from "./shopping-list";
import "./shopping-list-page.scss";

/** Load state for the `GET /shopping-list` call — same discriminated-union shape as `PlanningPage`'s own `PlanningState`. */
type ShoppingListState =
  | { status: "loading" }
  | { status: "loaded"; list: ShoppingListView }
  | { status: "error" };

/**
 * Shopping list section — routed at `/liste-de-courses`. Every ingredient
 * line of every recipe planned for a selectable week, aggregated server-side
 * (`GET /shopping-list`, see the API's `shopping-list.service.ts`) into one
 * quantity per (ingredient, unit) pair, grouped by supermarket aisle for
 * display. Deliberately simple by design — a read-only list, no
 * checkboxes/crossing-off state: the source of truth for what's needed is
 * the planning itself, not a separate to-do list this page would have to
 * keep in sync with it.
 */
export function ShoppingListPage() {
  const { t } = useTranslation();
  const [weekStart, setWeekStart] = useState<DateTime>(() => getWeekStart(DateTime.utc()));
  const [state, setState] = useState<ShoppingListState>({ status: "loading" });

  useEffect(() => {
    let cancelled = false;
    setState({ status: "loading" });

    apiClient
      .getShoppingListForWeek(formatDateOnly(weekStart))
      .then((list) => {
        if (!cancelled) setState({ status: "loaded", list });
      })
      .catch(() => {
        if (!cancelled) setState({ status: "error" });
      });

    return () => {
      cancelled = true;
    };
  }, [weekStart]);

  return (
    <div className="shopping-list-page">
      <div className="shopping-list-page__header">
        <h1>{t("shoppingList.title")}</h1>
        <WeekNavigator weekStart={weekStart} onChangeWeek={setWeekStart} />
      </div>

      {state.status === "loading" && (
        <p className="shopping-list-page__status">{t("shoppingList.loading")}</p>
      )}

      {state.status === "error" && (
        <p className="shopping-list-page__status shopping-list-page__status--error">
          {t("common.loadError")}
        </p>
      )}

      {state.status === "loaded" && <ShoppingListItems items={state.list.items} />}
    </div>
  );
}

/** The list itself, grouped by aisle (see `groupShoppingListItems`) — or the empty-week message if nothing's planned. */
function ShoppingListItems({ items }: { items: ShoppingListItemView[] }) {
  const { t } = useTranslation();

  if (items.length === 0) {
    return <p className="shopping-list-page__status">{t("shoppingList.empty")}</p>;
  }

  const groups = groupShoppingListItems(items, (item) => ingredientLabel(item.ingredient, t));

  return (
    <div className="shopping-list">
      {groups.map((group) => (
        <section key={group.category} className="shopping-list__group">
          <h2 className="shopping-list__group-title">
            <CategoryIcon category={group.category} />
            {t(`recipes.form.category.${group.category}`)}
          </h2>
          <ul className="shopping-list__items">
            {group.items.map((item) => (
              <li key={`${item.ingredient.id}-${item.unit.id}`} className="shopping-list__item">
                <span className="shopping-list__item-icon" aria-hidden="true">
                  <IngredientTypeIcon icon={item.ingredient.icon} />
                </span>
                <span className="shopping-list__item-name">
                  {ingredientLabel(item.ingredient, t)}
                </span>
                <span className="shopping-list__item-quantity">
                  {formatShoppingListQuantity(item.quantity)} {t(`catalog.units.${item.unit.key}`)}
                </span>
              </li>
            ))}
          </ul>
        </section>
      ))}
    </div>
  );
}
