/* App root + auth screens */

/* === Auth (guest login / signup) ===================================== */

const AuthScreen = ({ onAccount }) => {
  const { wedding, adminLogin } = useStore();
  const [mode, setMode] = React.useState("login"); // login | signup | admin
  const [email, setEmail] = React.useState("");
  const [password, setPassword] = React.useState("");
  const [err, setErr] = React.useState("");
  const [busy, setBusy] = React.useState(false);

  const submit = async (e) => {
    e.preventDefault();
    setErr("");

    if (mode === "admin") {
      // Authentification auprès du serveur (mot de passe ADMIN_PASSWORD du .env).
      setBusy(true);
      try {
        await adminLogin(password.trim());
        onAccount({ role: "admin", email: "mariés@chavagnac", displayName: `${wedding.bride} & ${wedding.groom}` });
      } catch (ex) {
        setErr(ex.offline
          ? "Serveur injoignable — connexion admin impossible."
          : "Mot de passe incorrect.");
      } finally {
        setBusy(false);
      }
      return;
    }

    const mail = email.trim().toLowerCase();
    if (!mail) {
      setErr("Merci de renseigner votre adresse e-mail.");
      return;
    }
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(mail)) {
      setErr("Entre une adresse e-mail valide.");
      return;
    }
    onAccount({ role: "guest", email: mail, displayName: mail });
  };

  const isAdmin = mode === "admin";

  return (
    <div className="auth-stage">
      <div className={"auth-card" + (isAdmin ? " admin" : "")}>
        <div className="ornament">{isAdmin ? "♛" : "✦"}</div>

        <div className="center" style={{ marginBottom: 26 }}>
          <Crest initials={`${wedding.bride[0]} & ${wedding.groom[0]}`} />
          <div style={{
            fontFamily: "'Cormorant Garamond', serif",
            fontSize: 28, marginTop: 14
          }}>{wedding.bride} & {wedding.groom}</div>
          <div className="eyebrow" style={{ marginTop: 6 }}>{wedding.dateShort}</div>
        </div>

        <div className="center" style={{ marginBottom: 22 }}>
          <h2 style={{ fontSize: 24 }}>
            {mode === "login" && "Bon retour parmi nous"}
            {mode === "signup" && "Création de votre compte"}
            {mode === "admin" && "Espace des mariés"}
          </h2>
          <p className="muted" style={{ fontSize: 14, marginTop: 6 }}>
            {mode === "login" && "Entrez votre adresse e-mail pour accéder à l'invitation."}
            {mode === "signup" && "Votre adresse e-mail suffit pour rejoindre la fête."}
            {mode === "admin" && "Connectez-vous pour modifier le site à votre guise."}
          </p>
        </div>

        <form onSubmit={submit}>
          {mode !== "admin" && (
            <div className="field">
              <label>Adresse e-mail</label>
              <input
                type="email"
                value={email}
                onChange={e => setEmail(e.target.value)}
                placeholder="vous@exemple.fr"
                autoFocus
              />
            </div>
          )}
          {mode === "admin" && (
            <div className="field">
              <label>Mot de passe des mariés</label>
              <input
                type="password"
                value={password}
                onChange={e => setPassword(e.target.value)}
                placeholder="••••••••"
                autoFocus
              />
            </div>
          )}

          {err && <div className="error-msg">{err}</div>}

          <button type="submit" className="btn" style={{ width: "100%", marginTop: 8 }} disabled={busy}>
            {busy ? "Connexion…" : (
              <>
                {mode === "login" && "Se connecter"}
                {mode === "signup" && "Créer mon compte"}
                {mode === "admin" && "Entrer dans l'espace"}
              </>
            )}
          </button>
        </form>

        {mode === "admin" && (
          <div className="center" style={{ marginTop: 22, fontSize: 14 }}>
            <button className="link-btn" onClick={() => { setMode("login"); setErr(""); setPassword(""); }}>
              ← Retour à l'espace invités
            </button>
          </div>
        )}

        {mode !== "admin" && (
          <>
            <div style={{ margin: "24px 0 16px" }}>
              <Divider />
            </div>
            <div className="center">
              <button className="link-btn" onClick={() => { setMode("admin"); setErr(""); setPassword(""); }}>
                ♛ Accès des mariés
              </button>
            </div>
          </>
        )}
      </div>
    </div>
  );
};

/* === Profile picker =================================================== */

