// Gestopia login + signup — real Supabase auth
// Supabase client available as window.__supabase

const { useState: useStateLogin, useEffect: useEffectLogin } = React;

// ─────────────────────────────────────────────────────────────
// Helpers
// ─────────────────────────────────────────────────────────────
const sb = () => window.__supabase;

// Translate Supabase error messages to French
function frenchError(msg) {
  if (!msg) return "Une erreur est survenue.";
  const m = msg.toLowerCase();
  if (m.includes("invalid login")) return "Email ou mot de passe incorrect.";
  if (m.includes("email not confirmed")) return "Veuillez confirmer votre email avant de vous connecter. Vérifiez votre boîte de réception.";
  if (m.includes("user already registered")) return "Un compte existe déjà avec cet email.";
  if (m.includes("password should be at least")) return "Le mot de passe doit contenir au moins 6 caractères.";
  if (m.includes("signup is disabled")) return "Les inscriptions sont temporairement désactivées.";
  if (m.includes("rate limit")) return "Trop de tentatives. Réessayez dans quelques minutes.";
  if (m.includes("email rate limit")) return "Trop d'emails envoyés. Réessayez dans quelques minutes.";
  if (m.includes("invalid email")) return "Adresse email invalide.";
  if (m.includes("weak password")) return "Mot de passe trop faible. Utilisez au moins 8 caractères.";
  if (m.includes("network") || m.includes("fetch")) return "Erreur réseau. Vérifiez votre connexion.";
  return msg;
}

// ─────────────────────────────────────────────────────────────
// Icons
// ─────────────────────────────────────────────────────────────
function GoogleIcon({ size = 18 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
      <path fill="#4285F4" d="M17.64 9.2c0-.64-.06-1.25-.17-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62z"/>
      <path fill="#34A853" d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.81.54-1.84.86-3.04.86a5.27 5.27 0 0 1-4.96-3.65H1.02v2.34A9 9 0 0 0 9 18z"/>
      <path fill="#FBBC05" d="M4.04 10.77a5.4 5.4 0 0 1 0-3.44V4.99H1.02a9 9 0 0 0 0 8.02l3.02-2.24z"/>
      <path fill="#EA4335" d="M9 3.58c1.32 0 2.5.45 3.44 1.34l2.58-2.58A9 9 0 0 0 9 0a9 9 0 0 0-7.98 4.99l3.02 2.34A5.27 5.27 0 0 1 9 3.58z"/>
    </svg>
  );
}

function EyeIcon({ shown, size = 18 }) {
  if (shown) {
    return (
      <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
        <path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z"/>
        <circle cx="12" cy="12" r="3"/>
      </svg>
    );
  }
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <path d="M9.88 5.08A10.7 10.7 0 0 1 12 5c6.5 0 10 7 10 7a18 18 0 0 1-3.07 3.94"/>
      <path d="M6.6 6.6A18 18 0 0 0 2 12s3.5 7 10 7c1.7 0 3.24-.36 4.6-.94"/>
      <path d="M14.12 14.12A3 3 0 1 1 9.88 9.88"/>
      <line x1="3" y1="3" x2="21" y2="21"/>
    </svg>
  );
}

