/* global React */
// BOB Inner Circle — Application Wizard
// 7-step form that POSTs submissions to Google Forms.
// Form ID: 1FAIpQLScY6A_T7jug1pavCfB7IS8R-bkvmnewjxlIpsr8xh0-Fvtd9w
//
// To refresh field IDs if you edit the Google Form:
//   1. Open the form in a browser
//   2. Open devtools console
//   3. Run: copy(JSON.stringify(FB_PUBLIC_LOAD_DATA_))
//   4. Paste back to Claude and ask to re-extract entry IDs

const T = window.ICTokens;

const FORM_ID = "1FAIpQLScY6A_T7jug1pavCfB7IS8R-bkvmnewjxlIpsr8xh0-Fvtd9w";
const FORM_URL = `https://docs.google.com/forms/d/e/${FORM_ID}/formResponse`;
const STORAGE_KEY = "bob-ic-application-draft-v1";

// Form definition — keep in lockstep with the live Google Form.
// `entry` = the entry.XXXXX ID Google expects for that question.
// `branch` = optional { "<answer>": pageIndex } for skip-logic.
const FORM_PAGES = [
  {
    badge: "About you",
    title: "Tell us who you are",
    subtitle: "Pseudonyms welcome — name and email are entirely optional.",
    questions: [
      { entry: 1762179337, label: "First name",        type: "text",  placeholder: "or a handle / pseudonym" },
      { entry: 1406897116, label: "Last name",         type: "text",  placeholder: "optional" },
      { entry: 1750612049, label: "Email address",     type: "email", placeholder: "optional — only if you want email contact" },
      { entry: 563128733,  label: "Do you primarily transact on behalf of yourself, or an entity (e.g. trading firm)?", type: "radio", required: true, options: ["Myself", "Entity", "Both"] },
      { entry: 1407947770, label: "If you transact on behalf of an entity, what is the name of the entity?", type: "text", placeholder: "Entity name (optional)" },
    ],
  },
  {
    badge: "How we'll reach you",
    title: "Pick your channel",
    subtitle: "We'll come to you in the channel you actually use.",
    questions: [
      { entry: 984550077,  label: "Discord handle",  type: "text", required: true, placeholder: "e.g. satoshi" },
      { entry: 2053700220, label: "Telegram handle", type: "text", required: true, placeholder: "e.g. @satoshi" },
      {
        entry: 1774881247,
        label: "Have you conducted onchain BTC↔EVM swaps in the past 12 months?",
        type: "radio", required: true, options: ["Yes", "No"],
        // Google Form rule: "No" jumps to "Wallet info" (page index 4)
        branch: { "No": 4 },
      },
    ],
  },
  {
    badge: "Swaps · part 1",
    title: "Your swap habits",
    subtitle: "Help us understand how you move capital between chains.",
    questions: [
      { entry: 91960684,   label: "What was your approximate total swap volume over the past 12 months?", type: "radio", options: ["Under $5k", "$5k–$25k", "$25k–$100k", "$100k+"] },
      { entry: 1826090189, label: "What device do you use to conduct swaps?", type: "radio", required: true, options: ["Mobile", "Desktop", "Both"] },
      { entry: 1964176697, label: "Do you primarily use an API or a UI to conduct swaps?", type: "radio", options: ["API", "UI", "Both"] },
      { entry: 1965485323, label: "If you use a UI for swap, which UI(s) do you primarily use?", type: "text", placeholder: "e.g. Ledger Live, MetaMask" },
    ],
  },
  {
    badge: "Swaps · part 2",
    title: "A bit more depth",
    subtitle: "Where the market falls short — in your words.",
    questions: [
      { entry: 856988453,  label: "How many individual swap transactions did you conduct in the past 12 months?", type: "radio", options: ["1–4", "5–20", "21–100", "100+"] },
      { entry: 1224919351, label: "What is the largest single swap you anticipate needing in the next 12 months?", type: "radio", options: ["Under $10k", "$10k–$100k", "$100k–$500k", "$500k+"] },
      { entry: 1477522837, label: "What swap protocol(s) do you primarily use today?", type: "text", placeholder: "e.g. 1inch, Thorchain, Uniswap" },
      { entry: 682009947,  label: "What would it realistically take to get you to enthusiastically switch to a new swap protocol?", type: "paragraph", placeholder: "Be specific — features, pricing, UX, anything." },
    ],
  },
  {
    badge: "Wallet & accounts",
    title: "How you manage crypto day-to-day",
    subtitle: "Wallets, mobile, neobanks.",
    questions: [
      { entry: 1470840714, label: "Do you hold crypto in a web wallet (e.g. MetaMask, Phantom)?", type: "radio", required: true, options: ["Yes", "No"] },
      { entry: 1472266237, label: "What crypto assets do you primarily hold in your web wallet?", type: "checkbox", options: ["BTC", "ETH", "Stablecoins", "Other"], hint: "Select all that apply" },
      { entry: 213191911,  label: "Do you ever manage your positions via mobile app?", type: "radio", required: true, options: ["Often", "Sometimes", "Never"] },
      { entry: 1214269508, label: "Do you actively use a neobank app (e.g. Revolut, Cash App, Chime)?", type: "radio", required: true, options: ["Yes", "No"] },
      { entry: 574718468,  label: "If yes, what neobank app(s) do you primarily use and why?", type: "paragraph", placeholder: "Optional — only if you use one." },
    ],
  },
  {
    badge: "Crypto card",
    title: "Crypto in everyday spending",
    subtitle: "Where the gap between crypto and daily life lives.",
    questions: [
      { entry: 1649189457, label: "Do you use a crypto debit/credit card for everyday purchases?", type: "radio", required: true, options: ["Yes", "No"] },
      { entry: 46489886,   label: "If no, why not?", type: "paragraph", placeholder: "Optional — what's blocking you?" },
      { entry: 1289280738, label: "If so, how much do you typically spend per month on your primary card?", type: "radio", options: ["Under $1k", "$1k–$5k", "$5k–$20k", "$20k+"] },
      { entry: 62371794,   label: "What would it realistically take for you to enthusiastically switch to habitually using a new crypto card?", type: "paragraph", required: true, placeholder: "Be specific — rewards, fees, supported networks, UX, anything." },
    ],
  },
  {
    badge: "Other products",
    title: "Yield, lending and more",
    subtitle: "The last few questions.",
    questions: [
      { entry: 779654746,  label: "Do you currently hold $10k+ of BTC or stablecoins in any onchain yield product?", type: "radio", options: ["Yes", "No"] },
      { entry: 1260921706, label: "Which yield platforms do you currently use?", type: "text", placeholder: "e.g. Aave, Pendle, Ethena" },
      { entry: 1633636730, label: "Have you borrowed against crypto or minted debt (e.g. loans, CDP) of $10k+?", type: "radio", options: ["Yes", "No"] },
      { entry: 1700427037, label: "Which platform(s) do you use to borrow or mint debt?", type: "text", placeholder: "e.g. Aave, Maker, Liquity" },
    ],
  },
];

