// Vanday DAM — login screen

// After an OAuth (Google) sign-in/up, Clerk does a FULL-PAGE redirect. With no
// redirect specified it falls back to the Clerk dashboard default — which points
// at the marketing site (vanday.ai) — so Google sign-ins landed on the landing
// page instead of the app. Force the return to the app root ("/"), which Clerk
// resolves against the current origin: beta.vanday.ai in prod, vanday-dev.fly.dev
// in dev. A relative "/" keeps it correct across both Fly apps with no hardcoding,
// and (being a *fallback*) still yields to an explicit redirect_url for invites.
const CLERK_REDIRECT = {
  fallbackRedirectUrl: "/",
  signInFallbackRedirectUrl: "/",
  signUpFallbackRedirectUrl: "/",
};

// Pre-signup plan picker, shown on the sign-in screen when billing is live.
// Visitor picks a plan → onPick stashes it and opens Clerk sign-up → the trial
// auto-starts on that plan after the account is created.
function SignupPlanPicker({ plans, clerkReady, onPick, onSignIn }) {
  const [cycle, setCycle] = React.useState(() => {
    try { return window.localStorage.getItem("vanday_billing_cycle") || "annual"; }
    catch { return "annual"; }
  });
  const fmtPrice = (n) => (n == null ? "—" : `$${Number(n).toLocaleString("en-US", { maximumFractionDigits: 0 })}`);
  return (
    <div style={{ marginBottom: 18 }}>
      <div role="tablist" style={{
        display: "inline-flex", gap: 4, padding: 4, marginBottom: 14,
        background: "var(--surface-sunken, #f1efe9)", borderRadius: 10,
        position: "relative", left: "50%", transform: "translateX(-50%)", width: "fit-content",
      }}>
        {[["monthly", "Monthly"], ["annual", "Annual · save 20%"]].map(([id, label]) => (
          <button key={id} type="button" role="tab" aria-selected={cycle === id}
            onClick={() => { setCycle(id); try { window.localStorage.setItem("vanday_billing_cycle", id); } catch {} }}
            style={{
              border: "none", cursor: "pointer", padding: "7px 13px", borderRadius: 7, fontSize: 12.5,
              background: cycle === id ? "var(--surface, #fff)" : "transparent",
              color: cycle === id ? "var(--text)" : "var(--text-muted)",
              fontWeight: cycle === id ? 600 : 500,
              boxShadow: cycle === id ? "0 1px 2px rgba(0,0,0,0.06)" : "none",
            }}>{label}</button>
        ))}
      </div>
      <div style={{ display: "grid", gap: 8 }}>
        {plans.map((p) => {
          const price = p.pricing?.[cycle] ?? null;
          const perMonth = cycle === "annual" && price != null ? price / 12 : price;
          return (
            <div key={p.id} style={{
              display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12,
              border: "1px solid var(--border, #e7e6e0)", borderRadius: 12, padding: "12px 14px",
            }}>
              <div>
                <div style={{ fontWeight: 600, fontSize: 14.5 }}>{p.label}</div>
                <div style={{ fontSize: 12, color: "var(--text-muted)" }}>
                  {fmtPrice(perMonth)}/mo{cycle === "annual" && price != null ? ` · ${fmtPrice(price)}/yr after trial` : " after trial"}
                </div>
              </div>
              <button type="button" className="btn primary" disabled={!clerkReady}
                onClick={() => onPick(p.id, cycle)} style={{ whiteSpace: "nowrap", fontSize: 13 }}>
                {clerkReady ? "Start free trial" : "Loading…"}
              </button>
            </div>
          );
        })}
      </div>
      <div style={{ textAlign: "center", marginTop: 12, fontSize: 12.5, color: "var(--text-muted)" }}>
        14-day free trial · no credit card required.
      </div>
    </div>
  );
}