function PasswordField({ id, label, placeholder, value, onChange, autoComplete, rightLink }) {
  const [shown, setShown] = useStateLogin(false);
  return (
    <div className="field" style={{ position: "relative" }}>
      <label
        htmlFor={id}
        style={
          rightLink
            ? { display: "flex", justifyContent: "space-between", alignItems: "center" }
            : undefined
        }
      >
        <span>{label}</span>
        {rightLink}
      </label>
      <div style={{ position: "relative" }}>
        <input
          id={id}
          type={shown ? "text" : "password"}
          autoComplete={autoComplete}
          placeholder={placeholder}
          value={value}
          onChange={(e) => onChange(e.target.value)}
          style={{ width: "100%", paddingRight: 44 }}
        />
        <button
          type="button"
          onClick={() => setShown((s) => !s)}
          aria-label={shown ? "Masquer le mot de passe" : "Afficher le mot de passe"}
          aria-pressed={shown}
          tabIndex={-1}
          style={{
            position: "absolute",
            right: 8,
            top: "50%",
            transform: "translateY(-50%)",
            width: 32,
            height: 32,
            display: "grid",
            placeItems: "center",
            border: "none",
            background: "transparent",
            cursor: "pointer",
            color: shown ? "var(--accent)" : "var(--fg-faint)",
            transition: "color 140ms ease",
          }}
          onMouseEnter={(e) => { if (!shown) e.currentTarget.style.color = "var(--fg-dim)"; }}
          onMouseLeave={(e) => { if (!shown) e.currentTarget.style.color = "var(--fg-faint)"; }}
        >
          <EyeIcon shown={shown} />
        </button>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// AuthShell — shared layout for all auth views
// ─────────────────────────────────────────────────────────────
function AuthShell({ children, setView, mode = "login" }) {
  return (
    <div className="login-shell" style={{ background: "var(--bg)", color: "var(--fg)" }}>
      {/* LEFT: form */}
      <div
        style={{
          padding: "32px 48px",
          display: "flex",
          flexDirection: "column",
          minHeight: "100vh",
        }}
      >
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
          <Logo size={26} onClick={() => setView("landing")} />
          <button
            onClick={() => setView("landing")}
            className="btn btn-sm"
            style={{ color: "var(--fg-dim)" }}
          >
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 12 }}>←</span>
            Retour
          </button>
        </div>

        <div style={{ flex: 1, display: "flex", flexDirection: "column", justifyContent: "center", maxWidth: 420, width: "100%", margin: "0 auto" }}>
          {children}
        </div>

        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            color: "var(--fg-faint)",
            fontFamily: "var(--font-mono)",
            fontSize: 11,
            letterSpacing: "0.08em",
            textTransform: "uppercase",
          }}
        >
          <span>© 2026 Gestopia</span>
          <span>Statut · Confidentialité · CGU</span>
        </div>
      </div>

      {/* RIGHT: contextual panel */}
      <AuthSidePanel setView={setView} mode={mode} />
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Login — email/password + Google
// ─────────────────────────────────────────────────────────────
function Login({ setView }) {
  const [email, setEmail] = useStateLogin("");
  const [password, setPassword] = useStateLogin("");
  const [loading, setLoading] = useStateLogin(false);
  const [googleLoading, setGoogleLoading] = useStateLogin(false);
  const [error, setError] = useStateLogin("");

  async function handleGoogle() {
    setError("");
    setGoogleLoading(true);
    try {
      const { error } = await sb().auth.signInWithOAuth({
        provider: "google",
        options: {
          redirectTo: window.location.origin + window.location.pathname,
        },
      });
      if (error) setError(frenchError(error.message));
    } catch (err) {
      setError(frenchError(err.message));
    }
    setGoogleLoading(false);
  }

  async function handleSubmit(e) {
    e.preventDefault();
    setError("");
    if (!email.includes("@")) { setError("Email invalide."); return; }
    if (password.length < 4) { setError("Mot de passe requis."); return; }
    setLoading(true);
    try {
      const { error } = await sb().auth.signInWithPassword({ email, password });
      if (error) setError(frenchError(error.message));
      // Success is handled by onAuthStateChange in App
    } catch (err) {
      setError(frenchError(err.message));
    }
    setLoading(false);
  }

  return (
    <AuthShell setView={setView} mode="login">
      <div className="mono-eyebrow" style={{ marginBottom: 20 }}>ATELIER · CONNEXION</div>
      <h1
        style={{
          fontFamily: "var(--font-display)",
          fontSize: "clamp(36px, 4.6vw, 54px)",
          fontWeight: 600,
          letterSpacing: "-0.025em",
          lineHeight: 1.02,
          margin: "0 0 12px",
          textWrap: "balance",
        }}
      >
        Bon retour à l'atelier.
      </h1>
      <p style={{ color: "var(--fg-dim)", fontSize: 15, lineHeight: 1.55, margin: "0 0 36px" }}>
        Connectez-vous pour reprendre vos tickets en cours, votre stock et votre caisse.
      </p>

      {/* Google */}
      <button
        type="button"
        className="btn"
        style={{
          width: "100%",
          height: 48,
          background: "var(--surface)",
          border: "1px solid var(--line-strong)",
          color: "var(--fg)",
          justifyContent: "center",
          borderRadius: 10,
          fontSize: 14.5,
          opacity: googleLoading ? 0.7 : 1,
        }}
        onClick={handleGoogle}
        disabled={googleLoading}
      >
        {googleLoading ? (
          <>
            <span className="dash-pulse" style={{ display: "inline-block", width: 8, height: 8, borderRadius: 999, background: "var(--fg)" }} />
            Redirection…
          </>
        ) : (
          <>
            <GoogleIcon />
            Continuer avec Google
          </>
        )}
      </button>

      {/* Divider */}
      <div
        style={{
          display: "flex",
          alignItems: "center",
          gap: 14,
          margin: "26px 0",
          color: "var(--fg-faint)",
        }}
      >
        <div style={{ flex: 1, height: 1, background: "var(--line)" }} />
        <span className="mono-eyebrow" style={{ fontSize: 10 }}>OU AVEC EMAIL</span>
        <div style={{ flex: 1, height: 1, background: "var(--line)" }} />
      </div>

      <form onSubmit={handleSubmit} style={{ display: "flex", flexDirection: "column", gap: 14 }}>
        <div className={"field" + (error && !email.includes("@") ? " field-error" : "")}>
          <label htmlFor="email">EMAIL</label>
          <input
            id="email"
            type="email"
            autoComplete="email"
            placeholder="vous@atelier.fr"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
          />
        </div>

        <PasswordField
          id="password"
          label="MOT DE PASSE"
          placeholder="••••••••"
          autoComplete="current-password"
          value={password}
          onChange={setPassword}
          rightLink={
            <button
              type="button"
              onClick={() => setView("forgot")}
              className="ulink"
              style={{
                textTransform: "none",
                letterSpacing: 0,
                fontFamily: "var(--font-ui)",
                color: "var(--fg-dim)",
                fontSize: 12,
              }}
            >
              Oublié ?
            </button>
          }
        />

        {error && (
          <div className="field-msg" role="alert">
            {error}
          </div>
        )}

        <button
          type="submit"
          className="btn btn-primary"
          style={{ width: "100%", height: 48, justifyContent: "center", borderRadius: 10, marginTop: 4 }}
          disabled={loading}
        >
          {loading ? (
            <>
              <span className="dash-pulse" style={{ display: "inline-block", width: 8, height: 8, borderRadius: 999, background: "var(--bg)" }} />
              Connexion…
            </>
          ) : (
            <>
              Se connecter
              <span style={{ fontFamily: "var(--font-mono)" }}>→</span>
            </>
          )}
        </button>
      </form>

      <p style={{ marginTop: 28, fontSize: 14, color: "var(--fg-dim)" }}>
        Pas encore de compte ?{" "}
        <button
          onClick={() => setView("signup")}
          className="ulink"
          style={{ color: "var(--fg)", fontWeight: 500 }}
        >
          Créer un atelier
        </button>
      </p>
    </AuthShell>
  );
}

