import type { SourceView } 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 { SourceSelect } from "../../features/house/SourceSelect";
import { errorMessageService } from "../../services/error-message.service";
import "./onboarding.scss";

/**
 * Third step of the post-signup onboarding wizard, routed at
 * `/onboarding/sources` — only reached when a household now exists (see
 * `OnboardingHouseholdPage`'s `goToStep`, which skips straight to
 * `/onboarding/allergenes` when the previous step was skipped): enabled
 * sources are a per-household preference (`HouseSource`, schema.prisma),
 * so there's nothing to attach a selection to without one.
 *
 * Starts from an empty selection — a newly created/joined household has
 * nothing enabled yet by design (opt-in, see `house.service.ts`'s
 * `getHouseSourceIds`). If no source is implemented yet (`getSources()`
 * comes back empty — currently always the case), there's nothing to pick
 * from either, so this step silently steps itself over rather than showing
 * an empty screen.
 */
export function OnboardingSourcesPage() {
  const { t } = useTranslation();
  const navigate = useNavigate();

  const [sources, setSources] = useState<SourceView[]>([]);
  const [sourceIds, setSourceIds] = useState<number[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [formError, setFormError] = useState<string | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);

  useEffect(() => {
    let cancelled = false;
    apiClient
      .getSources()
      .then((result) => {
        if (cancelled) return;
        if (result.length === 0) {
          void navigate("/onboarding/allergenes", { replace: true });
          return;
        }
        setSources(result);
        setIsLoading(false);
      })
      .catch(() => {
        // Nothing to configure sources for if we can't even list them — the
        // wizard shouldn't strand the visitor here over a transient failure
        // fetching an optional step's own data.
        if (!cancelled) void navigate("/onboarding/allergenes", { replace: true });
      });
    return () => {
      cancelled = true;
    };
  }, [navigate]);

  async function handleSubmit(e: FormEvent) {
    e.preventDefault();
    setFormError(null);
    setIsSubmitting(true);
    try {
      await apiClient.updateHouseSourceIds(sourceIds);
      void navigate("/onboarding/allergenes");
    } 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: 3, total: 4 })}</p>
        <h1>{t("onboarding.sources.title")}</h1>
        <p className="onboarding-subtitle">{t("onboarding.sources.subtitle")}</p>

        {isLoading ? (
          <p>{t("onboarding.loading")}</p>
        ) : (
          <SourceSelect
            legend={t("onboarding.sources.legend")}
            sources={sources}
            value={sourceIds}
            onChange={setSourceIds}
          />
        )}

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

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