// ─────────────────────────────────────────────────────────────
// Drafting / persistence
// ─────────────────────────────────────────────────────────────
function loadDraft() {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    return raw ? JSON.parse(raw) : {};
  } catch (e) { return {}; }
}
function saveDraft(values) {
  try { localStorage.setItem(STORAGE_KEY, JSON.stringify(values)); } catch (e) {}
}
function clearDraft() {
  try { localStorage.removeItem(STORAGE_KEY); } catch (e) {}
}

// ─────────────────────────────────────────────────────────────
// Analytics shim — dual-fires to PostHog + GA4 if present
// ─────────────────────────────────────────────────────────────
function track(name, props) {
  props = props || {};
  try { if (window.posthog && window.posthog.capture) window.posthog.capture(name, props); } catch (e) {}
  try { if (window.gtag) window.gtag('event', name, props); } catch (e) {}
}

// ─────────────────────────────────────────────────────────────
// Branching: given current values, return the ordered list of
// page indices the user should visit. Used for progress, Back/Next.
// ─────────────────────────────────────────────────────────────
function computeFlow(values) {
  const flow = [];
  let i = 0;
  const visited = new Set();
  while (i < FORM_PAGES.length && !visited.has(i)) {
    visited.add(i);
    flow.push(i);
    const page = FORM_PAGES[i];
    let next = i + 1;
    // Inspect this page's questions for a branch hit
    for (const q of page.questions) {
      if (q.branch) {
        const answer = values[q.entry];
        if (answer && q.branch[answer] != null) {
          next = q.branch[answer];
          break;
        }
      }
    }
    i = next;
  }
  return flow;
}