const ProfilePicker = ({ account, onPick, onLogout }) => {
  const { guests, addGuest, claimGuest } = useStore();
  const [selected, setSelected] = React.useState(null);
  const [filter, setFilter] = React.useState("");

  // Mode ajout (« je ne suis pas dans la liste »)
  const [adding, setAdding] = React.useState(false);
  const [newName, setNewName] = React.useState("");
  const [newSide, setNewSide] = React.useState("Lisa");
  const [err, setErr] = React.useState("");
  const [busy, setBusy] = React.useState(false);

  const visible = guests.filter(g =>
    g.name.toLowerCase().includes(filter.toLowerCase())
  );

  const fmtErr = (ex, fallback) =>
    ex.offline ? "Serveur injoignable — réessaie plus tard." : (ex.message || fallback);

  const startAdding = () => {
    setNewName(filter.trim());
    setErr("");
    setAdding(true);
  };

  // Réserve l'invité avec l'e-mail du compte puis entre sur le site.
  const choose = async (guest) => {
    setErr("");
    setBusy(true);
    try {
      const claimed = await claimGuest(guest.id, account.email);
      onPick(claimed);
    } catch (ex) {
      setErr(fmtErr(ex, "Impossible de sélectionner ce profil."));
      setBusy(false);
    }
  };

  const addSelf = async (e) => {
    e.preventDefault();
    const name = newName.trim();
    if (!name) { setErr("Merci d'indiquer votre nom."); return; }
    setErr("");
    setBusy(true);
    try {
      // Le serveur gère les doublons : si le nom existe déjà, il renvoie ce profil.
      const guest = await addGuest(name, newSide);
      const claimed = await claimGuest(guest.id, account.email);
      onPick(claimed);
    } catch (ex) {
      setErr(fmtErr(ex, "Impossible de t'ajouter à la liste."));
      setBusy(false);
    }
  };

  /* --- Formulaire d'auto-inscription --- */
  if (adding) {
    return (
      <div className="auth-stage">
        <div className="auth-card" style={{ maxWidth: 480 }}>
          <div className="ornament">✦</div>

          <div className="center" style={{ marginBottom: 22 }}>
            <div className="eyebrow">Bienvenue {account.displayName}</div>
            <h2 style={{ fontSize: 26, marginTop: 8 }}>Ajoutez-vous à la liste</h2>
            <p className="muted" style={{ fontSize: 14, marginTop: 8, maxWidth: 420, margin: "8px auto 0" }}>
              Vous ne figurez pas encore parmi nos invités ? Renseignez votre
              nom pour rejoindre la fête — vous apparaîtrez aussitôt dans la liste.
            </p>
          </div>

          <form onSubmit={addSelf}>
            <div className="field">
              <label>Votre nom</label>
              <input
                type="text"
                value={newName}
                onChange={e => setNewName(e.target.value)}
                placeholder="Romain Dupont"
                autoFocus
              />
            </div>
            <div className="field">
              <label>Vous êtes plutôt invité·e du côté de…</label>
              <select value={newSide} onChange={e => setNewSide(e.target.value)}>
                <option value="Lisa">Lisa</option>
                <option value="Thomas">Thomas</option>
                <option value="Les deux">Les deux</option>
              </select>
            </div>

            {err && <div className="error-msg">{err}</div>}

            <button type="submit" className="btn" style={{ width: "100%", marginTop: 8 }} disabled={busy}>
              {busy ? "Ajout en cours…" : "M'ajouter et continuer"}
            </button>
          </form>

          <div className="center" style={{ marginTop: 22 }}>
            <button className="link-btn" onClick={() => { setAdding(false); setErr(""); }}>
              ← Revenir à la liste
            </button>
          </div>
        </div>
      </div>
    );
  }

  /* --- Sélection dans la liste --- */
  return (
    <div className="auth-stage">
      <div className="auth-card" style={{ maxWidth: 720 }}>
        <div className="ornament">✦</div>

        <div className="center" style={{ marginBottom: 22 }}>
          <div className="eyebrow">Bienvenue {account.displayName}</div>
          <h2 style={{ fontSize: 28, marginTop: 8 }}>Qui êtes-vous parmi nos invités ?</h2>
          <p className="muted" style={{ fontSize: 14, marginTop: 8, maxWidth: 440, margin: "8px auto 0" }}>
            Sélectionnez votre profil dans la liste ci-dessous afin que nous
            puissions personnaliser votre invitation.
          </p>
        </div>

        <div className="field">
          <input
            type="text"
            value={filter}
            onChange={e => setFilter(e.target.value)}
            placeholder="Rechercher un prénom..."
          />
        </div>

        <div className="profile-grid" style={{ marginTop: 8, maxHeight: 360, overflowY: "auto", padding: 2 }}>
          {visible.map(g => (
            <button
              key={g.id}
              className={"profile-tile" + (selected?.id === g.id ? " selected" : "") + (g.claimed ? " claimed" : "")}
              onClick={() => !g.claimed && setSelected(g)}
              disabled={g.claimed}
              title={g.claimed ? "Profil déjà sélectionné par un autre invité" : undefined}
            >
              <div className="avatar-lg">{g.name[0]}</div>
              <div className="name">{g.name}</div>
              <div className="meta">{g.claimed ? "Déjà choisi" : (g.side ? `Côté ${g.side}` : "Invité")}</div>
            </button>
          ))}
          {visible.length === 0 && (
            <div className="muted" style={{ gridColumn: "1 / -1", textAlign: "center", padding: 24 }}>
              Aucun invité ne porte ce nom.{" "}
              <button className="link-btn" onClick={startAdding}>Ajoutez-vous à la liste</button>.
            </div>
          )}
        </div>

        <div className="center" style={{ marginTop: 18, fontSize: 14 }}>
          Vous ne vous trouvez pas ?{" "}
          <button className="link-btn" onClick={startAdding}>
            Ajoutez-vous à la liste
          </button>
        </div>

        {err && <div className="error-msg" style={{ marginTop: 14 }}>{err}</div>}

        <div style={{
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
          marginTop: 18,
          gap: 12,
          flexWrap: "wrap"
        }}>
          <button className="link-btn" onClick={onLogout}>Se déconnecter</button>
          <button
            className="btn"
            disabled={!selected || busy}
            onClick={() => selected && choose(selected)}
          >
            {busy ? "Sélection…" : (selected ? `Continuer en tant que ${selected.name}` : "Choisir un profil")}
          </button>
        </div>
      </div>
    </div>
  );
};

