/* Registration / sign-in with Google (Google Identity Services).
   The browser gets a Google ID token, our backend verifies it (/api/auth-google)
   and returns the profile, which we keep in localStorage. No passwords; no secret
   key in the client. Set window.GOOGLE_CLIENT_ID in index.html (see GOOGLE_AUTH_SETUP.md). */

const GOOGLE_CLIENT_ID = (typeof window !== "undefined" && window.GOOGLE_CLIENT_ID) || "";
const AUTH_API = (typeof window !== "undefined" && window.IDEAL_OFFER_API) || "/api";
const USER_KEY = "io-user";

function readUser() { try { return JSON.parse(localStorage.getItem(USER_KEY)) || null; } catch (e) { return null; } }
function writeUser(u) {
  try { u ? localStorage.setItem(USER_KEY, JSON.stringify(u)) : localStorage.removeItem(USER_KEY); } catch (e) {}
  window.dispatchEvent(new CustomEvent("io-user"));
}
function useUser() {
  const [user, setU] = useState(readUser);
  useEffect(() => {
    const h = () => setU(readUser());
    window.addEventListener("io-user", h);
    return () => window.removeEventListener("io-user", h);
  }, []);
  return user;
}
function signOut() {
  writeUser(null);
  try { if (window.google && google.accounts && google.accounts.id) google.accounts.id.disableAutoSelect(); } catch (e) {}
  window.navigate("/");
}

// ── anonymous analytics: a stable per-browser visitor id + a fire-and-forget tracker
function getVisitorId() {
  try {
    let v = localStorage.getItem("io-visitor");
    if (!v) { v = "v_" + Math.random().toString(36).slice(2, 10) + Date.now().toString(36); localStorage.setItem("io-visitor", v); }
    return v;
  } catch (e) { return "v_anon"; }
}
function track(event, moduleId) {
  try {
    fetch(AUTH_API + "/track", {
      method: "POST", headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ event, moduleId, visitorId: getVisitorId() }),
    }).catch(() => {});
  } catch (e) {}
}

// Refresh the signed-in user's paid status from the server (so unlocked content
// and hidden Enroll CTAs survive a reload / a purchase on another device).
function refreshMe() {
  const u = readUser();
  if (!u || !u.token) return;
  fetch(AUTH_API + "/me", { headers: { Authorization: "Bearer " + u.token } })
    .then((r) => (r.ok ? r.json() : null))
    .then((d) => {
      if (d && typeof d.paid === "boolean") {
        const cur = readUser();
        if (cur && cur.token && cur.paid !== d.paid) writeUser({ ...cur, paid: d.paid });
      }
    })
    .catch(() => {});
}

// Exchange the Google ID-token credential for a backend-verified profile.
async function exchangeGoogleCredential(credential) {
  const res = await fetch(AUTH_API + "/auth-google", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ credential }),
  });
  const data = await res.json().catch(() => ({}));
  if (!res.ok || !data.user) throw new Error(data.error || "Sign-in failed. Please try again.");
  return data; // { user, token }
}

// Programmatic sign-in for custom (colorful) buttons: initializes GIS and shows
// Google's sign-in prompt. On success the verified user is written (writeUser),
// so callers just watch `useUser()`. If the prompt can't be shown (third-party
// cookies / FedCM blocked, One-Tap cooldown), opts.onUnavailable fires so the
// caller can fall back to the standard <GoogleButton/>. Returns false if GIS
// isn't ready yet. Keeps the same ID-token flow the backend already verifies.
function signInWithGoogle(opts) {
  opts = opts || {};
  if (!GOOGLE_CLIENT_ID || !(window.google && google.accounts && google.accounts.id)) return false;
  google.accounts.id.initialize({
    client_id: GOOGLE_CLIENT_ID,
    callback: async (resp) => {
      try {
        const { user, token } = await exchangeGoogleCredential(resp.credential);
        writeUser({ ...user, token });
      } catch (e) { opts.onError && opts.onError(e.message); }
    },
  });
  try {
    google.accounts.id.prompt((n) => {
      let cant = false;
      try { cant = (n.isNotDisplayed && n.isNotDisplayed()) || (n.isSkippedMoment && n.isSkippedMoment()); } catch (e) { cant = false; }
      if (cant && opts.onUnavailable) opts.onUnavailable();
    });
  } catch (e) { if (opts.onUnavailable) opts.onUnavailable(); }
  return true;
}