// ─────────────────────────────────────────────────────────────
// Field components
// ─────────────────────────────────────────────────────────────
function ICFieldLabel({ label, required, hint }) {
  return (
    <div style={{ marginBottom: 8 }}>
      <div style={{ fontFamily: T.body, fontSize: 13.5, fontWeight: 500, color: T.fg, letterSpacing: ".005em", lineHeight: 1.4 }}>
        {label}
        {required && <span style={{ color: T.orange, marginLeft: 6 }}>*</span>}
      </div>
      {hint && <div style={{ fontFamily: T.body, fontSize: 12, color: T.fg4, marginTop: 4 }}>{hint}</div>}
    </div>
  );
}

function ICTextInput({ value, onChange, placeholder, type = "text", error, multiline = false }) {
  const baseStyle = {
    width: "100%",
    background: "#08080a",
    border: `1px solid ${error ? T.red : T.border}`,
    borderRadius: 12,
    padding: "12px 14px",
    fontFamily: T.body,
    fontSize: 14,
    color: T.fg,
    outline: "none",
    transition: "border-color .15s ease",
    resize: multiline ? "vertical" : "none",
    minHeight: multiline ? 96 : 44,
  };
  const onFocus = (e) => { if (!error) e.target.style.borderColor = T.orange; };
  const onBlur  = (e) => { e.target.style.borderColor = error ? T.red : T.border; };
  if (multiline) {
    return <textarea value={value || ""} onChange={(e) => onChange(e.target.value)} placeholder={placeholder} style={baseStyle} onFocus={onFocus} onBlur={onBlur} rows={3}/>;
  }
  return <input type={type} value={value || ""} onChange={(e) => onChange(e.target.value)} placeholder={placeholder} style={baseStyle} onFocus={onFocus} onBlur={onBlur}/>;
}

function ICRadioGroup({ value, onChange, options, error }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 8 }} role="radiogroup">
      {options.map((opt) => {
        const on = value === opt;
        return (
          <label key={opt} style={{
            display: "flex", alignItems: "center", gap: 12,
            padding: "11px 14px",
            border: `1px solid ${on ? T.orange : (error ? T.red : T.border)}`,
            borderRadius: 12,
            background: on ? "rgba(242,93,0,.08)" : "transparent",
            fontFamily: T.body, fontSize: 14, fontWeight: 500,
            color: on ? T.fg : T.fg2,
            cursor: "pointer",
            transition: "border-color .12s ease, background .12s ease",
          }}>
            <input type="radio" checked={on} onChange={() => onChange(opt)} style={{ display: "none" }}/>
            <span aria-hidden style={{
              width: 16, height: 16, borderRadius: 999,
              border: `1.5px solid ${on ? T.orange : T.fg4}`,
              display: "inline-flex", alignItems: "center", justifyContent: "center",
              flexShrink: 0,
            }}>
              {on && <span style={{ width: 8, height: 8, borderRadius: 999, background: T.orange }}/>}
            </span>
            {opt}
          </label>
        );
      })}
    </div>
  );
}

