'use client';

import { useState, useRef, useEffect } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { motion, AnimatePresence } from 'motion/react';
import { apiFetch } from '@/lib/api-client';
import { ToggleChipBar } from '@/components/toggle-chip-bar';
import { getCuisineOptions } from '@/lib/cuisine';
import { LanguageSwitch } from '@/components/language-switch';
import { TutorialOverlay } from '@/components/tutorial-overlay';
import { useTranslation } from '@/lib/i18n/context';
import { usePageTitle } from '@/lib/use-page-title';
import { PwaInstallBanner } from '@/components/pwa-install-banner';
import { useNavVisibility } from '@/components/nav-visibility';
import {
  getStoredDisplayName,
  setStoredDisplayName,
  getStoredLastCity,
  setStoredLastCity,
  getActiveSession,
} from '@/lib/storage';

type Screen = 'intro' | 'create';
type JoinStep = 'code' | 'name';

const CREATE_STEPS = 3;
const DEFAULT_CITY = 'Karlsruhe';
const DEFAULT_RADIUS_KM = 5;

/**
 * Animierter Karten-Stapel als neues Hero-Visual - ersetzt das vorherige
 * statische Logo-Icon neben dem "Yumder"-Schriftzug. Faechert bei Hover
 * per CSS auf (siehe .card-stack-Regeln in globals.css), um die
 * Kernmechanik (Swipen fuer Essen) schon vor dem ersten Tap visuell zu
 * kommunizieren. Farben bewusst aus unseren bestehenden Tailwind-Tokens
 * (yumder-pink/yumder-teal/neutral-*) statt der zinc-*-Klassen aus der
 * urspruenglichen Mockup-Vorlage.
 */
function SwipeCardStackHero() {
  return (
    <div className="relative w-24 h-32 mb-2 card-stack cursor-default">
      <div className="card-back absolute inset-0 bg-neutral-800 rounded-2xl rotate-[8deg] translate-x-3 translate-y-2 border border-neutral-700 shadow-xl transition-all duration-300" />
      <div className="card-middle absolute inset-0 bg-yumder-teal/90 rounded-2xl -rotate-[6deg] -translate-x-3 translate-y-1 shadow-xl transition-all duration-300 border border-yumder-teal backdrop-blur-sm" />
      <div className="card-front absolute inset-0 bg-gradient-to-tr from-yumder-pink to-pink-500 rounded-2xl flex items-center justify-center shadow-2xl z-10 transition-all duration-300 border border-pink-400/50">
        <svg className="w-10 h-10 text-white drop-shadow-md" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
          <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
        </svg>
      </div>
    </div>
  );
}