// ─────────────────────────────────────────────────────────────
// Signup — email/password + Google
// ─────────────────────────────────────────────────────────────
function Signup({ setView }) {
  const [name, setName] = useStateLogin("");
  const [shop, setShop] = useStateLogin("");
  const [email, setEmail] = useStateLogin("");
  const [password, setPassword] = useStateLogin("");
  const [loading, setLoading] = useStateLogin(false);
  const [googleLoading, setGoogleLoading] = useStateLogin(false);
  const [error, setError] = useStateLogin("");

  async function handleGoogle() {
    setError("");
    setGoogleLoading(true);
    try {
      const { error } = await sb().auth.signInWithOAuth({
        provider: "google",
        options: {
          redirectTo: window.location.origin + window.location.pathname,
        },
      });
      if (error) setError(frenchError(error.message));
    } catch (err) {
      setError(frenchError(err.message));
    }
    setGoogleLoading(false);
  }

  async function handleSubmit(e) {
    e.preventDefault();
    setError("");
    if (!name || !shop) { setError("Indiquez votre nom et le nom de votre atelier."); return; }
    if (!email.includes("@")) { setError("Email invalide."); return; }
    if (password.length < 8) { setError("Au moins 8 caractères pour le mot de passe."); return; }
    setLoading(true);
    try {
      const { data, error } = await sb().auth.signUp({
        email,
        password,
        options: {
          data: {
            full_name: name,
            shop_name: shop,
          },
          emailRedirectTo: window.location.origin + window.location.pathname,
        },
      });
      if (error) {
        setError(frenchError(error.message));
      } else {
        // If email confirmation is enabled, user won't be auto-logged in.
        // Show the check-email screen.
        // Store email for display on the check-email page.
        window.__pendingEmail = email;
        window.__pendingName = name;
        setView("check-email");
      }
    } catch (err) {
      setError(frenchError(err.message));
    }
    setLoading(false);
  }

  return (
    <AuthShell setView={setView} mode="signup">
      <div className="mono-eyebrow" style={{ marginBottom: 20 }}>NOUVEAU · ESSAI 14 JOURS</div>
      <h1
        style={{
          fontFamily: "var(--font-display)",
          fontSize: "clamp(36px, 4.6vw, 54px)",
          fontWeight: 600,
          letterSpacing: "-0.025em",
          lineHeight: 1.02,
          margin: "0 0 12px",
          textWrap: "balance",
        }}
      >
        Ouvrons votre atelier.
      </h1>
      <p style={{ color: "var(--fg-dim)", fontSize: 15, lineHeight: 1.55, margin: "0 0 32px" }}>
        14 jours pour tout tester. Aucune carte bancaire. Vous gardez vos données.
      </p>

      <button
        type="button"
        className="btn"
        style={{
          width: "100%",
          height: 48,
          background: "var(--surface)",
          border: "1px solid var(--line-strong)",
          color: "var(--fg)",
          justifyContent: "center",
          borderRadius: 10,
          fontSize: 14.5,
          opacity: googleLoading ? 0.7 : 1,
        }}
        onClick={handleGoogle}
        disabled={googleLoading}
      >
        {googleLoading ? (
          <>
            <span className="dash-pulse" style={{ display: "inline-block", width: 8, height: 8, borderRadius: 999, background: "var(--fg)" }} />
            Redirection…
          </>
        ) : (
          <>
            <GoogleIcon />
            S'inscrire avec Google
          </>
        )}
      </button>

      <div style={{ display: "flex", alignItems: "center", gap: 14, margin: "22px 0", color: "var(--fg-faint)" }}>
        <div style={{ flex: 1, height: 1, background: "var(--line)" }} />
        <span className="mono-eyebrow" style={{ fontSize: 10 }}>OU AVEC EMAIL</span>
        <div style={{ flex: 1, height: 1, background: "var(--line)" }} />
      </div>

      <form onSubmit={handleSubmit} style={{ display: "flex", flexDirection: "column", gap: 12 }}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
          <div className="field">
            <label htmlFor="name">VOTRE NOM</label>
            <input id="name" type="text" placeholder="Jean Dupont" value={name} onChange={(e) => setName(e.target.value)} />
          </div>
          <div className="field">
            <label htmlFor="shop">ATELIER</label>
            <input id="shop" type="text" placeholder="Phone Repair Lyon" value={shop} onChange={(e) => setShop(e.target.value)} />
          </div>
        </div>

        <div className="field">
          <label htmlFor="email2">EMAIL</label>
          <input id="email2" type="email" placeholder="vous@atelier.fr" value={email} onChange={(e) => setEmail(e.target.value)} />
        </div>

        <PasswordField
          id="password2"
          label="MOT DE PASSE"
          placeholder="8 caractères minimum"
          autoComplete="new-password"
          value={password}
          onChange={setPassword}
        />

        {error && <div className="field-msg" role="alert">{error}</div>}

        <button
          type="submit"
          className="btn btn-accent"
          style={{ width: "100%", height: 48, justifyContent: "center", borderRadius: 10, marginTop: 8 }}
          disabled={loading}
        >
          {loading ? (
            <>
              <span className="dash-pulse" style={{ display: "inline-block", width: 8, height: 8, borderRadius: 999, background: "#fff" }} />
              Création…
            </>
          ) : (
            <>
              Créer mon atelier
              <span style={{ fontFamily: "var(--font-mono)" }}>→</span>
            </>
          )}
        </button>

        <p style={{ color: "var(--fg-faint)", fontSize: 12, lineHeight: 1.5, margin: "10px 0 0" }}>
          En continuant, vous acceptez nos{" "}
          <a href="#" className="ulink" style={{ color: "var(--fg-dim)" }}>CGU</a> et notre{" "}
          <a href="#" className="ulink" style={{ color: "var(--fg-dim)" }}>politique de confidentialité</a>.
        </p>
      </form>

      <p style={{ marginTop: 24, fontSize: 14, color: "var(--fg-dim)" }}>
        Déjà un compte ?{" "}
        <button onClick={() => setView("login")} className="ulink" style={{ color: "var(--fg)", fontWeight: 500 }}>
          Se connecter
        </button>
      </p>
    </AuthShell>
  );
}