/* === Top bar ========================================================== */

const TopBar = ({ account, guest, active, onNav, onSwitchProfile, onLogout }) => {
  const { wedding } = useStore();
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);

  React.useEffect(() => {
    const close = (e) => {
      if (ref.current && !ref.current.contains(e.target)) setOpen(false);
    };
    document.addEventListener("mousedown", close);
    return () => document.removeEventListener("mousedown", close);
  }, []);

  const isAdmin = account.role === "admin";

  const items = [
    { id: "accueil", label: "Accueil" },
    { id: "infos",   label: "Informations" },
    { id: "jeux",    label: "Jeux" },
    ...(isAdmin ? [{ id: "admin", label: "Administration", admin: true }] : [])
  ];

  return (
    <header className="topbar">
      <div className="topbar-inner">
        <div className="brand" onClick={() => onNav("accueil")} style={{ cursor: "pointer" }}>
          <span>{wedding.bride}</span>
          <span className="amp">&</span>
          <span>{wedding.groom}</span>
        </div>
        <nav className="nav">
          {items.map(it => (
            <button
              key={it.id}
              className={"nav-item" + (active === it.id ? " active" : "") + (it.admin ? " admin-tab" : "")}
              onClick={() => onNav(it.id)}
            >{it.label}</button>
          ))}
        </nav>
        <div ref={ref} style={{ position: "relative" }}>
          <button className={"user-chip" + (isAdmin ? " admin" : "")} onClick={() => setOpen(o => !o)}>
            <span className="avatar">{(guest?.name || account.displayName || "?")[0]}</span>
            <span style={{ paddingRight: 4 }}>{guest?.name || account.displayName}</span>
            {isAdmin && <span className="badge">Mariés</span>}
            <span style={{ color: "var(--ink-muted)", fontSize: 11 }}>▾</span>
          </button>
          {open && (
            <div className="menu">
              {!isAdmin && (
                <button onClick={() => { setOpen(false); onSwitchProfile(); }}>
                  Changer de profil
                </button>
              )}
              {isAdmin && (
                <button onClick={() => { setOpen(false); onNav("admin"); }}>
                  Espace administration
                </button>
              )}
              <div className="sep"></div>
              <button onClick={() => { setOpen(false); onLogout(); }}>
                Se déconnecter
              </button>
            </div>
          )}
        </div>
      </div>
    </header>
  );
};

/* === App root ========================================================= */