export function HomeClient() {
  const router = useRouter();
  const { t, locale } = useTranslation();
  const cuisineOptions = getCuisineOptions(locale);
  const { setHidden } = useNavVisibility();
  // BUGFIX (i18n-Nachtrag): der Tab-Titel kam bisher NUR aus der statischen
  // metadata in app/page.tsx (server-seitig, kennt die Sprache nicht) - war
  // fuer EN-Nutzer:innen also immer "Start · Yumder" statt "Home · Yumder".
  // usePageTitle() ueberschreibt document.title clientseitig, sobald t
  // bekannt ist, analog zum <html lang>-Fix.
  usePageTitle(t.home.pageTitle);
  const [screen, setScreen] = useState<Screen>('intro');
  const [step, setStep] = useState(1);

  // Aktive Teilnahme erkennen, um auf der Startseite einen "Weiter swipen"-
  // Button anzubieten (statt nur Starten/Beitreten). Window-sicher, wird
  // nach dem Mount gesetzt.
  const [resumeCode, setResumeCode] = useState<string | null>(null);
  useEffect(() => {
    const active = getActiveSession();
    if (active.participantId && active.code) {
      setResumeCode(active.code);
    }
  }, []);

  // Bottom-Navigation waehrend des Erstellen-Wizards (screen === 'create')
  // ausblenden, damit der mehrstufige Flow fokussiert bleibt. Beim Verlassen
  // des Wizards bzw. der Seite wird die Nav wieder eingeblendet.
  useEffect(() => {
    setHidden(screen === 'create');
    return () => setHidden(false);
  }, [screen, setHidden]);

  // UPDATE: "So geht\'s"-Button oben links oeffnet das bestehende
  // TutorialOverlay direkt vom Start-Screen aus. Der frueher zusaetzliche
  // automatische Aufruf nach Erstellen/Beitreten (yumder_show_tutorial-Flag)
  // wurde am 13.08. entfernt - Tutorial startet jetzt ausschliesslich
  // manuell ueber diesen Button.
  const [showTutorial, setShowTutorial] = useState(false);

  // UPDATE (v3): "Session beitreten" ist kein eigener Screen mehr, sondern
  // klappt sich INLINE unterhalb des Buttons auf. Zwei-Schritt-Flow: erst
  // Code (joinStep 'code'), nach Bestaetigung per Pfeil/Enter DANN erst das
  // Namensfeld (joinStep 'name').
  const [isJoinMode, setIsJoinMode] = useState(false);
  const [joinStep, setJoinStep] = useState<JoinStep>('code');

  const [displayName, setDisplayName] = useState(getStoredDisplayName() ?? '');
  const [city, setCity] = useState(getStoredLastCity() ?? DEFAULT_CITY);
  const [cityTouched, setCityTouched] = useState(false);
  const [radiusKm, setRadiusKm] = useState(DEFAULT_RADIUS_KM);
  const [cuisineTags, setCuisineTags] = useState<string[]>([]);
  const [excludeFastFood, setExcludeFastFood] = useState(true);
  const [spinningWheel, setSpinningWheel] = useState(false);

  const [joinCode, setJoinCode] = useState('');
  const [loading, setLoading] = useState(false);
  // BUGFIX (13.08.): eigener Loading-State fuer die Code-Vorabpruefung,
  // getrennt von "loading" (das fuer den Namens-Schritt/Create genutzt wird)
  // - so bleibt der Namens-Schritt-Button unberuehrt, waehrend der
  // Code-Schritt seinen eigenen Spinner zeigt.
  const [checkingCode, setCheckingCode] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const joinCodeInputRef = useRef<HTMLInputElement | null>(null);
  const joinNameInputRef = useRef<HTMLInputElement | null>(null);

  const nameTrimmed = displayName.trim();
  const cityTitle = nameTrimmed
    ? t.home.step2TitleWithName(nameTrimmed)
    : t.home.step2TitleNoName;

  function toggleCuisine(value: string) {
    setCuisineTags((prev) =>
      prev.includes(value) ? prev.filter((v) => v !== value) : [...prev, value]
    );
  }

  function spinCuisineWheel() {
    if (spinningWheel) return;
    setSpinningWheel(true);
    const randomIndex = Math.floor(Math.random() * cuisineOptions.length);
    const picked = cuisineOptions[randomIndex];
    setTimeout(() => {
      setCuisineTags([picked.value]);
      setSpinningWheel(false);
    }, 600);
  }

  function goIntro() {
    setScreen('intro');
    setStep(1);
    setIsJoinMode(false);
    setJoinStep('code');
    setError(null);
  }

  function startCreate() {
    setScreen('create');
    setStep(1);
    setError(null);
  }

  function openJoinInline() {
    setIsJoinMode(true);
    setJoinStep('code');
    setError(null);
  }

  function closeJoinInline() {
    setIsJoinMode(false);
    setJoinStep('code');
    setJoinCode('');
    setError(null);
  }

  // BUGFIX (13.08.): Vorher wurde beim Bestaetigen des Codes NUR geprueft,
  // ob das Feld nicht leer ist, und direkt zum Namens-Schritt gewechselt.
  // Existierte die Session gar nicht, kam der Fehler "Session nicht
  // gefunden" erst NACH der Namenseingabe (Join-API-Call in handleJoin) -
  // Nutzer musste zurueckspringen. Jetzt: Session-Existenz vorab pruefen
  // (per bestehender, nebenwirkungsfreier Poll-Route), erst bei Erfolg
  // zum Namens-Schritt wechseln.
  async function submitJoinCode() {
    if (!joinCode.trim() || checkingCode) return;
    setError(null);
    setCheckingCode(true);
    try {
      const code = joinCode.toUpperCase().trim();
      await apiFetch(`/api/session/${code}/poll`);
      setJoinStep('name');
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : t.common.errorJoinDefault);
    } finally {
      setCheckingCode(false);
    }
  }

  function backToCodeStep() {
    setJoinStep('code');
    setError(null);
  }

  function handleJoinCodeKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
    if (e.key === 'Enter' && !checkingCode) {
      e.preventDefault();
      submitJoinCode();
    }
  }

  function handleJoinNameKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
    if (e.key === 'Enter' && !loading) {
      e.preventDefault();
      handleJoin();
    }
  }

  function goToStep2() {
    setError(null);
    setStep(2);
  }

  function goToStep3() {
    if (!city.trim()) return;
    setError(null);
    setStep(3);
  }

  function handleStep1KeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
    if (e.key === 'Enter') {
      e.preventDefault();
      goToStep2();
    }
  }

  function handleStep2KeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
    if (e.key === 'Enter') {
      e.preventDefault();
      goToStep3();
    }
  }

  function onCityFocus(e: React.FocusEvent<HTMLInputElement>) {
    if (!cityTouched) e.target.select();
  }

  function onCityChange(e: React.ChangeEvent<HTMLInputElement>) {
    if (!cityTouched) {
      setCityTouched(true);
      const native = e.nativeEvent as InputEvent;
      if (native.inputType === 'insertText' && native.data) {
        setCity(native.data);
        return;
      }
    }
    setCity(e.target.value);
  }

  async function handleCreate() {
    if (!city.trim() || loading) return;
    setLoading(true);
    setError(null);
    try {
      const data = await apiFetch('/api/session', {
        method: 'POST',
        body: JSON.stringify({
          city: city.trim(),
          radiusKm,
          priceMin: 1,
          priceMax: 4,
          displayName: nameTrimmed || undefined,
          excludeFastFood,
          excludeChains: excludeFastFood,
          openNowOnly: false,
          cuisineTags,
        }),
      });
      localStorage.setItem('yumder_anonymous_id', data.anonymousId);
      localStorage.setItem('yumder_participant_id', String(data.participantId));
      localStorage.setItem('yumder_session_code', data.code);
      setStoredDisplayName(nameTrimmed);
      setStoredLastCity(city.trim());
      router.push(`/session/${data.code}`);
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : t.home.errorCreateDefault);
    } finally {
      setLoading(false);
    }
  }

  async function handleJoin() {
    if (!joinCode.trim() || loading) return;
    setLoading(true);
    setError(null);
    try {
      const code = joinCode.toUpperCase().trim();
      const data = await apiFetch(`/api/session/${code}/join`, {
        method: 'POST',
        body: JSON.stringify({ displayName }),
      });
      localStorage.setItem('yumder_anonymous_id', data.anonymousId);
      localStorage.setItem('yumder_participant_id', String(data.participantId));
      localStorage.setItem('yumder_session_code', code);
      setStoredDisplayName(displayName.trim());
      router.push(`/session/${code}`);
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : t.common.errorJoinDefault);
    } finally {
      setLoading(false);
    }
  }

  return (
    <main className="relative flex flex-col items-center justify-center min-h-dvh-safe p-6 gap-6 overflow-x-hidden overflow-y-auto bg-neutral-950 safe-top safe-bottom">
      <div
        aria-hidden
        className="pointer-events-none absolute -top-1/3 left-1/2 -translate-x-1/2 h-[600px] w-[600px] rounded-full opacity-30 blur-3xl"
        style={{
          background:
            'radial-gradient(circle, rgba(254,60,114,0.5) 0%, rgba(0,194,168,0.25) 45%, transparent 75%)',
        }}
      />

      {/*
        UPDATE: "So geht\'s"-Button links (oeffnet TutorialOverlay direkt),
        Language-Toggle bleibt rechts. Das Settings-Zahnrad aus dem v3-
        Mockup wird weiterhin bewusst NICHT gerendert - es gibt aktuell
        keine Einstellungen, die es oeffnen wuerde.
      */}
      <div className="absolute top-0 left-0 w-full p-6 pt-[calc(1.5rem+var(--safe-area-inset-top,env(safe-area-inset-top,0px)))] flex justify-between items-center z-20">
        <button
          type="button"
          onClick={() => setShowTutorial(true)}
          className="flex items-center gap-1.5 text-neutral-400 hover:text-neutral-200 text-xs font-semibold transition-colors bg-neutral-900/50 px-3 py-1.5 rounded-full border border-transparent hover:border-neutral-700"
        >
          <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
          </svg>
          {t.home.howItWorksButton}
        </button>
        <div className="flex items-center gap-3">
          <LanguageSwitch />
        </div>
      </div>

      <motion.div
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.5, ease: 'easeOut' }}
        className="relative z-10 flex flex-col items-center gap-2"
      >
        {/*
          UPDATE: Animierter Karten-Stapel ersetzt das vorherige statische
          Logo-Icon (img/logo.svg) - jetzt vertikal ueber dem Schriftzug
          statt daneben, siehe SwipeCardStackHero oben.
        */}
        <SwipeCardStackHero />
        <h1 className="text-5xl font-extrabold tracking-tight bg-gradient-to-r from-yumder-pink via-pink-400 to-yumder-teal bg-clip-text text-transparent">
          Yumder
        </h1>
        {screen === 'intro' && (
          <p className="text-neutral-400 text-center text-sm max-w-xs">
            {t.home.introSubtitle}
          </p>
        )}
      </motion.div>

      {screen === 'create' && (
        <div
          className="relative z-10 flex items-center gap-2"
          aria-label={t.home.stepAriaLabel(step, CREATE_STEPS)}
        >
          {Array.from({ length: CREATE_STEPS }, (_, i) => {
            const n = i + 1;
            const active = n === step;
            const done = n < step;
            return (
              <div
                key={n}
                className={`h-2 rounded-full transition-all duration-300 ${
                  active
                    ? 'w-6 bg-yumder-pink shadow-[0_0_12px_rgba(254,60,114,0.55)]'
                    : done
                      ? 'w-2 bg-yumder-teal/80'
                      : 'w-2 bg-neutral-700'
                }`}
              />
            );
          })}
        </div>
      )}

      <AnimatePresence mode="wait">
        {screen === 'intro' && (
          <motion.div
            key="intro"
            initial={{ opacity: 0, y: 10 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -10 }}
            transition={{ duration: 0.28 }}
            className="relative z-10 w-full max-w-sm flex flex-col gap-3"
          >
            {resumeCode && (
              <Link
                href={`/session/${resumeCode}`}
                className="w-full flex items-center justify-center gap-2 rounded-xl px-4 py-3.5 font-semibold bg-gradient-to-r from-yumder-teal to-teal-400 text-neutral-900 shadow-[0_0_25px_rgba(0,194,168,0.35)]"
              >
                <svg viewBox="0 0 24 24" className="w-5 h-5" fill="none" stroke="currentColor" strokeWidth="2.5" aria-hidden="true">
                  <path strokeLinecap="round" strokeLinejoin="round" d="M5 3l14 9-14 9V3z" />
                </svg>
                {t.home.resumeButton}
              </Link>
            )}

            <motion.button
              type="button"
              onClick={startCreate}
              whileTap={{ scale: 0.97 }}
              className="w-full bg-gradient-to-r from-yumder-pink to-pink-500 font-semibold rounded-xl px-4 py-3.5 shadow-[0_0_25px_rgba(254,60,114,0.4)]"
            >
              {t.home.startSessionButton}
            </motion.button>

            <AnimatePresence mode="wait" initial={false}>
              {!isJoinMode ? (
                <motion.button
                  key="join-btn"
                  type="button"
                  onClick={openJoinInline}
                  whileTap={{ scale: 0.97 }}
                  initial={{ opacity: 0 }}
                  animate={{ opacity: 1 }}
                  exit={{ opacity: 0 }}
                  className="w-full rounded-xl px-4 py-3.5 font-semibold border border-white/10 bg-neutral-900 text-neutral-200 hover:border-yumder-teal/40 transition-colors"
                >
                  {t.home.joinSessionButton}
                </motion.button>
              ) : (
                <motion.div
                  key="join-inline"
                  initial={{ opacity: 0, y: -10 }}
                  animate={{ opacity: 1, y: 0 }}
                  exit={{ opacity: 0, y: -10 }}
                  transition={{ duration: 0.25 }}
                  className="w-full flex flex-col gap-2"
                >
                  <AnimatePresence mode="wait" initial={false}>
                    {joinStep === 'code' ? (
                      <motion.div
                        key="join-step-code"
                        initial={{ opacity: 0 }}
                        animate={{ opacity: 1 }}
                        exit={{ opacity: 0 }}
                        transition={{ duration: 0.2 }}
                        className="relative w-full"
                      >
                        <input
                          ref={joinCodeInputRef}
                          placeholder={t.home.codePlaceholder}
                          value={joinCode}
                          onChange={(e) => setJoinCode(e.target.value)}
                          onKeyDown={handleJoinCodeKeyDown}
                          disabled={checkingCode}
                          autoFocus
                          className="w-full bg-neutral-900 border border-yumder-teal/50 focus:border-yumder-teal text-white font-bold text-center text-lg py-3.5 pl-10 pr-14 rounded-xl outline-none transition-colors placeholder:font-normal placeholder:text-neutral-600 uppercase tracking-widest disabled:opacity-60"
                        />
                        <button
                          type="button"
                          onClick={closeJoinInline}
                          aria-label={t.home.joinInlineCloseAriaLabel}
                          className="absolute left-2 top-1/2 -translate-y-1/2 p-1.5 text-neutral-500 hover:text-neutral-300 rounded-full transition-colors"
                        >
                          <svg viewBox="0 0 24 24" className="w-4 h-4" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
                            <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
                          </svg>
                        </button>
                        <motion.button
                          type="button"
                          whileTap={{ scale: 0.95 }}
                          onClick={submitJoinCode}
                          disabled={!joinCode.trim() || checkingCode}
                          aria-label={t.home.joinInlineSubmitAriaLabel}
                          className="absolute right-2 top-1/2 -translate-y-1/2 p-2 bg-yumder-teal hover:bg-teal-400 disabled:opacity-40 text-neutral-900 rounded-lg shadow-md transition-all hover:scale-105"
                        >
                          {checkingCode ? (
                            <svg viewBox="0 0 24 24" className="w-4 h-4 animate-spin" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
                              <path strokeLinecap="round" d="M12 3a9 9 0 1 0 9 9" />
                            </svg>
                          ) : (
                            <svg viewBox="0 0 24 24" className="w-4 h-4" fill="none" stroke="currentColor" strokeWidth="3" aria-hidden="true">
                              <path strokeLinecap="round" strokeLinejoin="round" d="M14 5l7 7m0 0l-7 7m7-7H3" />
                            </svg>
                          )}
                        </motion.button>
                      </motion.div>
                    ) : (
                      <motion.div
                        key="join-step-name"
                        initial={{ opacity: 0, x: 14 }}
                        animate={{ opacity: 1, x: 0 }}
                        exit={{ opacity: 0, x: -14 }}
                        transition={{ duration: 0.22 }}
                        className="w-full flex flex-col gap-2"
                      >
                        <div className="flex items-center gap-2 px-1">
                          <button
                            type="button"
                            onClick={backToCodeStep}
                            aria-label={t.home.joinInlineBackAriaLabel}
                            className="text-neutral-500 hover:text-neutral-300 transition-colors shrink-0"
                          >
                            <svg viewBox="0 0 24 24" className="w-4 h-4" fill="none" stroke="currentColor" strokeWidth="2.5" aria-hidden="true">
                              <path strokeLinecap="round" strokeLinejoin="round" d="M15 19l-7-7 7-7" />
                            </svg>
                          </button>
                          <span className="text-xs font-mono font-bold text-neutral-400 tracking-widest truncate">
                            {joinCode.toUpperCase()}
                          </span>
                        </div>
                        <div className="relative w-full">
                          <input
                            ref={joinNameInputRef}
                            placeholder={t.common.namePlaceholderOptional}
                            value={displayName}
                            onChange={(e) => setDisplayName(e.target.value)}
                            onKeyDown={handleJoinNameKeyDown}
                            autoFocus
                            className="w-full bg-neutral-900 rounded-xl px-4 py-3 pr-14 border border-yumder-pink/40 focus:border-yumder-pink outline-none transition-colors text-neutral-100"
                          />
                          <motion.button
                            type="button"
                            whileTap={{ scale: 0.95 }}
                            onClick={handleJoin}
                            disabled={loading}
                            aria-label={t.home.joinInlineSubmitAriaLabel}
                            className="absolute right-2 top-1/2 -translate-y-1/2 p-2 bg-yumder-pink hover:bg-pink-500 disabled:opacity-50 text-white rounded-lg shadow-md transition-all hover:scale-105"
                          >
                            {loading ? (
                              <svg viewBox="0 0 24 24" className="w-4 h-4 animate-spin" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
                                <path strokeLinecap="round" d="M12 3a9 9 0 1 0 9 9" />
                              </svg>
                            ) : (
                              <svg viewBox="0 0 24 24" className="w-4 h-4" fill="none" stroke="currentColor" strokeWidth="3" aria-hidden="true">
                                <path strokeLinecap="round" strokeLinejoin="round" d="M14 5l7 7m0 0l-7 7m7-7H3" />
                              </svg>
                            )}
                          </motion.button>
                        </div>
                      </motion.div>
                    )}
                  </AnimatePresence>
                  <AnimatePresence>
                    {error && (
                      <motion.p
                        initial={{ opacity: 0, x: 0 }}
                        animate={{ opacity: 1, x: [0, -6, 6, -4, 4, 0] }}
                        exit={{ opacity: 0 }}
                        transition={{ duration: 0.4 }}
                        className="text-red-400 text-sm text-center"
                      >
                        {error}
                      </motion.p>
                    )}
                  </AnimatePresence>
                </motion.div>
              )}
            </AnimatePresence>
          </motion.div>
        )}

        {screen === 'create' && (
          <motion.div
            key="create-shell"
            layout
            initial={{ opacity: 0, y: 10 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -10 }}
            transition={{ duration: 0.28, layout: { duration: 0.35, ease: 'easeInOut' } }}
            className="relative z-10 w-full max-w-sm flex flex-col gap-3 rounded-3xl border border-white/10 bg-neutral-900 p-5 shadow-2xl"
          >
            <AnimatePresence mode="wait">
              {step === 1 && (
                <motion.div
                  key="step-1"
                  initial={{ opacity: 0, x: 16 }}
                  animate={{ opacity: 1, x: 0 }}
                  exit={{ opacity: 0, x: -16 }}
                  transition={{ duration: 0.22 }}
                  className="flex flex-col gap-3"
                >
                  <div>
                    <h2 className="text-lg font-semibold text-white">{t.home.step1Title}</h2>
                    <p className="text-sm text-neutral-400 mt-0.5">
                      {t.home.step1Subtitle}
                    </p>
                  </div>
                  <input
                    placeholder={t.home.namePlaceholder}
                    value={displayName}
                    onChange={(e) => setDisplayName(e.target.value)}
                    onKeyDown={handleStep1KeyDown}
                    autoComplete="nickname"
                    className="bg-neutral-800 rounded-xl px-4 py-3 border border-white/5 focus:border-yumder-pink/60 outline-none transition-colors"
                  />
                  <div className="flex gap-2 mt-1">
                    <button
                      type="button"
                      onClick={goIntro}
                      className="flex-1 rounded-xl px-4 py-3 text-sm font-medium text-neutral-300 bg-neutral-800 border border-white/5 hover:bg-neutral-700 transition-colors"
                    >
                      {t.common.back}
                    </button>
                    <motion.button
                      type="button"
                      whileTap={{ scale: 0.97 }}
                      onClick={goToStep2}
                      className="flex-[1.4] rounded-xl px-4 py-3 text-sm font-semibold bg-gradient-to-r from-yumder-pink to-pink-500 shadow-[0_0_20px_rgba(254,60,114,0.35)]"
                    >
                      {t.common.next}
                    </motion.button>
                  </div>
                </motion.div>
              )}

              {step === 2 && (
                <motion.div
                  key="step-2"
                  initial={{ opacity: 0, x: 16 }}
                  animate={{ opacity: 1, x: 0 }}
                  exit={{ opacity: 0, x: -16 }}
                  transition={{ duration: 0.22 }}
                  className="flex flex-col gap-3"
                >
                  <div>
                    <h2 className="text-lg font-semibold text-white">{cityTitle}</h2>
                    <p className="text-sm text-neutral-400 mt-0.5">
                      {t.home.step2Subtitle}
                    </p>
                  </div>
                  <input
                    placeholder={t.home.cityPlaceholder}
                    value={city}
                    onFocus={onCityFocus}
                    onChange={onCityChange}
                    onKeyDown={handleStep2KeyDown}
                    autoComplete="address-level2"
                    className="bg-neutral-800 rounded-xl px-4 py-3 border border-white/5 focus:border-yumder-pink/60 outline-none transition-colors"
                  />
                  <div className="flex items-center gap-3 bg-neutral-800 rounded-xl px-4 py-3 border border-white/5">
                    <label className="text-sm text-neutral-400 whitespace-nowrap">{t.home.radiusLabel}</label>
                    <input
                      type="range"
                      min={1}
                      max={15}
                      value={radiusKm}
                      onChange={(e) => setRadiusKm(Number(e.target.value))}
                      className="flex-1 accent-yumder-pink"
                    />
                    <span className="text-sm w-14 text-right font-medium text-yumder-pink">
                      {radiusKm} km
                    </span>
                  </div>
                  <div className="flex gap-2 mt-1">
                    <button
                      type="button"
                      onClick={() => {
                        setError(null);
                        setStep(1);
                      }}
                      className="flex-1 rounded-xl px-4 py-3 text-sm font-medium text-neutral-300 bg-neutral-800 border border-white/5 hover:bg-neutral-700 transition-colors"
                    >
                      {t.common.back}
                    </button>
                    <motion.button
                      type="button"
                      whileTap={{ scale: 0.97 }}
                      disabled={!city.trim()}
                      onClick={goToStep3}
                      className="flex-[1.4] rounded-xl px-4 py-3 text-sm font-semibold bg-gradient-to-r from-yumder-pink to-pink-500 disabled:opacity-40 shadow-[0_0_20px_rgba(254,60,114,0.35)]"
                    >
                      {t.common.next}
                    </motion.button>
                  </div>
                </motion.div>
              )}

              {step === 3 && (
                <motion.div
                  key="step-3"
                  initial={{ opacity: 0, x: 16 }}
                  animate={{ opacity: 1, x: 0 }}
                  exit={{ opacity: 0, x: -16 }}
                  transition={{ duration: 0.22 }}
                  className="flex flex-col gap-3"
                >
                  <div>
                    <h2 className="text-lg font-semibold text-white">{t.home.step3Title}</h2>
                    <p className="text-sm text-neutral-400 mt-0.5">
                      {t.home.step3Subtitle}
                    </p>
                  </div>
                  <div>
                    <p className="text-sm text-neutral-400 mb-1">{t.home.cuisineLabel}</p>
                    <ToggleChipBar
                      options={cuisineOptions}
                      selected={cuisineTags}
                      onToggle={toggleCuisine}
                      searchable
                      leadingSlot={
                        <motion.button
                          type="button"
                          layout
                          onClick={spinCuisineWheel}
                          className="shrink-0 flex items-center gap-1.5 whitespace-nowrap text-sm font-medium bg-neutral-800 border border-yumder-pink/40 px-4 py-2 rounded-full text-yumder-pink hover:bg-neutral-700 transition-colors"
                        >
                          <motion.span
                            animate={spinningWheel ? { rotate: 360 } : { rotate: 0 }}
                            transition={{ duration: 0.6, ease: 'easeInOut' }}
                            className="relative inline-grid grid-cols-2 gap-[2px] h-3.5 w-3.5 rounded-[3px] border-[1.5px] border-yumder-pink p-[2px]"
                          >
                            <span className="h-[3px] w-[3px] rounded-full bg-yumder-pink" />
                            <span className="h-[3px] w-[3px] rounded-full bg-transparent" />
                            <span className="h-[3px] w-[3px] rounded-full bg-transparent" />
                            <span className="h-[3px] w-[3px] rounded-full bg-yumder-pink" />
                          </motion.span>
                          {t.home.diceButton}
                        </motion.button>
                      }
                    />
                  </div>
                  <div className="flex items-center justify-between bg-neutral-800 rounded-xl px-4 py-3 border border-white/5">
                    <div className="pr-3">
                      <span className="text-sm text-neutral-200 block">{t.home.excludeFastFoodLabel}</span>
                      <span className="text-xs text-neutral-500">
                        {excludeFastFood ? t.home.excludeFastFoodExcluded : t.home.excludeFastFoodAllowed}
                      </span>
                    </div>
                    <button
                      type="button"
                      aria-pressed={!excludeFastFood}
                      onClick={() => setExcludeFastFood((v) => !v)}
                      className={`relative h-6 w-11 shrink-0 rounded-full transition-colors ${
                        !excludeFastFood ? 'bg-yumder-pink' : 'bg-neutral-700'
                      }`}
                    >
                      <motion.div
                        animate={{ x: !excludeFastFood ? 20 : 0 }}
                        transition={{ type: 'spring', stiffness: 500, damping: 30 }}
                        className="absolute top-0.5 left-0.5 h-5 w-5 rounded-full bg-white shadow"
                      />
                    </button>
                  </div>
                  <div className="flex gap-2 mt-1">
                    <button
                      type="button"
                      onClick={() => {
                        setError(null);
                        setStep(2);
                      }}
                      className="flex-1 rounded-xl px-4 py-3 text-sm font-medium text-neutral-300 bg-neutral-800 border border-white/5 hover:bg-neutral-700 transition-colors"
                    >
                      {t.common.back}
                    </button>
                    <motion.button
                      type="button"
                      whileTap={{ scale: 0.97 }}
                      disabled={loading || !city.trim()}
                      onClick={handleCreate}
                      className="flex-[1.6] rounded-xl px-3 py-3 text-sm font-semibold bg-gradient-to-r from-yumder-pink to-pink-500 disabled:opacity-40 shadow-[0_0_20px_rgba(254,60,114,0.35)]"
                    >
                      {loading ? t.home.creatingButton : t.home.createButton}
                    </motion.button>
                  </div>
                </motion.div>
              )}
            </AnimatePresence>

            <AnimatePresence>
              {error && (
                <motion.p
                  initial={{ opacity: 0, x: 0 }}
                  animate={{ opacity: 1, x: [0, -6, 6, -4, 4, 0] }}
                  exit={{ opacity: 0 }}
                  transition={{ duration: 0.4 }}
                  className="text-red-400 text-sm"
                >
                  {error}
                </motion.p>
              )}
            </AnimatePresence>
          </motion.div>
        )}
      </AnimatePresence>

      <TutorialOverlay visible={showTutorial} onClose={() => setShowTutorial(false)} />

      <PwaInstallBanner />
    </main>
  );
}