// ─────────────────────────────────────────────────────────────
// ForgotPassword — request a password reset email
// ─────────────────────────────────────────────────────────────
function ForgotPassword({ setView }) {
  const [email, setEmail] = useStateLogin("");
  const [loading, setLoading] = useStateLogin(false);
  const [sent, setSent] = useStateLogin(false);
  const [error, setError] = useStateLogin("");

  async function handleSubmit(e) {
    e.preventDefault();
    setError("");
    if (!email.includes("@")) { setError("Email invalide."); return; }
    setLoading(true);
    try {
      const { error } = await sb().auth.resetPasswordForEmail(email, {
        redirectTo: window.location.origin + window.location.pathname,
      });
      if (error) {
        setError(frenchError(error.message));
      } else {
        setSent(true);
      }
    } catch (err) {
      setError(frenchError(err.message));
    }
    setLoading(false);
  }

  return (
    <AuthShell setView={setView} mode="login">
      <div className="mono-eyebrow" style={{ marginBottom: 20 }}>ATELIER · RÉINITIALISATION</div>
      <h1
        style={{
          fontFamily: "var(--font-display)",
          fontSize: "clamp(32px, 4vw, 48px)",
          fontWeight: 600,
          letterSpacing: "-0.025em",
          lineHeight: 1.05,
          margin: "0 0 12px",
          textWrap: "balance",
        }}
      >
        {sent ? "Email envoyé." : "Mot de passe oublié ?"}
      </h1>

      {sent ? (
        <div>
          <p style={{ color: "var(--fg-dim)", fontSize: 15, lineHeight: 1.6, margin: "0 0 12px" }}>
            Si un compte existe pour <strong style={{ color: "var(--fg)" }}>{email}</strong>,
            vous recevrez un lien de réinitialisation dans quelques instants.
          </p>
          <p style={{ color: "var(--fg-faint)", fontSize: 13, lineHeight: 1.5, margin: "0 0 32px" }}>
            Pensez à vérifier vos spams. Le lien expire dans 1 heure.
          </p>

          {/* Mail icon */}
          <div style={{ display: "flex", justifyContent: "center", margin: "32px 0" }}>
            <div style={{
              width: 80, height: 80, borderRadius: 20,
              background: "var(--accent-soft)",
              display: "grid", placeItems: "center",
            }}>
              <svg width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
                <rect x="2" y="4" width="20" height="16" rx="2" />
                <path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" />
              </svg>
            </div>
          </div>

          <div style={{ display: "flex", gap: 12, marginTop: 24 }}>
            <button onClick={() => { setSent(false); setEmail(""); }} className="btn btn-ghost" style={{ flex: 1, justifyContent: "center", borderRadius: 10 }}>
              Renvoyer
            </button>
            <button onClick={() => setView("login")} className="btn btn-primary" style={{ flex: 1, justifyContent: "center", borderRadius: 10 }}>
              Retour connexion
            </button>
          </div>
        </div>
      ) : (
        <div>
          <p style={{ color: "var(--fg-dim)", fontSize: 15, lineHeight: 1.55, margin: "0 0 32px" }}>
            Entrez l'email de votre compte. Nous vous enverrons un lien pour créer un nouveau mot de passe.
          </p>

          <form onSubmit={handleSubmit} style={{ display: "flex", flexDirection: "column", gap: 14 }}>
            <div className={"field" + (error ? " field-error" : "")}>
              <label htmlFor="reset-email">EMAIL</label>
              <input
                id="reset-email"
                type="email"
                autoComplete="email"
                placeholder="vous@atelier.fr"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                autoFocus
              />
            </div>

            {error && <div className="field-msg" role="alert">{error}</div>}

            <button
              type="submit"
              className="btn btn-accent"
              style={{ width: "100%", height: 48, justifyContent: "center", borderRadius: 10, marginTop: 4 }}
              disabled={loading}
            >
              {loading ? (
                <>
                  <span className="dash-pulse" style={{ display: "inline-block", width: 8, height: 8, borderRadius: 999, background: "#fff" }} />
                  Envoi…
                </>
              ) : (
                <>
                  Envoyer le lien
                  <span style={{ fontFamily: "var(--font-mono)" }}>→</span>
                </>
              )}
            </button>
          </form>

          <p style={{ marginTop: 24, fontSize: 14, color: "var(--fg-dim)" }}>
            <button onClick={() => setView("login")} className="ulink" style={{ color: "var(--fg)", fontWeight: 500 }}>
              ← Retour à la connexion
            </button>
          </p>
        </div>
      )}
    </AuthShell>
  );
}