const App = () => {
  const { adminLogout, findClaimedGuest } = useStore();
  const [account, setAccount] = useLocalStorage("wedding-account-v2", null);
  const [guest, setGuest] = useLocalStorage("wedding-guest-v2", null);
  const [view, setView] = useLocalStorage("wedding-view-v1", "site"); // "site" (page scrollable) | "admin"
  const [active, setActive] = React.useState("accueil");  // section visible (surlignage nav)

  // Auto-redirection : si l'e-mail a déjà réservé un profil, on saute la sélection.
  const [skipResolve, setSkipResolve] = React.useState(false); // « changer de profil »
  const [pickerReady, setPickerReady] = React.useState(false); // résolution terminée, aucun profil trouvé

  React.useEffect(() => {
    let cancelled = false;
    if (account && account.role === "guest" && !guest && !skipResolve) {
      setPickerReady(false);
      findClaimedGuest(account.email)
        .then((g) => { if (cancelled) return; if (g) setGuest(g); else setPickerReady(true); })
        .catch(() => { if (!cancelled) setPickerReady(true); });
    }
    return () => { cancelled = true; };
  }, [account, guest, skipResolve]);

  // Scroll-spy : surligne l'onglet de la section visible (vue site uniquement).
  React.useEffect(() => {
    if (view !== "site") return;
    const ids = ["accueil", "infos", "jeux"];
    const els = ids.map((id) => document.getElementById(id)).filter(Boolean);
    if (!els.length) return;
    const obs = new IntersectionObserver(
      (entries) => entries.forEach((e) => { if (e.isIntersecting) setActive(e.target.id); }),
      { rootMargin: "-45% 0px -50% 0px", threshold: 0 }
    );
    els.forEach((el) => obs.observe(el));
    return () => obs.disconnect();
  }, [view, guest, account]);

  const handleAccount = (acc) => {
    setAccount(acc);
    if (acc.role === "admin") setView("admin");
    else { setSkipResolve(false); setPickerReady(false); setView("site"); }
  };

  const fullLogout = () => {
    adminLogout();
    setSkipResolve(false);
    setPickerReady(false);
    setView("site");
    setAccount(null);
    setGuest(null);
  };

  const scrollToSection = (id) => {
    const el = document.getElementById(id);
    if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
  };
  const onNav = (id) => {
    if (id === "admin") { setView("admin"); window.scrollTo({ top: 0 }); return; }
    if (view !== "site") { setView("site"); setTimeout(() => scrollToSection(id), 60); }
    else scrollToSection(id);
  };

  if (!account) {
    return (<><SideFlowers /><AuthScreen onAccount={handleAccount} /></>);
  }

  const isAdmin = account.role === "admin";

  // For admin, build a pseudo-guest so HomePage greeting works.
  const effectiveGuest = isAdmin
    ? (guest || { id: "admin", name: account.displayName.split(" ")[0] || "Les mariés", side: "Les deux" })
    : guest;

  if (!isAdmin && !guest) {
    // Tant que la résolution e-mail → profil n'est pas finie, on patiente.
    if (!skipResolve && !pickerReady) {
      return (
        <>
          <SideFlowers />
          <div className="auth-stage">
            <div className="auth-card" style={{ textAlign: "center" }}>
              <div className="ornament">✦</div>
              <p className="muted">Connexion en cours…</p>
            </div>
          </div>
        </>
      );
    }
    return (
      <>
        <SideFlowers />
        <ProfilePicker
          account={account}
          onPick={setGuest}
          onLogout={fullLogout}
        />
      </>
    );
  }

  return (
    <>
      {view !== "admin" && <SideFlowers />}
      <div className="shell">
      <TopBar
        account={account}
        guest={effectiveGuest}
        active={view === "admin" ? "admin" : active}
        onNav={onNav}
        onSwitchProfile={() => { setSkipResolve(true); setGuest(null); }}
        onLogout={fullLogout}
      />
      {view === "admin" && isAdmin ? (
        <AdminPage />
      ) : (
        <>
          <section id="accueil" className="scroll-section"><HomePage guest={effectiveGuest} /></section>
          <section id="infos" className="scroll-section"><InfoPage guest={effectiveGuest} /></section>
          <section id="jeux" className="scroll-section"><GamePage guest={effectiveGuest} /></section>
        </>
      )}
      </div>
    </>
  );
};

const Root = () => (
  <StoreProvider>
    <App />
  </StoreProvider>
);

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Root />);
