/* ============================================================
   VKTR TCO — Landing page / access gate (V1.7.5)
   ------------------------------------------------------------
   Design (discussed and confirmed 2026-07-09-10):
   - Replaces the previously fully-open guest tier with a hard gate in
     front of the WHOLE platform: either the shared guest password (set by
     admin, verified server-side by cf-worker, never shipped to the
     client) or a signed-in account with accessGranted (auto for @vktr.id,
     otherwise admin-approved via the Admin Panel's Access Requests tab --
     no email service, approve/deny happens directly in-app).
   - Explicitly a UI-level deterrent, NOT a real security boundary: this
     app has no build step, so its JS/data ships publicly via Firebase
     Hosting to anyone who can reach the URL, gate or not (see CLAUDE.md).
     Confirmed acceptable for the current data sensitivity bar -- a
     stronger bar (blocking even a technically capable extractor) would
     need gating Hosting itself, e.g. Cloudflare Access, noted as a
     documented future step, not built now.
   - Guest-gate session persistence: a plain localStorage flag (the
     lighter option, matching the "casual deterrent" bar) -- Firebase
     Auth's own "stay signed in" is separate and already the SDK default
     (see auth.jsx's explicit setPersistence(LOCAL) call).
   ============================================================ */

const GUEST_GATE_KEY = "vktr_guest_gate_passed_v1";

const GuestGateStore = {
  passed() { try { return localStorage.getItem(GUEST_GATE_KEY) === "1"; } catch (e) { return false; } },
  setPassed() { try { localStorage.setItem(GUEST_GATE_KEY, "1"); } catch (e) {} },
  clear() { try { localStorage.removeItem(GUEST_GATE_KEY); } catch (e) {} },
};

async function verifyGuestPassword(password) {
  if (!window.API_PROXY_URL || window.API_PROXY_URL === "REPLACE_ME") throw new Error("API proxy not configured yet");
  const res = await fetch(window.API_PROXY_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ action: "verify_guest_password", password }),
  });
  const data = await res.json();
  if (!res.ok) throw new Error(data.error || `Request failed (${res.status})`);
  return !!data.ok;
}

function LandingScreen({ onGuestPassed }) {
  const { lang, setLang } = useLang();
  const { signInGoogle, signInMicrosoft } = useAuth();
  const [mode, setMode] = React.useState("choose"); // choose | guest
  const [password, setPassword] = React.useState("");
  const [status, setStatus] = React.useState("idle"); // idle | checking | error
  const [errorMsg, setErrorMsg] = React.useState("");

  const submitGuest = async (e) => {
    e.preventDefault();
    if (!password.trim() || status === "checking") return;
    setStatus("checking"); setErrorMsg("");
    try {
      const ok = await verifyGuestPassword(password.trim());
      if (ok) {
        GuestGateStore.setPassed();
        onGuestPassed();
      } else {
        setStatus("error");
        setErrorMsg(tr(lang, "Incorrect password.", "Kata sandi salah."));
      }
    } catch (err) {
      setStatus("error");
      setErrorMsg(tr(lang, "Couldn't reach the server — try again.", "Tidak bisa menghubungi server — coba lagi."));
    }
  };

  return (
    <div className="landing-screen">
      <div className="landing-card">
        <div className="landing-lang">
          <span className={lang === "id" ? "on" : ""} onClick={() => setLang("id")}>ID</span>
          <span className={lang === "en" ? "on" : ""} onClick={() => setLang("en")}>EN</span>
        </div>
        <img className="landing-logo" src="assets/vktr-white-horizontal.png" alt="VKTR" />
        <h1><Tr en="TCO Competitive Analysis Platform" id="Platform Analisis Kompetitif TCO" /></h1>
        <p className="landing-sub">
          <Tr en="Internal access only. Sign in with your VKTR account, or continue as guest with the shared access password."
              id="Hanya untuk akses internal. Masuk dengan akun VKTR Anda, atau lanjutkan sebagai tamu dengan kata sandi akses bersama." />
        </p>

        {mode === "choose" && (
          <div className="landing-actions">
            <button type="button" className="btn btn-primary" onClick={signInGoogle}>
              🟢 <Tr en="Sign in with Google" id="Masuk dengan Google" />
            </button>
            <button type="button" className="btn btn-primary" onClick={signInMicrosoft}>
              🟦 <Tr en="Sign in with Microsoft" id="Masuk dengan Microsoft" />
            </button>
            <button type="button" className="btn btn-ghost" onClick={() => setMode("guest")}>
              👤 <Tr en="Continue as guest" id="Lanjutkan sebagai tamu" />
            </button>
          </div>
        )}

        {mode === "guest" && (
          <form className="landing-actions" onSubmit={submitGuest}>
            <input
              type="password"
              className="input landing-password"
              placeholder={tr(lang, "Guest access password", "Kata sandi akses tamu")}
              value={password}
              autoFocus
              disabled={status === "checking"}
              onChange={(e) => { setPassword(e.target.value); setStatus("idle"); }}
            />
            {status === "error" && <div className="landing-error">{errorMsg}</div>}
            <button type="submit" className="btn btn-primary" disabled={status === "checking" || !password.trim()}>
              {status === "checking" ? <Tr en="Checking…" id="Memeriksa…" /> : <Tr en="Continue" id="Lanjutkan" />}
            </button>
            <button type="button" className="btn btn-ghost" onClick={() => { setMode("choose"); setPassword(""); setStatus("idle"); }}>
              <Tr en="← Back" id="← Kembali" />
            </button>
          </form>
        )}
      </div>
    </div>
  );
}

