import type { AllergyView } from "@batch-cooking/shared";
import { ErrorCode } from "@batch-cooking/shared";
import { type FormEvent, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { ApiError, apiClient } from "../../api/client";
import { AllergySelect } from "../../features/profile/AllergySelect";
import { errorMessageService } from "../../services/error-message.service";
import "./onboarding.scss";

/**
 * Last step of the post-signup onboarding wizard, routed at
 * `/onboarding/allergenes`. Starts from an empty selection — a freshly
 * signed-up profile has none yet, so there's no need for the extra
 * `GET /profile/allergies` round trip a "resume where I left off" flow
 * would require (the `/parametres/preferences` settings page is the
 * always-fetch source of truth for editing an existing selection later).
 *
 * Also fetches the current household on mount, only to know whether the
 * `/onboarding/sources` step ran before this one (household step created
 * one and it had a source to configure) — the step count shown reflects
 * whichever path the visitor actually took, "3 sur 3" or "4 sur 4"
 * (there's no shared wizard state to read this from — see
 * `OnboardingHouseholdPage`'s doc comment on why each step is independent).
 */
export function OnboardingAllergensPage() {
  const { t } = useTranslation();
  const navigate = useNavigate();

  const [allergies, setAllergies] = useState<AllergyView[]>([]);
  const [allergyIds, setAllergyIds] = useState<number[]>([]);
  const [totalSteps, setTotalSteps] = useState(3);
  const [isLoading, setIsLoading] = useState(true);
  const [formError, setFormError] = useState<string | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);

  useEffect(() => {
    let cancelled = false;
    Promise.all([apiClient.getAllergies(), apiClient.getCurrentHouse()])
      .then(([allergiesResult, house]) => {
        if (cancelled) return;
        setAllergies(allergiesResult);
        setTotalSteps(house !== null ? 4 : 3);
      })
      .catch(() => {
        // Neither piece is essential for this last step to render — the
        // allergy list just stays empty (nothing to pick from) and the
        // step count keeps its 3-of-3 default, same "don't strand the
        // visitor over a transient failure" reasoning as
        // OnboardingSourcesPage's own catch, just with nothing to
        // navigate away to since this already is the last step.
      })
      .finally(() => {
        if (!cancelled) setIsLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, []);

  /** Finishes the wizard — the profile journey is complete, back to the app itself. */
  async function handleSubmit(e: FormEvent) {
    e.preventDefault();
    setFormError(null);
    setIsSubmitting(true);
    try {
      await apiClient.updateAllergyIds(allergyIds);
      void navigate("/");
    } catch (err) {
      const code = err instanceof ApiError ? err.code : ErrorCode.INTERNAL_ERROR;
      setFormError(errorMessageService.getLabel(code));
    } finally {
      setIsSubmitting(false);
    }
  }

  return (
    <main className="onboarding-page">
      <form className="onboarding-card" onSubmit={handleSubmit} noValidate>
        <p className="onboarding-step">
          {t("onboarding.step", { current: totalSteps, total: totalSteps })}
        </p>
        <h1>{t("onboarding.allergens.title")}</h1>

        {isLoading ? (
          <p>{t("onboarding.loading")}</p>
        ) : (
          <>
            <AllergySelect
              legend={t("preferences.form.allergiesLabel")}
              allergies={allergies.filter((allergy) => allergy.kind === "ALLERGY")}
              value={allergyIds}
              onChange={setAllergyIds}
            />
            <AllergySelect
              legend={t("preferences.form.intolerancesLabel")}
              allergies={allergies.filter((allergy) => allergy.kind === "INTOLERANCE")}
              value={allergyIds}
              onChange={setAllergyIds}
            />
          </>
        )}

        {formError && <p className="form-error">{formError}</p>}

        <button type="submit" disabled={isSubmitting || isLoading}>
          {t("onboarding.finish")}
        </button>
      </form>
    </main>
  );
}