function ICCheckboxGroup({ value, onChange, options, error }) {
  const arr = Array.isArray(value) ? value : [];
  const toggle = (opt) => {
    const next = arr.includes(opt) ? arr.filter(v => v !== opt) : [...arr, opt];
    onChange(next);
  };
  return (
    <div className="ic-wizard-checks" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
      {options.map((opt) => {
        const on = arr.includes(opt);
        return (
          <label key={opt} style={{
            display: "flex", alignItems: "center", gap: 10,
            padding: "11px 14px",
            border: `1px solid ${on ? "rgba(242,93,0,.55)" : (error ? T.red : T.border)}`,
            borderRadius: 12,
            background: on ? "rgba(242,93,0,.06)" : "transparent",
            fontFamily: T.body, fontSize: 14, fontWeight: 500,
            color: on ? T.fg : T.fg2,
            cursor: "pointer",
            transition: "border-color .12s ease, background .12s ease",
          }}>
            <input type="checkbox" checked={on} onChange={() => toggle(opt)} style={{ display: "none" }}/>
            <span aria-hidden style={{
              width: 16, height: 16, borderRadius: 4,
              border: `1.5px solid ${on ? T.orange : T.fg4}`,
              background: on ? T.orange : "transparent",
              display: "inline-flex", alignItems: "center", justifyContent: "center",
              color: "#000", fontSize: 11, fontWeight: 800,
              flexShrink: 0,
            }}>{on && "✓"}</span>
            {opt}
          </label>
        );
      })}
    </div>
  );
}