// ─────────────────────────────────────────────────────────────
// UpdatePassword — set new password after clicking reset link
// ─────────────────────────────────────────────────────────────
function UpdatePassword({ setView, onDone }) {
  const [password, setPassword] = useStateLogin("");
  const [confirm, setConfirm] = useStateLogin("");
  const [loading, setLoading] = useStateLogin(false);
  const [error, setError] = useStateLogin("");

  async function handleSubmit(e) {
    e.preventDefault();
    setError("");
    if (password.length < 8) { setError("Au moins 8 caractères."); return; }
    if (password !== confirm) { setError("Les mots de passe ne correspondent pas."); return; }
    setLoading(true);
    try {
      const { error } = await sb().auth.updateUser({ password });
      if (error) {
        setError(frenchError(error.message));
      } else {
        if (onDone) onDone();
      }
    } catch (err) {
      setError(frenchError(err.message));
    }
    setLoading(false);
  }

  return (
    <AuthShell setView={setView} mode="login">
      <div className="mono-eyebrow" style={{ marginBottom: 20 }}>ATELIER · NOUVEAU MOT DE PASSE</div>
      <h1
        style={{
          fontFamily: "var(--font-display)",
          fontSize: "clamp(32px, 4vw, 48px)",
          fontWeight: 600,
          letterSpacing: "-0.025em",
          lineHeight: 1.05,
          margin: "0 0 12px",
          textWrap: "balance",
        }}
      >
        Nouveau mot de passe
      </h1>
      <p style={{ color: "var(--fg-dim)", fontSize: 15, lineHeight: 1.55, margin: "0 0 32px" }}>
        Choisissez un mot de passe sécurisé pour protéger votre atelier.
      </p>

      <form onSubmit={handleSubmit} style={{ display: "flex", flexDirection: "column", gap: 14 }}>
        <PasswordField
          id="new-pass"
          label="NOUVEAU MOT DE PASSE"
          placeholder="8 caractères minimum"
          autoComplete="new-password"
          value={password}
          onChange={setPassword}
        />
        <PasswordField
          id="confirm-pass"
          label="CONFIRMER"
          placeholder="Retapez le mot de passe"
          autoComplete="new-password"
          value={confirm}
          onChange={setConfirm}
        />

        {error && <div className="field-msg" role="alert">{error}</div>}

        <button
          type="submit"
          className="btn btn-accent"
          style={{ width: "100%", height: 48, justifyContent: "center", borderRadius: 10, marginTop: 4 }}
          disabled={loading}
        >
          {loading ? (
            <>
              <span className="dash-pulse" style={{ display: "inline-block", width: 8, height: 8, borderRadius: 999, background: "#fff" }} />
              Mise à jour…
            </>
          ) : (
            <>
              Enregistrer
              <span style={{ fontFamily: "var(--font-mono)" }}>→</span>
            </>
          )}
        </button>
      </form>
    </AuthShell>
  );
}