function LoginPage({ onLogin }) {
  const [email, setEmail] = React.useState("you@yourteam.com");
  const [password, setPassword] = React.useState("");
  const [error, setError] = React.useState(null);
  const [submitting, setSubmitting] = React.useState(false);

  // ---- Clerk integration --------------------------------------------------
  // Track whether the Clerk SDK has finished initialising. The HTML page
  // dispatches a `clerk-ready` event once Clerk.load() resolves.
  const [clerkReady, setClerkReady] = React.useState(window.__clerkReady === true);
  React.useEffect(() => {
    if (clerkReady) return;
    const onReady = () => setClerkReady(true);
    window.addEventListener("clerk-ready", onReady);
    return () => window.removeEventListener("clerk-ready", onReady);
  }, [clerkReady]);

  // If Clerk hasn't initialised within 10s, something is blocking it (an
  // ad-blocker blocking clerk.vanday.ai, an offline network, a script error).
  // Without this the sign-up/sign-in buttons sit on "Loading…" forever with no
  // explanation, so surface a clear retry instead of a dead-looking page.
  const [clerkTimedOut, setClerkTimedOut] = React.useState(false);
  React.useEffect(() => {
    if (clerkReady) { setClerkTimedOut(false); return; }
    const t = setTimeout(() => { if (!window.__clerkReady) setClerkTimedOut(true); }, 10000);
    return () => clearTimeout(t);
  }, [clerkReady]);

  // Fetch the public deployment config to know whether to show Clerk
  // sign-up/sign-in (beta) or just the password form (dev).
  const [config, setConfig] = React.useState(null);
  // Two-step signup (when billing is live): the entry screen offers Sign up /
  // Log in; clicking Sign up flips this to reveal the plan picker + trial copy.
  const [showPlans, setShowPlans] = React.useState(false);
  React.useEffect(() => {
    let stop = false;
    fetch("/api/config").then((r) => r.ok ? r.json() : { mode: "beta", clerkSignupEnabled: true })
      .then((d) => { if (!stop) setConfig(d); })
      .catch(() => { if (!stop) setConfig({ mode: "beta", clerkSignupEnabled: true }); });
    return () => { stop = true; };
  }, []);
  const showClerk = config ? config.clerkSignupEnabled : true;
  // When billing is rolled out, the sign-in screen becomes trial-only: visitors
  // pick a plan BEFORE signing up (no free-beta messaging). Off → keep the beta
  // experience for existing beta users.
  const billingLive = config?.billingLive === true;
  const signupPlans = Array.isArray(config?.plans) ? config.plans : [];

  // Stash the chosen plan so the trial auto-starts on it right after signup,
  // then open Clerk sign-up.
  const pickPlanThenSignUp = (planId, cycle) => {
    try {
      // localStorage (not sessionStorage): Clerk email verification can land in
      // a new tab, which would wipe a per-tab sessionStorage value and make the
      // app re-ask for a plan after sign-up. localStorage survives that.
      window.localStorage.setItem("vanday_signup_plan", planId);
      if (cycle) window.localStorage.setItem("vanday_signup_cycle", cycle);
    } catch {}
    openClerkSignUp();
  };

  // Best-effort: clear any leftover legacy session cookie from prior password
  // logins so it can't mask the Clerk identity on the server. Does NOT reload —
  // app.jsx's /api/me load attaches the Clerk token via the Authorization
  // header (not the cookie), so no reload is needed to authenticate.
  const clearLegacySession = React.useCallback(() => {
    try { fetch("/api/logout", { method: "POST" }); } catch {}
  }, []);

  // Once Clerk is ready, advance the user into the app as soon as a session
  // exists. The Google OAuth flow populates Clerk.user a short beat AFTER the
  // `clerk-ready` event fires, so a single point-in-time check misses it —
  // hence we poll briefly (with the SDK listener kept as a backstop). We only
  // ever call onLogin() to switch views; app.jsx's own /api/me load handles
  // provisioning + the welcome modal. Crucially this NEVER reloads the page.
  React.useEffect(() => {
    if (!clerkReady || !window.Clerk) return;
    let done = false;
    const advance = () => {
      if (done) return;
      done = true;
      clearLegacySession();
      onLogin();
    };

    if (window.Clerk.user) { advance(); return; }

    const iv = setInterval(() => {
      if (window.Clerk && window.Clerk.user) { clearInterval(iv); advance(); }
    }, 200);
    const stop = setTimeout(() => clearInterval(iv), 12000);
    let unsub;
    try {
      unsub = window.Clerk.addListener(({ user }) => {
        if (user) { clearInterval(iv); advance(); }
      });
    } catch {}

    return () => {
      done = true;
      clearInterval(iv);
      clearTimeout(stop);
      try { unsub && unsub(); } catch {}
    };
  }, [clerkReady, onLogin, clearLegacySession]);

  const openClerkSignIn = () => {
    if (!window.Clerk) return;
    // Already signed in (e.g. just came back from a Google flow) — go straight
    // into the app instead of reopening the modal.
    if (window.Clerk.user) { clearLegacySession(); onLogin(); return; }
    window.Clerk.openSignIn(CLERK_REDIRECT);
  };
  const openClerkSignUp = () => {
    if (!window.Clerk) return;
    if (window.Clerk.user) { clearLegacySession(); onLogin(); return; }
    window.Clerk.openSignUp(CLERK_REDIRECT);
  };

  // Invitees arrive via the email link (…/?join=invite). They don't have a
  // password — they need to CREATE an account with the invited email, after
  // which the server auto-joins them to the workspace. So when we see that
  // flag we lead with sign-up and open the Clerk sign-up form automatically.
  const invited = React.useMemo(() => {
    try { return new URLSearchParams(window.location.search).get("join") === "invite"; }
    catch { return false; }
  }, []);
  // Workspace the invitee is joining, passed as ?w= on the invite link. Used to
  // personalize the sign-up copy ("…for the Acme workspace").
  const inviteWorkspace = React.useMemo(() => {
    try {
      const w = new URLSearchParams(window.location.search).get("w");
      return w ? w.slice(0, 80) : null;
    } catch { return null; }
  }, []);
  // Stash the invite id (?i=) so it survives the Clerk sign-up popup. jfetch
  // reads this and sends it as the X-Vanday-Invite header so the server can
  // validate the invitee's email matches the invite (and auto-join them to the
  // right workspace).
  React.useEffect(() => {
    try {
      const params = new URLSearchParams(window.location.search);
      if (params.get("join") === "invite") {
        const i = params.get("i");
        if (i) window.sessionStorage.setItem("vanday_invite_id", i);
      }
    } catch {}
  }, []);
  const autoOpenedSignUp = React.useRef(false);
  React.useEffect(() => {
    if (!invited || !showClerk) return;
    if (!clerkReady || !window.Clerk || autoOpenedSignUp.current) return;
    if (window.Clerk.user) return; // already signed in — the other effect advances them
    autoOpenedSignUp.current = true;
    window.Clerk.openSignUp(CLERK_REDIRECT);
  }, [invited, showClerk, clerkReady]);

  // 8-tile asymmetric mosaic (Option C design refresh): five landscape
  // scenes interleaved with three team portraits. Each tile is placed via
  // its m-1..m-8 class in styles.css — order matters because the grid is
  // designed around portrait vs. landscape orientations per cell.
  const MOSAIC_TILES = [
    { cls: "m-1", src: "https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?w=900&q=70&auto=format&fit=crop" },        // Alps, landscape
    { cls: "m-2", src: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=600&q=70&auto=format&fit=crop" },        // portrait
    { cls: "m-3", src: "https://images.unsplash.com/photo-1521540216272-a50305cd4421?w=600&q=70&auto=format&fit=crop" },        // blossom
    { cls: "m-4", src: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=600&q=70&auto=format&fit=crop" },        // portrait
    { cls: "m-5", src: "https://images.unsplash.com/photo-1517022812141-23620dba5c23?w=900&q=70&auto=format&fit=crop" },        // horses
    { cls: "m-6", src: "https://images.unsplash.com/photo-1531123897727-8f129e1688ce?w=600&q=70&auto=format&fit=crop" },        // portrait
    { cls: "m-7", src: "https://images.unsplash.com/photo-1518709268805-4e9042af2176?w=600&q=70&auto=format&fit=crop" },        // arches
    { cls: "m-8", src: "https://images.unsplash.com/photo-1501594907352-04cda38ebc29?w=900&q=70&auto=format&fit=crop" },        // city/Lombard
  ];

  const submit = async (e) => {
    e.preventDefault();
    setError(null);
    setSubmitting(true);
    try {
      const r = await fetch("/api/login", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ password }),
      });
      if (r.status === 401) {
        setError("Wrong password.");
      } else if (!r.ok) {
        setError(`Couldn't reach the server (${r.status}). Is it running?`);
      } else {
        onLogin();
      }
    } catch (err) {
      setError("Couldn't reach the server. Is it running?");
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="login">
      <div className="login-form-side">
        <div className="login-brand">
          <div className="login-brand-mark">v.</div>
          <span>Vanday</span>
        </div>

        <div className="login-form-wrap">
          <h1 className="login-h">
            {invited
              ? "You're invited."
              : (showClerk
                  ? (billingLive
                      ? (showPlans ? "Start your free trial." : "Welcome to Vanday.")
                      : "Try the Vanday beta.")
                  : "Welcome back.")}
          </h1>
          <p className="login-sub">
            {invited
              ? (inviteWorkspace
                  ? `Create your account to join the ${inviteWorkspace} workspace.`
                  : "Create your account to join your team library.")
              : (showClerk
                  ? (billingLive
                      ? (showPlans
                          ? "Pick a plan and try Vanday free for 14 days — no credit card required."
                          : "Your whole photo library, auto-tagged, cropped, and instantly searchable.")
                      : "Sign up free and put your whole photo library to work — auto-tagged, cropped, and instantly searchable.")
                  : "Sign in to your team library.")}
          </p>

          {showClerk && clerkTimedOut && !clerkReady && (
            <div
              role="alert"
              style={{
                background: "oklch(0.97 0.03 24)",
                border: "1px solid oklch(0.85 0.08 24)",
                color: "oklch(0.45 0.16 24)",
                borderRadius: 10,
                padding: "12px 14px",
                marginBottom: 18,
                fontSize: 13,
                lineHeight: 1.5,
              }}
            >
              Sign-in is taking longer than usual — an ad blocker or network
              issue may be blocking it.{" "}
              <a
                href="#"
                onClick={(e) => { e.preventDefault(); window.location.reload(); }}
                style={{ color: "var(--brand)", fontWeight: 600 }}
              >
                Reload the page
              </a>{" "}
              to try again.
            </div>
          )}

          {invited && showClerk && (
            <div
              style={{
                background: "var(--surface-2, #f5f3ff)",
                border: "1px solid var(--border)",
                borderRadius: 10,
                padding: "14px 16px",
                marginBottom: 18,
                fontSize: 13.5,
              }}
            >
              <div style={{ fontWeight: 600, marginBottom: 4 }}>
                {inviteWorkspace ? `You've been invited to ${inviteWorkspace} 🎉` : "You've been invited to a workspace 🎉"}
              </div>
              <div style={{ color: "var(--text-muted)", marginBottom: 12 }}>
                Sign up with the email address your invite was sent to and you'll join your team automatically. You don't need a password yet — you'll create one now.
              </div>
              <button
                type="button"
                className="btn primary btn-block"
                onClick={openClerkSignUp}
                disabled={!clerkReady}
                title={clerkReady ? "Create your Vanday account" : "Loading…"}
              >
                {clerkReady ? "Create your account" : "Loading…"}
              </button>
              <div style={{ marginTop: 10, textAlign: "center", fontSize: 12.5, color: "var(--text-faint)" }}>
                Already have an account?{" "}
                <a
                  href="#"
                  onClick={(e) => { e.preventDefault(); openClerkSignIn(); }}
                  style={{ color: "var(--brand)", fontWeight: 500 }}
                >
                  Sign in
                </a>
              </div>
            </div>
          )}

          {/* Billing live, entry step → exactly two options: Sign up / Log in.
              Log in opens the Clerk sign-in modal (Google + email/password). */}
          {!invited && showClerk && billingLive && !showPlans && (
            <div style={{ marginBottom: 18, display: "flex", flexDirection: "column", gap: 10 }}>
              <button
                type="button"
                className="btn primary btn-block"
                onClick={() => setShowPlans(true)}
              >
                Sign up now
              </button>
              <button
                type="button"
                className="btn btn-block"
                onClick={openClerkSignIn}
                disabled={!clerkReady}
                title={clerkReady ? "Sign in with Google or password" : "Loading…"}
              >
                {clerkReady ? "Log in" : "Loading…"}
              </button>
            </div>
          )}

          {/* Billing live, plan step → pick a plan, then sign up (trial-only). */}
          {!invited && showClerk && billingLive && showPlans && signupPlans.length > 0 && (
            <div style={{ marginBottom: 18 }}>
              <SignupPlanPicker
                plans={signupPlans}
                clerkReady={clerkReady}
                onPick={pickPlanThenSignUp}
                onSignIn={openClerkSignIn}
              />
              <div style={{ textAlign: "center", marginTop: 4 }}>
                <a href="#" onClick={(e) => { e.preventDefault(); setShowPlans(false); }}
                  style={{ color: "var(--text-faint)", fontSize: 12.5 }}>← Back</a>
              </div>
            </div>
          )}

          {/* Billing not rolled out → keep the free-beta signup card. */}
          {!invited && showClerk && !billingLive && (
            <div
              style={{
                background: "var(--surface-2, #f5f3ff)",
                border: "1px solid var(--border)",
                borderRadius: 10,
                padding: "14px 16px",
                marginBottom: 18,
                fontSize: 13.5,
              }}
            >
              <div style={{ fontWeight: 600, marginBottom: 4 }}>
                Vanday is in free beta 🎉
              </div>
              <div style={{ color: "var(--text-muted)", marginBottom: 12 }}>
                Create your account to start uploading — no credit card, no setup. Your team library is ready in minutes.
              </div>
              <button
                type="button"
                className="btn primary btn-block"
                onClick={openClerkSignUp}
                disabled={!clerkReady}
                title={clerkReady ? "Create your Vanday account" : "Loading…"}
              >
                {clerkReady ? "Try the beta" : "Loading…"}
              </button>
            </div>
          )}

          {/* Beta (Clerk) mode: NO legacy email/password form. Users sign up
              or sign in exclusively through Clerk. Exactly two ways in: the
              primary "Try the beta" CTA above (Clerk sign-up — email OR Google)
              and the "Sign in" button below (Clerk sign-in — email OR Google).
              Google lives INSIDE both Clerk modals, so there's no separate
              social button. The old password form dropped people into an empty,
              shared workspace, so it's shown ONLY in dev mode (showClerk === false). */}
          {billingLive ? null : showClerk ? (
            <div>
              <button
                type="button"
                className="btn btn-block"
                onClick={openClerkSignIn}
                disabled={!clerkReady}
                title={clerkReady ? "Sign in to your account" : "Loading…"}
              >
                Sign in
              </button>
            </div>
          ) : (
            <form onSubmit={submit}>
              <div className="field">
                <label htmlFor="email">Work email</label>
                <input
                  id="email"
                  type="email"
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  autoComplete="email"
                />
              </div>
              <div className="field">
                <label htmlFor="password">Password</label>
                <input
                  id="password"
                  type="password"
                  value={password}
                  onChange={(e) => setPassword(e.target.value)}
                  autoComplete="current-password"
                  autoFocus
                  placeholder="Enter your password"
                />
              </div>

              {error && (
                <div style={{ color: "oklch(0.65 0.2 24)", fontSize: 12.5, marginBottom: 12 }}>
                  {error}
                </div>
              )}

              <button
                type="submit"
                className="btn primary btn-block"
                disabled={submitting || !password}
              >
                {submitting ? "Signing in…" : "Sign in"}
              </button>

              {config && config.mode === "dev" && (
                <div style={{ marginTop: 18, textAlign: "center", fontSize: 12, color: "var(--text-faint)" }}>
                  Dev build · password-only
                </div>
              )}
            </form>
          )}
        </div>

        <div className="login-foot">
          <span>© 2026 Vanday, Inc.</span>
          <span>
            <a href="https://vanday.ai/privacy" target="_blank" rel="noopener">Privacy</a> &nbsp;·&nbsp; <a href="https://vanday.ai/terms" target="_blank" rel="noopener">Terms</a> &nbsp;·&nbsp;{" "}
            <a href="https://vanday.ai/contact" target="_blank" rel="noopener">Help</a>
          </span>
        </div>
      </div>

      <div className="login-art-side">
        <div className="login-mosaic">
          {MOSAIC_TILES.map((t) => (
            <div
              key={t.cls}
              className={`login-m-tile ${t.cls}`}
              style={{ backgroundImage: `url('${t.src}')` }}
            />
          ))}
        </div>
        <div className="login-art-overlay" />
        <div className="login-art-content">
          <h2 className="login-art-h">
            Found <em>in a glance</em> — every shot from Tuscany to the Tidal Basin.
          </h2>
          <p className="login-art-p">
            Vanday auto-tags, crops and serves your team's images. Spend more time shooting, less time hunting.
          </p>
        </div>
      </div>
    </div>
  );
}

window.LoginPage = LoginPage;