function ICQuestion({ question, value, onChange, error }) {
  const { type, label, required, hint, options, placeholder } = question;
  return (
    <div style={{ marginBottom: 18 }}>
      <ICFieldLabel label={label} required={required} hint={hint}/>
      {type === "text" && <ICTextInput value={value} onChange={onChange} placeholder={placeholder} error={!!error}/>}
      {type === "email" && <ICTextInput value={value} onChange={onChange} placeholder={placeholder} type="email" error={!!error}/>}
      {type === "paragraph" && <ICTextInput value={value} onChange={onChange} placeholder={placeholder} multiline error={!!error}/>}
      {type === "radio" && <ICRadioGroup value={value} onChange={onChange} options={options} error={!!error}/>}
      {type === "checkbox" && <ICCheckboxGroup value={value} onChange={onChange} options={options} error={!!error}/>}
      {error && <div style={{ marginTop: 6, fontFamily: T.body, fontSize: 12, color: T.red }}>{error}</div>}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// The wizard
// ─────────────────────────────────────────────────────────────
function ICApplicationWizard() {
  const [values, setValues] = React.useState(() => loadDraft());
  const [pageIdx, setPageIdx] = React.useState(0);   // index into FORM_PAGES
  const [errors, setErrors] = React.useState({});
  const [submitting, setSubmitting] = React.useState(false);
  const [submitted, setSubmitted] = React.useState(false);
  const [started, setStarted] = React.useState(false);

  // Persist draft on every change
  React.useEffect(() => { saveDraft(values); }, [values]);

  // Fire application_start once on first interaction
  const markStarted = React.useCallback(() => {
    if (started) return;
    setStarted(true);
    track('application_start', {});
  }, [started]);

  const flow = React.useMemo(() => computeFlow(values), [values]);
  const flowPos = flow.indexOf(pageIdx);          // 0-based position within visible flow
  const totalSteps = flow.length;
  const isFirstStep = flowPos <= 0;
  const isLastStep  = flowPos === totalSteps - 1;
  const page = FORM_PAGES[pageIdx];

  function setValue(entry, v) {
    markStarted();
    setValues((prev) => ({ ...prev, [entry]: v }));
    setErrors((prev) => {
      if (!prev[entry]) return prev;
      const { [entry]: _, ...rest } = prev;
      return rest;
    });
  }

  function validatePage() {
    const errs = {};
    for (const q of page.questions) {
      if (!q.required) continue;
      const v = values[q.entry];
      const empty = v == null || v === "" || (Array.isArray(v) && v.length === 0);
      if (empty) errs[q.entry] = "Required.";
      if (q.type === "email" && v && !/^\S+@\S+\.\S+$/.test(v)) errs[q.entry] = "Enter a valid email.";
    }
    setErrors(errs);
    return Object.keys(errs).length === 0;
  }

  function goNext() {
    if (!validatePage()) return;
    track('application_step_complete', { step: flowPos + 1, section: page.badge });
    // Determine next page from branching
    let next = pageIdx + 1;
    for (const q of page.questions) {
      if (q.branch && values[q.entry] != null && q.branch[values[q.entry]] != null) {
        next = q.branch[values[q.entry]];
        break;
      }
    }
    if (next >= FORM_PAGES.length) return submit();
    setPageIdx(next);
    scrollPanelTop();
  }

  function goBack() {
    track('application_back', { step: flowPos + 1 });
    const prevIdx = flow[Math.max(0, flowPos - 1)];
    setPageIdx(prevIdx);
    scrollPanelTop();
  }

  function scrollPanelTop() {
    // Scroll the wizard back to its top so users always start a page at q1
    requestAnimationFrame(() => {
      const el = document.getElementById('ic-wizard-top');
      if (el && typeof el.scrollIntoView === 'function') {
        // Use 'nearest' to avoid jumping past the header on tall pages
        try { el.scrollIntoView({ block: 'start', behavior: 'smooth' }); } catch (e) {}
      }
    });
  }

  async function submit() {
    if (!validatePage()) return;
    setSubmitting(true);
    track('application_submit', { fields: Object.keys(values).length });
    try {
      const fd = new FormData();
      for (const [entry, v] of Object.entries(values)) {
        if (v == null || v === "") continue;
        const key = `entry.${entry}`;
        if (Array.isArray(v)) {
          for (const item of v) fd.append(key, item);
        } else {
          fd.append(key, v);
        }
      }
      // CRITICAL for multi-page forms: tell Google which pages the user
      // traversed. Without this, Google accepts the POST but only records
      // page-0 fields and drops everything else.
      fd.append('pageHistory', flow.join(','));
      fd.append('fvv', '1');
      // Google blocks reading the response cross-origin — we send in no-cors mode
      // and trust that submission reached Google's servers.
      await fetch(FORM_URL, { method: 'POST', mode: 'no-cors', body: fd });
      track('application_success', {});
      clearDraft();
      setSubmitted(true);
    } catch (err) {
      track('application_error', { message: String(err && err.message || err) });
      setErrors({ __submit: "Something went wrong sending your application. Please try again." });
    } finally {
      setSubmitting(false);
    }
  }

  // ── Thank-you state ──────────────────────────────────────────
  if (submitted) {
    return (
      <div style={{
        background: "#0c0c0e",
        border: `1px solid ${T.border}`,
        borderRadius: 18,
        padding: "40px 32px",
        textAlign: "center",
        minHeight: 460,
        display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", gap: 14,
      }}>
        <div style={{
          width: 64, height: 64, borderRadius: 999,
          background: "rgba(242,93,0,.10)",
          border: `1px solid ${T.borderHi}`,
          display: "flex", alignItems: "center", justifyContent: "center",
          marginBottom: 6,
        }}>
          <svg width="28" height="28" viewBox="0 0 24 24" fill="none">
            <path d="M5 12.5l4.5 4.5L19 7.5" stroke={T.orange} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </div>
        <div style={{ fontFamily: T.display, fontSize: 28, fontWeight: 600, color: T.fg, letterSpacing: "-.01em" }}>
          Application received
        </div>
        <div style={{ fontFamily: T.body, fontSize: 15, color: T.fg2, maxWidth: 380, lineHeight: 1.55, textWrap: "pretty" }}>
          Thanks for applying to the BOB Inner Circle. We're reviewing applications on a rolling basis — you'll hear from us on your preferred channel within two weeks.
        </div>
        <div style={{ marginTop: 12, padding: "12px 18px", border: `1px solid ${T.border}`, borderRadius: 999, fontFamily: T.body, fontSize: 13, color: T.fg3 }}>
          <span style={{ color: T.orange, marginRight: 8, fontWeight: 600 }}>Next:</span>
          Watch for a kickoff invite from the BOB product team.
        </div>
      </div>
    );
  }

  // ── Active form state ────────────────────────────────────────
  return (
    <div id="ic-wizard-top" className="ic-wizard" style={{
      background: "#0c0c0e",
      border: `1px solid ${T.border}`,
      borderRadius: 18,
      padding: 28,
      scrollMarginTop: 100,
    }}>
      {/* Progress bar */}
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 18 }}>
        <div style={{ fontFamily: T.body, fontSize: 11, fontWeight: 600, color: T.orange, letterSpacing: ".16em", textTransform: "uppercase" }}>
          {page.badge}
        </div>
        <div style={{ fontFamily: T.body, fontSize: 12, color: T.fg3 }}>
          Step <span style={{ color: T.fg, fontWeight: 600 }}>{flowPos + 1}</span> of {totalSteps}
        </div>
      </div>
      <div style={{
        height: 4, borderRadius: 999, background: "#1a1a1c",
        marginBottom: 24, overflow: "hidden",
      }}>
        <div style={{
          width: `${((flowPos + 1) / totalSteps) * 100}%`,
          height: "100%",
          background: `linear-gradient(90deg, #FF9500, ${T.orange})`,
          transition: "width .3s ease",
        }}/>
      </div>

      {/* Page heading */}
      <div style={{ marginBottom: 22 }}>
        <div style={{ fontFamily: T.display, fontSize: 22, fontWeight: 600, color: T.fg, letterSpacing: "-.01em", lineHeight: 1.15, marginBottom: 6 }}>
          {page.title}
        </div>
        <div style={{ fontFamily: T.body, fontSize: 13.5, color: T.fg3, lineHeight: 1.5 }}>
          {page.subtitle}
        </div>
      </div>

      {/* Questions */}
      <div>
        {page.questions.map((q) => (
          <ICQuestion
            key={q.entry}
            question={q}
            value={values[q.entry]}
            onChange={(v) => setValue(q.entry, v)}
            error={errors[q.entry]}
          />
        ))}
      </div>

      {/* Submit-level error */}
      {errors.__submit && (
        <div style={{ marginBottom: 14, padding: "10px 14px", border: `1px solid ${T.red}`, borderRadius: 10, fontFamily: T.body, fontSize: 13, color: T.red, background: "rgba(255,59,59,.05)" }}>
          {errors.__submit}
        </div>
      )}

      {/* Footer controls */}
      <div style={{ marginTop: 22, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12 }}>
        <button
          type="button"
          onClick={goBack}
          disabled={isFirstStep || submitting}
          style={{
            background: "transparent",
            color: isFirstStep ? T.fg4 : T.fg2,
            border: `1px solid ${T.border}`,
            padding: "12px 20px",
            borderRadius: 12,
            fontFamily: T.body, fontSize: 14, fontWeight: 500,
            cursor: isFirstStep ? "default" : "pointer",
            opacity: isFirstStep ? 0.45 : 1,
          }}
        >← Back</button>

        <button
          type="button"
          onClick={goNext}
          disabled={submitting}
          className="cta-form-submit"
          data-cta-location="wizard"
          style={{
            background: T.orange,
            color: "#fff", border: 0,
            padding: "13px 26px",
            borderRadius: 12,
            fontFamily: T.body, fontWeight: 600, fontSize: 14,
            cursor: submitting ? "wait" : "pointer",
            boxShadow: "0 10px 24px rgba(242,93,0,.35)",
            opacity: submitting ? 0.7 : 1,
            display: "inline-flex", alignItems: "center", gap: 8,
          }}
        >
          {submitting ? "Sending…" : (isLastStep ? "Submit application →" : "Next →")}
        </button>
      </div>
    </div>
  );
}

window.ICApplicationWizard = ICApplicationWizard;