// ─────────────────────────────────────────────────────────────
// CheckEmail — shown after signup
// ─────────────────────────────────────────────────────────────
function CheckEmail({ setView }) {
  const email = window.__pendingEmail || "votre adresse";
  const name = window.__pendingName || "";

  return (
    <div
      style={{
        minHeight: "100vh",
        background: "var(--bg)",
        color: "var(--fg)",
        display: "flex",
        flexDirection: "column",
        alignItems: "center",
        justifyContent: "center",
        padding: 32,
        textAlign: "center",
        position: "relative",
      }}
    >
      {/* Top bar */}
      <div style={{ position: "absolute", top: 32, left: 48 }}>
        <Logo size={26} onClick={() => setView("landing")} />
      </div>

      {/* Mail icon */}
      <div style={{
        width: 100, height: 100, borderRadius: 24,
        background: "var(--accent-soft)",
        display: "grid", placeItems: "center",
        marginBottom: 32,
      }}>
        <svg width="44" height="44" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
          <rect x="2" y="4" width="20" height="16" rx="2" />
          <path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" />
        </svg>
      </div>

      <div className="mono-eyebrow" style={{ color: "var(--accent)", marginBottom: 16 }}>
        VÉRIFICATION REQUISE
      </div>

      <h1
        style={{
          fontFamily: "var(--font-display)",
          fontSize: "clamp(36px, 5vw, 56px)",
          fontWeight: 700,
          letterSpacing: "-0.03em",
          lineHeight: 1.02,
          margin: "0 0 20px",
        }}
      >
        Vérifiez votre email
      </h1>

      <p style={{
        color: "var(--fg-dim)",
        fontSize: 16,
        lineHeight: 1.6,
        maxWidth: 440,
        margin: "0 0 8px",
      }}>
        {name ? `${name}, un` : "Un"} email de confirmation a été envoyé à
      </p>
      <p style={{
        color: "var(--fg)",
        fontSize: 17,
        fontWeight: 600,
        margin: "0 0 28px",
      }}>
        {email}
      </p>
      <p style={{
        color: "var(--fg-faint)",
        fontSize: 14,
        lineHeight: 1.5,
        maxWidth: 380,
        margin: "0 0 40px",
      }}>
        Cliquez sur le lien dans l'email pour activer votre compte.
        Pensez à vérifier vos spams.
      </p>

      <div style={{ display: "flex", gap: 12 }}>
        <button onClick={() => setView("login")} className="btn btn-primary" style={{ borderRadius: 10 }}>
          J'ai confirmé — me connecter
          <span style={{ fontFamily: "var(--font-mono)" }}>→</span>
        </button>
      </div>

      <p style={{ marginTop: 24, fontSize: 13, color: "var(--fg-faint)" }}>
        Pas reçu ?{" "}
        <button
          onClick={async () => {
            if (email && email !== "votre adresse") {
              await sb().auth.resend({ type: "signup", email });
              alert("Email renvoyé !");
            }
          }}
          className="ulink"
          style={{ color: "var(--fg-dim)" }}
        >
          Renvoyer l'email
        </button>
      </p>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// SuccessView — shown after successful authentication
// ─────────────────────────────────────────────────────────────
function SuccessView({ session, setView, onLogout }) {
  const user = session?.user;
  const email = user?.email || "";
  const name = user?.user_metadata?.full_name || user?.user_metadata?.name || "";
  const shop = user?.user_metadata?.shop_name || "";
  const provider = user?.app_metadata?.provider || "email";
  const isGoogle = provider === "google";

  return (
    <div
      className="grain"
      style={{
        minHeight: "100vh",
        background: "var(--bg)",
        color: "var(--fg)",
        display: "flex",
        flexDirection: "column",
        alignItems: "center",
        justifyContent: "center",
        padding: 32,
        textAlign: "center",
        position: "relative",
        overflow: "hidden",
      }}
    >
      {/* Background glow */}
      <div
        aria-hidden="true"
        className="glow-pulse"
        style={{
          position: "absolute",
          left: "50%",
          top: "30%",
          transform: "translate(-50%, -50%)",
          width: "min(700px, 90vw)",
          height: "min(500px, 60vh)",
          background: "radial-gradient(ellipse at center, color-mix(in oklab, var(--accent) 28%, transparent), transparent 60%)",
          filter: "blur(40px)",
          pointerEvents: "none",
        }}
      />

      {/* Top bar */}
      <div style={{ position: "absolute", top: 32, left: 48, right: 48, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <Logo size={26} onClick={() => setView("landing")} />
        <button onClick={onLogout} className="btn btn-sm btn-ghost">
          Déconnexion
        </button>
      </div>

      {/* Animated checkmark */}
      <div style={{
        position: "relative",
        width: 120, height: 120,
        marginBottom: 36,
      }}>
        <svg width="120" height="120" viewBox="0 0 120 120" style={{ position: "absolute", inset: 0 }}>
          <circle
            cx="60" cy="60" r="54"
            fill="none"
            stroke="var(--accent)"
            strokeWidth="2.5"
            strokeDasharray="340"
            strokeDashoffset="0"
            style={{
              animation: "circle-draw 800ms cubic-bezier(0.65, 0, 0.35, 1) both",
              opacity: 0.3,
            }}
          />
          <circle
            cx="60" cy="60" r="54"
            fill="var(--accent-soft)"
          />
        </svg>
        <svg
          width="48" height="48"
          viewBox="0 0 48 48"
          style={{
            position: "absolute",
            left: "50%",
            top: "50%",
            transform: "translate(-50%, -50%)",
          }}
        >
          <polyline
            points="12,24 20,33 36,15"
            fill="none"
            stroke="var(--accent)"
            strokeWidth="3.5"
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeDasharray="48"
            style={{
              animation: "check-draw 500ms 400ms cubic-bezier(0.65, 0, 0.35, 1) both",
            }}
          />
        </svg>
      </div>

      <div
        className="mono-eyebrow"
        style={{ color: "var(--accent)", marginBottom: 16 }}
      >
        {isGoogle ? "AUTHENTIFICATION GOOGLE" : "AUTHENTIFICATION EMAIL"}
      </div>

      <h1
        style={{
          fontFamily: "var(--font-display)",
          fontSize: "clamp(44px, 6vw, 72px)",
          fontWeight: 700,
          letterSpacing: "-0.035em",
          lineHeight: 1,
          margin: "0 0 20px",
          animation: "success-fade-in 700ms 600ms cubic-bezier(0.16, 0.84, 0.28, 1) both",
        }}
      >
        Connexion réussie
      </h1>

      {name && (
        <p style={{
          fontSize: 20,
          fontWeight: 500,
          margin: "0 0 8px",
          animation: "success-fade-in 700ms 750ms cubic-bezier(0.16, 0.84, 0.28, 1) both",
        }}>
          Bienvenue{name ? `, ${name}` : ""} 👋
        </p>
      )}

      <p style={{
        color: "var(--fg-dim)",
        fontSize: 15,
        margin: "0 0 8px",
        animation: "success-fade-in 700ms 850ms cubic-bezier(0.16, 0.84, 0.28, 1) both",
      }}>
        {email}
      </p>

      {shop && (
        <p style={{
          color: "var(--fg-faint)",
          fontSize: 14,
          margin: "0 0 8px",
          animation: "success-fade-in 700ms 950ms cubic-bezier(0.16, 0.84, 0.28, 1) both",
        }}>
          Atelier : {shop}
        </p>
      )}

      {/* Code-style session card */}
      <div
        style={{
          border: "1px solid var(--line)",
          borderRadius: 12,
          background: "color-mix(in oklab, var(--surface) 60%, transparent)",
          backdropFilter: "blur(8px)",
          padding: 20,
          marginTop: 32,
          maxWidth: 400,
          width: "100%",
          textAlign: "left",
          animation: "success-fade-in 700ms 1000ms cubic-bezier(0.16, 0.84, 0.28, 1) both",
        }}
      >
        <div style={{
          fontFamily: "var(--font-mono)",
          fontSize: 11,
          color: "var(--fg-faint)",
          letterSpacing: "0.1em",
          textTransform: "uppercase",
          marginBottom: 12,
        }}>
          $ gestopia session
        </div>
        <div style={{
          fontFamily: "var(--font-mono)",
          fontSize: 12.5,
          color: "var(--fg-dim)",
          lineHeight: 1.7,
        }}>
          <div>→ statut : <span style={{ color: "var(--accent)" }}>● connecté</span></div>
          <div>→ méthode : <span style={{ color: "var(--fg)" }}>{isGoogle ? "Google OAuth" : "email"}</span></div>
          <div>→ email : <span style={{ color: "var(--fg)" }}>{email}</span></div>
          {shop && <div>→ atelier : <span style={{ color: "var(--fg)" }}>{shop}</span></div>}
          <div>→ essai : <span style={{ color: "var(--accent)" }}>14 jours restants</span></div>
        </div>
      </div>

      <p style={{
        color: "var(--fg-faint)",
        fontSize: 14,
        marginTop: 28,
        animation: "success-fade-in 700ms 1100ms cubic-bezier(0.16, 0.84, 0.28, 1) both",
      }}>
        Le tableau de bord arrive bientôt. Vous serez notifié par email.
      </p>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// AuthSidePanel — right panel for Login & Signup
// ─────────────────────────────────────────────────────────────
function AuthSidePanel({ setView, mode = "login" }) {
  const isLogin = mode === "login";

  const config = isLogin
    ? {
        eyebrow: "↳ NOUVEAU SUR GESTOPIA",
        titlePre: "Démarrez en ",
        titleAccent: "10 minutes.",
        titleSuf: "",
        body: "Un seul outil pour tickets, stock, clients, caisse et factures — pensé avec et pour les réparateurs indépendants.",
        bullets: [
          ["10 min", "Pour ouvrir votre 1ᵉʳ ticket de réparation."],
          ["14 jours", "D'essai gratuit, sans carte bancaire."],
          ["0 €", "Pour migrer vos données depuis votre outil actuel."],
          ["24/7", "Vos données sont hébergées en France, chiffrées au repos."],
        ],
        ctaLabel: "Créer un atelier",
        ctaAction: () => setView("signup"),
      }
    : {
        eyebrow: "↳ DÉJÀ INSCRIT ?",
        titlePre: "Retrouvez votre ",
        titleAccent: "atelier.",
        titleSuf: "",
        body: "Vos tickets en cours, votre stock, votre caisse — tout est là où vous l'avez laissé. Connectez-vous en un clic.",
        bullets: [
          ["1 clic", "Connexion par Google ou email."],
          ["Hors ligne", "L'app fonctionne même sans internet à l'atelier."],
          ["2FA", "Authentification renforcée disponible pour tous."],
          ["UE", "Données en France, jamais hors d'Europe."],
        ],
        ctaLabel: "Se connecter à mon atelier",
        ctaAction: () => setView("login"),
      };

  return (
    <div
      className="login-right grain"
      style={{
        position: "relative",
        background: "var(--bg-2)",
        borderLeft: "1px solid var(--line)",
        padding: "32px 48px",
        display: "flex",
        flexDirection: "column",
        justifyContent: "space-between",
        minHeight: "100vh",
        overflow: "hidden",
      }}
    >
      <div
        aria-hidden="true"
        style={{
          position: "absolute",
          right: -150,
          bottom: -150,
          width: 500,
          height: 500,
          background: "radial-gradient(circle at center, var(--accent), transparent 60%)",
          opacity: 0.25,
          filter: "blur(60px)",
          pointerEvents: "none",
        }}
      />

      <div style={{ position: "relative", zIndex: 1, display: "flex", justifyContent: "flex-end" }}>
        <div className="mono-eyebrow">{isLogin ? "DÉMARRAGE / 00" : "RETOUR / 00"}</div>
      </div>

      <div style={{ position: "relative", zIndex: 1, maxWidth: 480 }}>
        <div className="mono-eyebrow" style={{ color: "var(--accent)", marginBottom: 20 }}>
          {config.eyebrow}
        </div>
        <h2
          style={{
            fontFamily: "var(--font-display)",
            fontSize: "clamp(40px, 4.4vw, 64px)",
            fontWeight: 700,
            letterSpacing: "-0.03em",
            lineHeight: 1,
            margin: "0 0 24px",
            textWrap: "balance",
          }}
        >
          {config.titlePre}
          <span style={{ color: "var(--accent)" }}>{config.titleAccent}</span>
          {config.titleSuf}
        </h2>
        <p
          style={{
            color: "var(--fg-dim)",
            fontSize: 16,
            lineHeight: 1.55,
            margin: "0 0 40px",
            textWrap: "pretty",
          }}
        >
          {config.body}
        </p>

        <ul
          style={{
            listStyle: "none",
            padding: 0,
            margin: "0 0 40px",
            display: "flex",
            flexDirection: "column",
            gap: 18,
          }}
        >
          {config.bullets.map(([k, v], i) => (
            <li
              key={i}
              style={{
                display: "grid",
                gridTemplateColumns: "100px 1fr",
                gap: 16,
                alignItems: "baseline",
              }}
            >
              <span style={{
                fontFamily: "var(--font-display)",
                fontSize: 22,
                fontWeight: 700,
                letterSpacing: "-0.02em",
                color: "var(--accent)",
              }}>
                {k}
              </span>
              <span style={{ color: "var(--fg-dim)", fontSize: 14.5, lineHeight: 1.5 }}>
                {v}
              </span>
            </li>
          ))}
        </ul>

        <button onClick={config.ctaAction} className="btn btn-lg btn-accent">
          {config.ctaLabel}
          <span style={{ fontFamily: "var(--font-mono)" }}>→</span>
        </button>
      </div>

      <div
        style={{
          position: "relative",
          zIndex: 1,
          border: "1px solid var(--line)",
          borderRadius: 12,
          background: "color-mix(in oklab, var(--bg) 70%, transparent)",
          backdropFilter: "blur(6px)",
          padding: 18,
          marginTop: 32,
          maxWidth: 480,
        }}
      >
        <div style={{
          fontFamily: "var(--font-mono)",
          fontSize: 11,
          color: "var(--fg-faint)",
          letterSpacing: "0.1em",
          textTransform: "uppercase",
          marginBottom: 10,
        }}>
          {isLogin ? "$ gestopia ticket nouveau" : "$ gestopia atelier ouvrir"}
        </div>
        <div style={{
          fontFamily: "var(--font-mono)",
          fontSize: 12.5,
          color: "var(--fg-dim)",
          lineHeight: 1.6,
        }}>
          {isLogin ? (
            <>
              <div>→ client : <span style={{ color: "var(--fg)" }}>M. Bertrand</span></div>
              <div>→ appareil : <span style={{ color: "var(--fg)" }}>iPhone 13 (IMEI 35…)</span></div>
              <div>→ panne : <span style={{ color: "var(--fg)" }}>écran cassé</span></div>
              <div>→ devis : <span style={{ color: "var(--accent)" }}>89 € · prêt</span></div>
            </>
          ) : (
            <>
              <div>→ nom : <span style={{ color: "var(--fg)" }}>Phone Repair Lyon</span></div>
              <div>→ utilisateurs : <span style={{ color: "var(--fg)" }}>1 (vous)</span></div>
              <div>→ migration : <span style={{ color: "var(--fg)" }}>0 fichier importé</span></div>
              <div>→ statut : <span style={{ color: "var(--accent)" }}>● prêt à démarrer</span></div>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Login, Signup, ForgotPassword, UpdatePassword, CheckEmail, SuccessView });