// Renders Google's official button into a div and wires the callback.
function GoogleButton({ onError }) {
  const ref = useRef(null);
  useEffect(() => {
    if (!GOOGLE_CLIENT_ID) return;
    let stop = false, timer = null;
    const init = () => {
      if (stop || !(window.google && google.accounts && google.accounts.id)) return false;
      google.accounts.id.initialize({
        client_id: GOOGLE_CLIENT_ID,
        callback: async (resp) => {
          try {
            const { user, token } = await exchangeGoogleCredential(resp.credential);
            writeUser({ ...user, token }); // keep the session token for progress reporting
          } catch (e) { onError && onError(e.message); }
        },
      });
      if (ref.current) {
        google.accounts.id.renderButton(ref.current, {
          theme: "outline", size: "large", shape: "pill", text: "continue_with", width: 300,
        });
      }
      return true;
    };
    if (!init()) { timer = setInterval(() => { if (init()) clearInterval(timer); }, 200); setTimeout(() => clearInterval(timer), 6000); }
    return () => { stop = true; if (timer) clearInterval(timer); };
  }, []);
  return <div ref={ref} className="po-gbtn" />;
}

/* The /#/signup page - also serves as the signed-in "account" view. */
function Signup() {
  const user = useUser();
  const [error, setError] = useState(null);
  const configured = !!GOOGLE_CLIENT_ID;

  return (
    <main className="po-auth">
      <div className="wrap po-auth-wrap">
        <div className="po-auth-card card reveal">
          {user ? (
            <>
              <div className="po-auth-id">
                {user.picture
                  ? <img src={user.picture} alt="" className="po-auth-avatar" referrerPolicy="no-referrer" />
                  : <span className="po-auth-avatar po-auth-avatar-fallback">{(user.name || user.email || "?").charAt(0).toUpperCase()}</span>}
                <div>
                  <span className="po-auth-tag mono">Signed in</span>
                  <h1>{user.name || "Welcome"}</h1>
                  <p className="po-auth-email">{user.email}</p>
                </div>
              </div>
              <div className="po-auth-actions">
                <a className="btn btn-primary" href="/learn/module-1">Start with Module 1 <Icon name="arrow" size={17} /></a>
                {!user.paid && <a className="btn btn-ghost" href="/checkout"><Icon name="badge" size={16} /> Get the full course</a>}
              </div>
              {user.paid && <OutcomeSurvey />}
              {user.paid && <RefundRequest />}
              <button className="po-auth-signout" onClick={signOut}>Sign out</button>
            </>
          ) : (
            <>
              <span className="eyebrow"><Icon name="user" size={15} /> Create your account</span>
              <h1>Join beHired</h1>
              <p>Sign up with Google - no password to remember. Your progress and purchases stay tied to your account.</p>
              {configured ? (
                <div className="po-auth-google">
                  <GoogleButton onError={setError} />
                  {error && <p className="po-auth-error" role="alert"><Icon name="bolt" size={14} /><span>{error}</span></p>}
                </div>
              ) : (
                <p className="po-auth-note"><Icon name="bolt" size={15} /><span>Google sign-in isn’t configured yet. Add your <b>GOOGLE_CLIENT_ID</b> - see GOOGLE_AUTH_SETUP.md.</span></p>
              )}
              <p className="po-auth-fine mono">We only read your name, email &amp; avatar. No posting, ever.</p>
            </>
          )}
        </div>
      </div>
    </main>
  );
}

