/* global React, ReactDOM */
/* Pull from window: survey screens, sales console, tweaks */
const {
  useState: useStateA, useEffect: useEffectA, useCallback: useCallbackA,
} = React;

// ─────────────────────────────────────────────
// Edit-mode persisted defaults
// ─────────────────────────────────────────────
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#004DE6",
  "progressStyle": "bar",
  "tone": "professional",
  "demoProspect": "northwind",
  "showSalesButton": true
}/*EDITMODE-END*/;

// Demo prospects (pretend pre-fills)
const DEMO_PROSPECTS = {
  northwind: {
    company: 'Northwind Health',
    contact: 'Priya Shah',
    role: 'COO / Operations',
    industry: 'Healthcare',
    size: '1,001–5,000',
    demoDate: 'May 20 · 2:00 PM PT',
    hypothesis: 'Clinical documentation is scattered across 6 systems; new clinician ramp is 14+ weeks.',
    rep: 'Alex Rivera, Account Executive',
  },
  orbit: {
    company: 'Orbit Logistics',
    contact: 'Marc Estevez',
    role: 'CTO / Engineering',
    industry: 'Supply chain',
    size: '201–1,000',
    demoDate: 'May 22 · 11:00 AM ET',
    hypothesis: 'RFP cycle takes 4 weeks; same answers being re-written by ops + legal each time.',
    rep: 'Jordan Park, Senior AE',
  },
  helix: {
    company: 'Helix Bioworks',
    contact: 'Sarah Lin',
    role: 'Head of AI / Data',
    industry: 'Biotech',
    size: '51–200',
    demoDate: 'May 27 · 9:30 AM PT',
    hypothesis: 'Lab protocols and SOPs live in PDFs across SharePoint; auditors flag stale versions.',
    rep: 'Alex Rivera, Account Executive',
  },
  blank: {
    company: '', contact: '', role: '', industry: '', size: '',
    demoDate: '', hypothesis: '', rep: '',
  },
};