function AccessRequestScreen() {
  const { lang } = useLang();
  const { user, profile, requestAccess, signOutUser } = useAuth();
  const [note, setNote] = React.useState("");
  const [sent, setSent] = React.useState(false);
  // v1.9.8 (2026-07-21): requestAccess now reports whether the Firestore
  // write actually landed -- previously this screen claimed success
  // unconditionally the instant the button was clicked, so a silently
  // failed write still told the requester "pending admin approval" with
  // nothing to contradict it. See auth.jsx's requestAccess for the full
  // account of the bug this caused.
  const [submitting, setSubmitting] = React.useState(false);
  const [submitError, setSubmitError] = React.useState(false);

  const submit = async () => {
    setSubmitting(true);
    setSubmitError(false);
    const ok = await requestAccess(note);
    setSubmitting(false);
    if (ok) setSent(true); else setSubmitError(true);
  };

  const alreadyRequested = !!profile.accessRequestedAt || sent;
  const denied = !!profile.accessDenied;

  return (
    <div className="landing-screen">
      <div className="landing-card">
        <img className="landing-logo" src="assets/vktr-white-horizontal.png" alt="VKTR" />
        <h1><Tr en="Access required" id="Akses diperlukan" /></h1>
        <p className="landing-sub">
          {tr(lang, "Signed in as", "Masuk sebagai")} <b>{user.email}</b>.{" "}
          {denied
            ? tr(lang, "Your access request was denied.", "Permintaan akses Anda ditolak.")
            : alreadyRequested
            ? tr(lang, "Your access request is pending admin approval.", "Permintaan akses Anda menunggu persetujuan admin.")
            : tr(lang, "This account doesn't have access yet — request it below.", "Akun ini belum memiliki akses — ajukan permintaan di bawah.")}
        </p>

        {!alreadyRequested && !denied && (
          <div className="landing-actions">
            <textarea
              className="input"
              rows={3}
              placeholder={tr(lang, "Optional note (e.g. your role/company)", "Catatan opsional (mis. peran/perusahaan Anda)")}
              value={note}
              onChange={(e) => setNote(e.target.value)}
            />
            <button type="button" className="btn btn-primary" disabled={submitting} onClick={submit}>
              {submitting ? tr(lang, "Sending…", "Mengirim…") : <Tr en="Request access" id="Ajukan akses" />}
            </button>
            {submitError && (
              <div className="landing-error">
                <Tr en="Couldn't send your request — check your connection and try again." id="Gagal mengirim permintaan Anda — periksa koneksi Anda dan coba lagi." />
              </div>
            )}
          </div>
        )}
        {denied && (
          <div className="landing-actions">
            <button type="button" className="btn btn-primary" disabled={submitting} onClick={submit}>
              {submitting ? tr(lang, "Sending…", "Mengirim…") : <Tr en="Request again" id="Ajukan lagi" />}
            </button>
            {submitError && (
              <div className="landing-error">
                <Tr en="Couldn't send your request — check your connection and try again." id="Gagal mengirim permintaan Anda — periksa koneksi Anda dan coba lagi." />
              </div>
            )}
          </div>
        )}
        <button type="button" className="btn btn-ghost" style={{ marginTop: 10 }} onClick={signOutUser}>
          ↪ <Tr en="Sign out" id="Keluar" />
        </button>
      </div>
    </div>
  );
}

// v1.9.9 (2026-07-21) audit: both of these returned `null` -- a genuinely
// blank white page, no spinner, no message -- for (a) the normal brief
// window while Firebase Auth/the profile doc first resolve on every fresh
// load, and (b) a real dead end: if the profile Firestore listener ever
// errors (network blip, Firestore temporarily unreachable), auth.jsx's
// error callback sets loading=false without ever setting a profile, and
// this component had no way out of that state short of the user guessing
// to hard-refresh. First impression matters for a platform being handed
// off as a final deliverable -- a stuck blank screen reads as "broken,"
// not "loading."
function AccessGateLoading() {
  return (
    <div className="landing-screen">
      <div className="landing-card">
        <img className="landing-logo" src="assets/vktr-white-horizontal.png" alt="VKTR" />
        <p className="landing-sub"><Tr en="Loading…" id="Memuat…" /></p>
      </div>
    </div>
  );
}

function AccessGateError() {
  const { lang } = useLang();
  return (
    <div className="landing-screen">
      <div className="landing-card">
        <img className="landing-logo" src="assets/vktr-white-horizontal.png" alt="VKTR" />
        <h1><Tr en="Couldn't load your account" id="Gagal memuat akun Anda" /></h1>
        <p className="landing-sub">
          <Tr en="This is usually a temporary connection issue." id="Ini biasanya masalah koneksi sementara." />
        </p>
        <div className="landing-actions">
          <button type="button" className="btn btn-primary" onClick={() => window.location.reload()}>
            {tr(lang, "Reload", "Muat ulang")}
          </button>
        </div>
      </div>
    </div>
  );
}

function AccessGate({ children }) {
  const { user, profile, loading } = useAuth();
  const [guestPassed, setGuestPassed] = React.useState(GuestGateStore.passed());

  if (loading) return <AccessGateLoading />;

  if (user) {
    if (!profile) return <AccessGateError />; // loading is false but no profile ever arrived -- the listener's error path, not a normal transient state
    if (window.hasAccess(profile)) return children;
    return <AccessRequestScreen />;
  }

  if (guestPassed) return children;

  return <LandingScreen onGuestPassed={() => setGuestPassed(true)} />;
}

Object.assign(window, { AccessGate, GuestGateStore, verifyGuestPassword });