/* ── account-page data collection: outcome survey + refund-reason ──────────── */
function OutcomeSurvey() {
  const u = readUser();
  const [open, setOpen] = useState(false);
  const [status, setStatus] = useState("");
  const [gotInterview, setGI] = useState(false);
  const [gotOffer, setGO] = useState(false);
  const [company, setCompany] = useState("");
  const [role, setRole] = useState("");
  const [city, setCity] = useState("");
  const [quote, setQuote] = useState("");
  const [consent, setConsent] = useState(false);
  const [sent, setSent] = useState(false);

  const submit = () => {
    if (!status || !u || !u.token) return;
    fetch(AUTH_API + "/outcome", {
      method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + u.token },
      body: JSON.stringify({ status, gotInterview, gotOffer, company, role, city, quote, shareConsent: consent, stage: "adhoc" }),
    }).then((r) => { if (r.ok) setSent(true); }).catch(() => {});
  };

  if (sent) return (
    <div className="po-acct-card"><p className="po-acct-thanks"><Icon name="check" size={16} stroke={2.6} /> Thank you - this helps us and the next reader a lot.{consent && quote ? " We'll confirm with you before sharing your story." : ""}</p></div>
  );
  return (
    <div className="po-acct-card">
      <button className="po-acct-head" onClick={() => setOpen(!open)} aria-expanded={open}>
        <span><Icon name="spark" size={16} /> How's your job search going?</span>
        <Icon name="arrowDown" size={18} style={{ transform: open ? "rotate(180deg)" : "none", transition: "transform .2s" }} />
      </button>
      {open && (
        <div className="po-acct-body">
          <label className="po-acct-label">Where are you right now?</label>
          <div className="po-acct-chips">
            {[["searching", "Still searching"], ["interviewing", "Interviewing"], ["offer", "Got an offer"], ["hired", "Hired 🎉"]].map(([v, l]) => (
              <button key={v} className={"po-acct-chip" + (status === v ? " on" : "")} onClick={() => setStatus(v)}>{l}</button>
            ))}
          </div>
          <div className="po-acct-checks">
            <label><input type="checkbox" checked={gotInterview} onChange={(e) => setGI(e.target.checked)} /> I landed at least one interview</label>
            <label><input type="checkbox" checked={gotOffer} onChange={(e) => setGO(e.target.checked)} /> I received an offer</label>
          </div>
          <div className="po-acct-row">
            <input className="po-acct-input" placeholder="Company (optional)" value={company} onChange={(e) => setCompany(e.target.value)} />
            <input className="po-acct-input" placeholder="Role (optional)" value={role} onChange={(e) => setRole(e.target.value)} />
            <input className="po-acct-input" placeholder="City (optional)" value={city} onChange={(e) => setCity(e.target.value)} />
          </div>
          <textarea className="po-acct-text" rows={3} maxLength={1000} placeholder="Anything you'd tell someone just starting? (optional)" value={quote} onChange={(e) => setQuote(e.target.value)} />
          <label className="po-acct-consent"><input type="checkbox" checked={consent} onChange={(e) => setConsent(e.target.checked)} /> You may share my words (with my first name) as a testimonial. We'll confirm before publishing.</label>
          <button className="btn btn-primary po-acct-send" disabled={!status} onClick={submit}>Send update</button>
        </div>
      )}
    </div>
  );
}

function RefundRequest() {
  const u = readUser();
  const [open, setOpen] = useState(false);
  const [reason, setReason] = useState("");
  const [note, setNote] = useState("");
  const [sent, setSent] = useState(false);
  const REASONS = ["Not what I expected", "Found the info elsewhere", "Too basic", "Too advanced", "No longer job-hunting", "Other"];
  const submit = () => {
    if (!reason || !u || !u.token) return;
    fetch(AUTH_API + "/refund-request", {
      method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + u.token },
      body: JSON.stringify({ reason, note }),
    }).then((r) => { if (r.ok) setSent(true); }).catch(() => {});
  };
  if (sent) return (
    <div className="po-acct-card po-acct-muted"><p className="po-acct-thanks"><Icon name="check" size={15} stroke={2.6} /> Got it - we'll process your refund. Reach us at <a href="mailto:contact@behired.dev">contact@behired.dev</a> with any details.</p></div>
  );
  return (
    <div className="po-acct-card po-acct-muted">
      <button className="po-acct-head po-acct-head-sm" onClick={() => setOpen(!open)} aria-expanded={open}>
        <span>Need a refund?</span>
        <Icon name="arrowDown" size={16} style={{ transform: open ? "rotate(180deg)" : "none", transition: "transform .2s" }} />
      </button>
      {open && (
        <div className="po-acct-body">
          <p className="po-acct-fine">30-day money-back, no hard feelings. A quick why helps us improve.</p>
          <select className="po-acct-input" value={reason} onChange={(e) => setReason(e.target.value)}>
            <option value="">Reason…</option>
            {REASONS.map((r) => <option key={r} value={r}>{r}</option>)}
          </select>
          <textarea className="po-acct-text" rows={2} maxLength={1000} placeholder="Anything else? (optional)" value={note} onChange={(e) => setNote(e.target.value)} />
          <button className="btn btn-ghost po-acct-send" disabled={!reason} onClick={submit}>Request refund</button>
        </div>
      )}
    </div>
  );
}

refreshMe(); // pull paid status on load for an already-signed-in user
const GOOGLE_CONFIGURED = !!GOOGLE_CLIENT_ID;
Object.assign(window, { Signup, GoogleButton, signInWithGoogle, GOOGLE_CONFIGURED, useUser, signOut, readUser, writeUser, track, getVisitorId, refreshMe });