function App() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [salesOpen, setSalesOpen] = useStateA(false);

  // step: 0 = welcome, 1..7 = questions, 8 = done
  const [step, setStep] = useStateA(0);

  // prefill from URL or selected demo prospect
  const [prospect, setProspect] = useStateA(() => {
    const fromUrl = readUrlPrefill();
    const hasUrl = Object.values(fromUrl).some(Boolean);
    if (hasUrl) return fromUrl;
    return DEMO_PROSPECTS[tweaks.demoProspect] || DEMO_PROSPECTS.northwind;
  });

  // Detect whether this view is the prospect-facing one (personalized link)
  // or the rep-facing one (bare URL or ?admin=1 escape hatch).
  const isProspectView = (() => {
    try {
      const params = new URLSearchParams(window.location.search);
      if (params.get('admin') === '1') return false; // rep escape hatch
      const fromUrl = readUrlPrefill();
      return Object.values(fromUrl).some(Boolean);
    } catch { return false; }
  })();

  // when demo prospect tweak changes, update prefill (unless URL provided)
  useEffectA(() => {
    const fromUrl = readUrlPrefill();
    const hasUrl = Object.values(fromUrl).some(Boolean);
    if (hasUrl) return;
    setProspect(DEMO_PROSPECTS[tweaks.demoProspect] || DEMO_PROSPECTS.northwind);
  }, [tweaks.demoProspect]);

  // accent live update on root
  useEffectA(() => {
    document.documentElement.style.setProperty('--accent', tweaks.accent);
    document.documentElement.style.setProperty('--accent-hover',
      darken(tweaks.accent, 0.22));
  }, [tweaks.accent]);

  // answers
  const [answers, setAnswers] = useStateA({
    role: '',
    roleOther: '',
    selectedPains: [],
    customPains: [],
    severities: {},
    order: [],
    tools: [],
    customTools: [],
    fix: '',
    success: '',
  });
  const updateAnswers = (patch) => setAnswers(a => ({ ...a, ...patch }));

  const [submitted, setSubmitted] = useStateA(false);
  const [submitState, setSubmitState] = useStateA('idle'); // idle | submitting | success | error
  const [submitError, setSubmitError] = useStateA('');

  // Webhook URL resolution priority:
  //   1. Override saved via Sales Console (localStorage)
  //   2. config.json (fetched on load) — this is what your prospects use
  const [configEndpoint, setConfigEndpoint] = useStateA('');
  const [configLoaded, setConfigLoaded] = useStateA(false);
  const [localOverride, setLocalOverride] = useStateA(() => {
    try { return localStorage.getItem('oe.briefing.webhook') || ''; } catch { return ''; }
  });
  const webhookUrl = (localOverride || configEndpoint || '').trim();
  const saveWebhook = (url) => {
    setLocalOverride(url);
    try { localStorage.setItem('oe.briefing.webhook', url); } catch {}
  };

  useEffectA(() => {
    fetch('config.json', { cache: 'no-store' })
      .then(r => r.ok ? r.json() : null)
      .then(j => { if (j && j.captureEndpoint) setConfigEndpoint(j.captureEndpoint); })
      .catch(() => {})
      .finally(() => setConfigLoaded(true));
  }, []);

  // Total questions
  const TOTAL = 7;
  const totalScreens = TOTAL + 2; // welcome + 7 questions + done

  const progress = step === 0 ? 0 : Math.min(1, step / (TOTAL + 1));

  const canAdvance = (() => {
    if (step === 1) {
      if (!answers.role) return false;
      if (answers.role === 'Other' && !answers.roleOther.trim()) return false;
      return true;
    }
    if (step === 2) return answers.selectedPains.length > 0;
    if (step === 3) return answers.selectedPains.every(id => answers.severities[id]);
    if (step === 4) return answers.order.length === answers.selectedPains.length;
    if (step === 5) return true; // tools optional
    if (step === 6) return true; // fix optional
    if (step === 7) return true; // success optional
    return true;
  })();

  const next = useCallbackA(() => {
    if (step <= TOTAL && canAdvance) setStep(s => s + 1);
  }, [step, canAdvance]);

  const prev = () => setStep(s => Math.max(0, s - 1));

  // global keyboard
  useEffectA(() => {
    const onKey = (e) => {
      if (e.target.tagName === 'TEXTAREA' || e.target.tagName === 'INPUT') return;
      if (e.key === 'Enter' && canAdvance) { e.preventDefault(); next(); }
      if (e.key === 'ArrowLeft') prev();
      if (e.key === 'ArrowRight' && canAdvance) next();
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [next, canAdvance]);

  const handleSubmit = async () => {
    setSubmitState('submitting');
    setSubmitError('');

    // Build a label map so the Sheet shows readable pain names instead of internal ids
    const painLabelsById = {};
    PAIN_AREAS.forEach(p => { painLabelsById[p.id] = p.label; });
    (answers.customPains || []).forEach(c => { painLabelsById[c.id] = c.label; });

    const payload = {
      submittedAt: new Date().toISOString(),
      prospect,
      answers: { ...answers, painLabelsById },
    };

    if (!webhookUrl) {
      // No endpoint configured — surface a clear error instead of silently "succeeding".
      console.warn('[briefing] no capture endpoint configured — submission NOT sent', payload);
      setSubmitError('No capture endpoint is configured for this deployment. Please contact your sales rep.');
      setSubmitState('error');
      return;
    }

    try {
      // FormData POST avoids CORS preflight and works against Apps Script
      const fd = new FormData();
      fd.append('payload', JSON.stringify(payload));
      const res = await fetch(webhookUrl, { method: 'POST', body: fd });
      // Apps Script returns text/plain JSON; opaque responses are also fine
      let ok = res.ok;
      try { const j = await res.json(); ok = ok && (j.ok !== false); } catch {}
      if (!ok) throw new Error('Endpoint returned a non-OK response.');
      setSubmitted(true);
      setSubmitState('success');
    } catch (err) {
      console.error('[briefing] submit failed', err);
      setSubmitError(err.message || 'Network error');
      setSubmitState('error');
    }
  };

  const handleRestart = () => {
    setAnswers({ role: '', roleOther: '', selectedPains: [], customPains: [], severities: {}, order: [], tools: [], customTools: [], fix: '', success: '' });
    setSubmitted(false);
    setSubmitState('idle');
    setSubmitError('');
    setStep(0);
  };

  // current screen render
  let body = null;
  if (step === 0) body = <ScreenWelcome prospect={prospect} onStart={() => setStep(1)} />;
  else if (step === 1) body = <ScreenRole num={1} total={TOTAL} value={answers.role} otherValue={answers.roleOther} onChange={r => updateAnswers({ role: r })} onOtherChange={v => updateAnswers({ roleOther: v })} onEnter={next} prospect={prospect} />;
  else if (step === 2) body = <ScreenPainSelect num={2} total={TOTAL} value={answers.selectedPains} onChange={p => updateAnswers({ selectedPains: p })} customPains={answers.customPains} onCustomPainsChange={cp => updateAnswers({ customPains: cp })} />;
  else if (step === 3) body = <ScreenSeverity num={3} total={TOTAL} selectedPains={answers.selectedPains} severities={answers.severities} onChange={sv => updateAnswers({ severities: sv })} customPains={answers.customPains} />;
  else if (step === 4) body = <ScreenRank num={4} total={TOTAL} selectedPains={answers.selectedPains} order={answers.order} onChange={o => updateAnswers({ order: o })} customPains={answers.customPains} />;
  else if (step === 5) body = <ScreenTools num={5} total={TOTAL} value={answers.tools} onChange={t => updateAnswers({ tools: t })} customTools={answers.customTools} onCustomToolsChange={ct => updateAnswers({ customTools: ct })} />;
  else if (step === 6) body = <ScreenFix num={6} total={TOTAL} value={answers.fix} onChange={f => updateAnswers({ fix: f })} onEnter={next} />;
  else if (step === 7) body = <ScreenSuccess num={7} total={TOTAL} value={answers.success} onChange={f => updateAnswers({ success: f })} onEnter={next} />;
  else body = <ScreenDone answers={answers} prospect={prospect} submitted={submitted} submitState={submitState} submitError={submitError} onSubmit={handleSubmit} onRestart={handleRestart} />;

  return (
    <>
      {/* top bar */}
      <header className="h-topbar">
        <div className="h-lockup">
          <img className="h-oe-logo" src="assets/oe-logo-horizontal.png" alt="Object Edge" />
          <span className="h-lockup-divider" />
          <span className="h-lockup-eyebrow">
            Pre-demo briefing <b style={{margin: '0 4px'}}>·</b> Hive
          </span>
        </div>
        <div className="h-topbar-right">
          {step > 0 && step <= TOTAL && (
            <span className="h-counter"><b>{String(step).padStart(2, '0')}</b> / {String(TOTAL).padStart(2, '0')}</span>
          )}
          {step === 0 && prospect.company && (
            <span style={{textTransform: 'none', letterSpacing: 0, color: 'var(--fg-2)'}}>
              For <b style={{color: 'var(--fg-1)'}}>{prospect.company}</b>
            </span>
          )}
        </div>
      </header>

      {/* progress */}
      {tweaks.progressStyle === 'bar' && (
        <div className="h-progress"><div className="h-progress-fill" style={{ width: `${progress * 100}%` }} /></div>
      )}
      {tweaks.progressStyle === 'dots' && (
        <div className="h-dots">
          {Array.from({ length: TOTAL }).map((_, i) => (
            <span key={i} className={cn('h-dot', step === i + 1 && 'is-active', step > i + 1 && 'is-done')} />
          ))}
        </div>
      )}
      {tweaks.progressStyle === 'steps' && (
        <div className="h-steps">
          {Array.from({ length: TOTAL }).map((_, i) => (
            <span key={i} className={cn('h-step', step > i && 'is-done')} />
          ))}
        </div>
      )}

      {/* stage */}
      <main className="h-stage">
        {body}
      </main>

      {/* footer nav */}
      {step > 0 && step <= TOTAL && (
        <>
          <div className="h-foot-left">
            <span className="h-kbd">←</span>
            <span style={{margin: '0 6px'}}>Back</span>
          </div>
          <div className="h-foot">
            {step > 1 && (
              <button className="h-btn h-btn--ghost" onClick={prev}>Back</button>
            )}
            <button className="h-btn" onClick={next} disabled={!canAdvance}>
              {step === TOTAL ? 'See recap' : 'Continue'} <Arrow />
            </button>
            <span className="h-foot-hint" style={{marginLeft: 8}}>
              or press <span className="h-kbd">Enter ↵</span>
            </span>
          </div>
        </>
      )}

      {/* sales button — hidden when this is a prospect-facing personalized link */}
      {tweaks.showSalesButton && !isProspectView && !salesOpen && (
        <button className="h-sales-toggle" onClick={() => setSalesOpen(true)}>
          Sales Console · Pre-fill
        </button>
      )}

      <SalesConsole
        open={salesOpen}
        onClose={() => setSalesOpen(false)}
        prospect={prospect}
        setProspect={setProspect}
        webhookUrl={webhookUrl}
        onSaveWebhook={saveWebhook}
      />

      {/* TWEAKS */}
      <TweaksPanel title="Tweaks">
        <TweakSection label="Theme">
          <TweakColor
            label="Accent color"
            value={tweaks.accent}
            onChange={v => setTweak('accent', v)}
            options={['#004DE6', '#0F172A', '#1F8A5B', '#D97757', '#7C3AED']}
          />
          <TweakRadio
            label="Progress style"
            value={tweaks.progressStyle}
            onChange={v => setTweak('progressStyle', v)}
            options={[
              { value: 'bar',   label: 'Bar' },
              { value: 'dots',  label: 'Dots' },
              { value: 'steps', label: 'Steps' },
            ]}
          />
        </TweakSection>

        <TweakSection label="Content">
          <TweakSelect
            label="Demo prospect (prefill)"
            value={tweaks.demoProspect}
            onChange={v => setTweak('demoProspect', v)}
            options={[
              { value: 'northwind', label: 'Northwind Health · Priya' },
              { value: 'orbit',     label: 'Orbit Logistics · Marc'   },
              { value: 'helix',     label: 'Helix Bioworks · Sarah'   },
              { value: 'blank',     label: 'Blank (no prefill)'        },
            ]}
          />
        </TweakSection>

        <TweakSection label="Layout">
          <TweakToggle
            label="Show 'Sales Console' button"
            value={tweaks.showSalesButton}
            onChange={v => setTweak('showSalesButton', v)}
          />
          <TweakButton
            label="Open Sales Console"
            onClick={() => setSalesOpen(true)}
          />
          <TweakButton
            label="Reset survey"
            onClick={handleRestart}
          />
        </TweakSection>
      </TweaksPanel>
    </>
  );
}

// ─────────────────────────────────────────────
// utils
// ─────────────────────────────────────────────
function darken(hex, amt) {
  try {
    const m = hex.replace('#', '').match(/.{2}/g);
    if (!m) return hex;
    const [r, g, b] = m.map(h => parseInt(h, 16));
    const f = (c) => Math.max(0, Math.round(c * (1 - amt)));
    return '#' + [f(r), f(g), f(b)].map(x => x.toString(16).padStart(2, '0')).join('');
  } catch { return hex; }
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
