/* global React */
// Screen components for the AI Marketing Audit.
// Each screen is a pure component that receives state + callbacks from app.jsx.

const { useState, useEffect, useMemo } = React;

// ---- Theme toggle ------------------------------------------------------
function toggleTheme() {
  const root = document.documentElement;
  const stored = root.getAttribute('data-theme');
  const systemPref = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
  const current = stored || systemPref;
  const next = current === 'dark' ? 'light' : 'dark';
  root.setAttribute('data-theme', next);
  try { localStorage.setItem('theme', next); } catch (_) {}
}

function ThemeToggle() {
  return (
    <button type="button" className="theme-toggle" onClick={toggleTheme} aria-label="Toggle light or dark theme" title="Toggle theme">
      <svg className="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" aria-hidden="true">
        <path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z" />
      </svg>
      <svg className="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" aria-hidden="true">
        <circle cx="12" cy="12" r="4" />
        <path d="M12 3v2M12 19v2M3 12h2M19 12h2M5.6 5.6l1.4 1.4M17 17l1.4 1.4M5.6 18.4 7 17M17 7l1.4-1.4" strokeLinecap="round"/>
      </svg>
    </button>
  );
}

// ---- Masthead ----------------------------------------------------------
// Same shape as the rest of the site: mark + Eddie tag on the left,
// Eduardo wordmark in the center linking home, five nav links + theme
// toggle + hamburger on the right. The hamburger drives a static
// .mobile-menu element in audit/index.html via plain JS.
function Masthead() {
  return (
    <header className="mast">
      <div className="mast-l">
        <a className="mast-l-link" href="/" aria-label="Eddie Espriella, home">
          <img src="assets/mark-navy.png" alt="Eddie Espriella monogram" />
          <span className="dot"></span>
          <span>Eddie Espriella</span>
        </a>
      </div>
      <div className="mast-c"><a href="/">Eduardo de la Espriella</a></div>
      <nav className="mast-r">
        <a href="/audit/" className="is-current" aria-current="page">Audit</a>
        <a href="/#work">Work</a>
        <a href="/cv/">CV</a>
        <a href="/writing/">Writing</a>
        <a href="/#contact">Contact</a>
        <ThemeToggle />
        <button type="button" className="hamburger" id="hamburger" aria-label="Open menu" aria-expanded="false" aria-controls="mobileMenu">
          <span></span><span></span><span></span>
        </button>
      </nav>
    </header>
  );
}

// ---- Progress bar ------------------------------------------------------
function Progress({ current, total }) {
  const pct = Math.max(0, Math.min(100, (current / total) * 100));
  return (
    <div className="progress">
      <div className="progress-track"><div className="progress-fill" style={{ width: `${pct}%` }} /></div>
      <div className="progress-meta">Question&nbsp;<em>{String(current).padStart(2,'0')}</em>&nbsp;/&nbsp;{String(total).padStart(2,'0')}</div>
    </div>
  );
}

// ---- Intro screen ------------------------------------------------------
function Intro({ onStart }) {
  return (
    <div className="shell stage">
      <div className="eyebrow">
        <span>Intake</span>
        <span className="rule"></span>
        <span>5 questions · ~2 minutes</span>
      </div>
      <div className="intro-head">
        <span className="ix">Audit</span>
        <div style={{ fontFamily: '-apple-system' }}>
          <h1 className="intro-title">AI for <em>marketing,</em><br/>audited <em>honestly.</em></h1>
          <p className="intro-deck">
            Five questions about your team, your goals, and where the week actually goes. You'll get a short, prioritised map of the AI moves worth making first, not a wish list of every tool on the market.
          </p>

          <div className="intro-meta">
            <div><span className="k">Built for</span><span className="v">B2B SaaS · CMOs, heads of marketing, founders</span></div>
            <div><span className="k">Runtime</span><span className="v"><em>~2</em>&nbsp;minutes, 5 questions</span></div>
            <div><span className="k">Output</span><span className="v">3 to 5 prioritized opportunities · PDF</span></div>
          </div>

          <div className="intro-actions">
            <button className="btn btn-primary" onClick={onStart}>Start audit&nbsp;&nbsp;→</button>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10.5, letterSpacing: '.14em', textTransform: 'uppercase', color: 'var(--muted)' }}>
              No account · No spam · PDF at the end
            </span>
          </div>

          <p style={{ fontFamily: 'var(--font-serif)', fontStyle: 'italic', color: 'var(--muted)', fontSize: 16, marginTop: 56, maxWidth: '52ch', lineHeight: 1.45 }}>
            "If there are two CTAs above the fold, one of them is a hedge." A principle I use when building marketing systems, and the same one I use when building this tool.
          </p>
        </div>
      </div>
    </div>
  );
}

// ---- Question screen ---------------------------------------------------
function QuestionStage({ q, index, total, value, onPick, onBack, onNext }) {
  return (
    <>
      <Progress current={index + 1} total={total} />
      <div className="shell">
        <div className="q-wrap stage" key={q.id}>
          <div className="q-head">
            <span className="q-ix">{String(index + 1).padStart(2,'0')} · {q.id.toUpperCase()}</span>
            <div>
              <h2 className="q-title">{q.title}</h2>
              <p className="q-sub">{q.sub}</p>
            </div>
          </div>

          <div className="choices">
            {q.options.map((opt, i) => {
              const selected = value === opt.id;
              return (
                <button
                  key={opt.id}
                  className="choice"
                  data-selected={selected}
                  onClick={() => onPick(opt.id)}
                >
                  <span>
                    <span className="choice-ix">Option {String(i + 1).padStart(2,'0')}</span>
                    <span className="choice-label">{opt.label}</span>
                    <span className="choice-sub">{opt.sub}</span>
                  </span>
                  <span className="choice-mark">{selected ? '●' : '→'}</span>
                </button>
              );
            })}
          </div>

          <div className="q-foot">
            <button className="btn-text" onClick={onBack} disabled={index === 0} style={{ opacity: index === 0 ? .3 : 1, cursor: index === 0 ? 'default' : 'pointer' }}>
              ← Back
            </button>
            <button className="btn btn-primary" onClick={onNext} disabled={!value}>
              {index === total - 1 ? 'Review & unlock' : 'Next question'}&nbsp;&nbsp;→
            </button>
          </div>
        </div>
      </div>
    </>
  );
}

// ---- Follow-up loading -------------------------------------------------
// Shown while the AI generates the two follow-up questions. Falls through
// to the capture step if the user picks Skip or the model hangs.
function FollowupsLoading({ onSkip }) {
  return (
    <div className="shell stage">
      <div className="eyebrow">
        <span>Personalising</span>
        <span className="rule"></span>
        <span>Eddie's audit AI is reading your answers</span>
      </div>
      <div className="intro-head" style={{ marginTop: 30 }}>
        <span className="ix">Reading<br/>your answers</span>
        <div>
          <h2 className="intro-title" style={{ fontSize: 'clamp(36px, 5.5vw, 64px)' }}>
            Generating <em>two follow-up questions.</em>
          </h2>
          <p className="intro-deck" style={{ marginBottom: 24 }}>
            One layer deeper, based on what you just told me. About ten seconds.
          </p>
          <div className="loading-dots" aria-hidden="true">
            <span></span><span></span><span></span>
          </div>
          <div className="q-foot" style={{ marginTop: 28, borderTop: 0, paddingTop: 0 }}>
            <span></span>
            <button className="btn-text" onClick={onSkip}>Skip and continue&nbsp;&nbsp;→</button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ---- Follow-up question screen -----------------------------------------
// Same layout as QuestionStage but for AI-generated follow-ups. Each
// question has 3 to 4 multiple-choice options. The user can skip the rest
// at any time; nothing here is required.
function FollowupStage({ q, index, total, value, onPick, onBack, onNext, onSkip }) {
  if (!q) return null;
  return (
    <>
      <Progress current={QUESTIONS.length + index + 1} total={QUESTIONS.length + total} />
      <div className="shell">
        <div className="q-wrap stage" key={q.id}>
          <div className="q-head">
            <span className="q-ix">FOLLOW-UP {String(index + 1).padStart(2, '0')} · {String(total).padStart(2, '0')}</span>
            <div>
              <h2 className="q-title">{q.title}</h2>
              <p className="q-sub">{q.sub}</p>
            </div>
          </div>

          <div className="choices">
            {(q.options || []).map((opt, i) => {
              const selected = value === opt.id;
              return (
                <button
                  key={opt.id}
                  className="choice"
                  data-selected={selected}
                  onClick={() => onPick(q.id, opt.id)}
                >
                  <span>
                    <span className="choice-ix">Option {String(i + 1).padStart(2, '0')}</span>
                    <span className="choice-label">{opt.label}</span>
                    {opt.sub && <span className="choice-sub">{opt.sub}</span>}
                  </span>
                  <span className="choice-mark">{selected ? '●' : '→'}</span>
                </button>
              );
            })}
          </div>

          <div className="q-foot">
            <button className="btn-text" onClick={onBack}>← Back</button>
            <div style={{ display: 'flex', gap: 14, alignItems: 'center' }}>
              <button className="btn-text" onClick={onSkip}>Skip the rest</button>
              <button className="btn btn-primary" onClick={onNext} disabled={!value}>
                {index === total - 1 ? 'Continue to unlock' : 'Next'}&nbsp;&nbsp;→
              </button>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

// ---- Lead capture ------------------------------------------------------
// Free / consumer email providers we reject. The audit is for B2B teams,
// so a work email gives us the company domain for free and filters most
// throwaway signups.
const FREE_EMAIL_DOMAINS = new Set([
  'gmail.com','googlemail.com','yahoo.com','yahoo.co.uk','yahoo.fr','yahoo.es',
  'outlook.com','hotmail.com','live.com','msn.com',
  'icloud.com','me.com','mac.com',
  'protonmail.com','proton.me','pm.me',
  'aol.com','gmx.com','gmx.net','gmx.de','mail.com',
  'yandex.com','yandex.ru','zoho.com','fastmail.com','fastmail.fm','hey.com',
  'tutanota.com','tuta.io','tutamail.com','disroot.org',
]);

function Capture({ onSubmit, onBack }) {
  const [form, setForm] = useState({ first: '', last: '', email: '', industry: '' });
  const [errors, setErrors] = useState({});
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const validate = () => {
    const e = {};
    if (!form.first.trim()) e.first = 'Required';
    if (!form.last.trim())  e.last  = 'Required';
    const email = form.email.trim().toLowerCase();
    if (!email) e.email = 'Required';
    else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) e.email = 'Enter a valid email';
    else {
      const domain = email.split('@')[1] || '';
      if (FREE_EMAIL_DOMAINS.has(domain)) e.email = 'Please use a work email, not a personal one';
    }
    if (!form.industry) e.industry = 'Required';
    setErrors(e);
    return Object.keys(e).length === 0;
  };

  const submit = (ev) => {
    ev.preventDefault();
    if (!validate()) return;
    // Pull the Turnstile token from the hidden field the widget creates.
    const tsField = document.querySelector('[name="cf-turnstile-response"]');
    const turnstileToken = tsField ? tsField.value : '';
    onSubmit({ ...form, turnstileToken });
  };

  return (
    <div className="shell stage">
      <div className="eyebrow">
        <span>Unlock</span>
        <span className="rule"></span>
        <span>One more step</span>
      </div>
      <div className="intro-head" style={{ marginTop: 30 }}>
        <span className="ix">Step 06<br/>of 07</span>
        <div>
          <h2 className="intro-title" style={{ fontSize: 'clamp(40px, 6.5vw, 84px)' }}>Where should I <em>send it?</em></h2>
          <p className="intro-deck" style={{ marginBottom: 0 }}>
            Your AI Opportunity Map is ready. Drop your name and work email and I'll show it on the next screen and send a PDF copy to keep.
          </p>

          <form onSubmit={submit}>
            <div className="form-grid">
              <div className={`field ${errors.first ? 'invalid' : ''}`}>
                <label>First name <span className="req">*</span></label>
                <input type="text" value={form.first} onChange={e => set('first', e.target.value)} placeholder="Eduardo" autoFocus />
                <span className="err">{errors.first || ''}</span>
              </div>
              <div className={`field ${errors.last ? 'invalid' : ''}`}>
                <label>Last name <span className="req">*</span></label>
                <input type="text" value={form.last} onChange={e => set('last', e.target.value)} placeholder="de la Espriella" />
                <span className="err">{errors.last || ''}</span>
              </div>
              <div className={`field full ${errors.email ? 'invalid' : ''}`}>
                <label>Work email <span className="req">*</span></label>
                <input type="email" value={form.email} onChange={e => set('email', e.target.value)} placeholder="you@company.com" />
                <span className="err">{errors.email || ''}</span>
              </div>
              <div className={`field full ${errors.industry ? 'invalid' : ''}`}>
                <label>Industry <span className="req">*</span></label>
                <select value={form.industry} onChange={e => set('industry', e.target.value)}>
                  <option value="">Pick one</option>
                  {INDUSTRIES.map(i => <option key={i.id} value={i.id}>{i.label}</option>)}
                </select>
                <span className="err">{errors.industry || ''}</span>
              </div>
              <div className="field full">
                <div className="cf-turnstile" data-sitekey="0x4AAAAAADHpeh998mXKmN2O" data-theme="auto" data-size="flexible"></div>
              </div>
            </div>

            <p className="form-fine">
              I'll send you the full PDF and won't spam you. Unsubscribe anytime. If the audit turns into a conversation, that's your call, not mine.
            </p>

            <div className="q-foot" style={{ marginTop: 16, borderTop: 0, paddingTop: 0 }}>
              <button type="button" className="btn-text" onClick={onBack}>← Back to questions</button>
              <button type="submit" className="btn btn-primary">Show my map&nbsp;&nbsp;→</button>
            </div>
          </form>
        </div>
      </div>
    </div>
  );
}

// ---- Results -----------------------------------------------------------
function ImpactBadge({ level }) {
  const cls = level === 'High' ? 'badge-high' : level === 'Medium' ? 'badge-med' : 'badge-low';
  return <span className={`badge ${cls}`}><span className="bdot" style={{ background: 'currentColor' }}></span>Impact · {level}</span>;
}
function EffortBadge({ level }) {
  // Effort always uses the calm teal / muted, never orange
  const cls = level === 'Low' ? 'badge-med' : level === 'Medium' ? 'badge-med' : 'badge-low';
  return <span className={`badge ${cls}`} style={{ color: 'var(--muted)', borderColor: 'var(--rule-2)' }}>
    <span className="bdot" style={{ background: 'currentColor' }}></span>Effort · {level}
  </span>;
}

// ---- Prompt block ------------------------------------------------------
// Lives below the opportunities. Two copy-able panes: a prompt shaped by
// the user's answers, and a context template they fill in and paste under it.
// The prompt prefers the AI-generated version (aiPrompt) when present, with
// the static buildPrompt() output as a fallback if the AI call hasn't
// returned yet or failed.
function PromptBlock({ answers, opportunityMap, aiPrompt, followupPairs }) {
  const fallback = useMemo(() => buildPrompt(answers, opportunityMap, followupPairs), [answers, opportunityMap, followupPairs]);
  const prompt = aiPrompt || fallback;
  const context = useMemo(() => buildContextTemplate(), []);
  const [copied, setCopied] = useState(null); // 'prompt' | 'context' | null

  const copy = async (text, key) => {
    try {
      await navigator.clipboard.writeText(text);
    } catch (_) {
      // Fallback: select the text so the user can hit cmd/ctrl+C themselves.
      const el = document.getElementById('prompt-pane-' + key);
      if (el) {
        const r = document.createRange();
        r.selectNodeContents(el);
        const s = window.getSelection();
        s.removeAllRanges();
        s.addRange(r);
      }
    }
    setCopied(key);
    setTimeout(() => setCopied(c => (c === key ? null : c)), 2000);
  };

  return (
    <section className="prompt-block">
      <div className="prompt-head">
        <h3>Take this <em>to your AI.</em></h3>
        <p className="prompt-deck">
          A prompt and a context template, shaped by your answers. Paste both into Claude, ChatGPT, or whatever you use. Both are also in the PDF you download below.
        </p>
      </div>

      <div className="prompt-pane">
        <div className="prompt-pane-head">
          <span className="prompt-pane-tag">01 · Prompt</span>
          <button type="button" className="copy-btn" onClick={() => copy(prompt, 'prompt')}>
            {copied === 'prompt' ? 'Copied ✓' : 'Copy prompt ⧉'}
          </button>
        </div>
        <pre id="prompt-pane-prompt" className="prompt-text">{prompt}</pre>
      </div>

      <div className="prompt-pane">
        <div className="prompt-pane-head">
          <span className="prompt-pane-tag">02 · Context to fill in</span>
          <button type="button" className="copy-btn" onClick={() => copy(context, 'context')}>
            {copied === 'context' ? 'Copied ✓' : 'Copy template ⧉'}
          </button>
        </div>
        <pre id="prompt-pane-context" className="prompt-text">{context}</pre>
      </div>
    </section>
  );
}

function Results({ answers, lead, onRestart, onDownload, onBookCall, enrichment, enriching, followupPairs }) {
  const map = useMemo(() => buildOpportunityMap(answers), [answers]);
  const goal = ANSWER_LABELS.goal[answers.goal];
  const size = ANSWER_LABELS.size[answers.size];
  const timesink = ANSWER_LABELS.timesink[answers.timesink];
  const blocker = ANSWER_LABELS.blocker[answers.blocker];
  const whyLines = (enrichment && enrichment.whyLines) || {};

  return (
    <div className="shell stage">
      <div className="eyebrow">
        <span>Output</span>
        <span className="rule"></span>
        <span>Prepared for {lead.first}{lead.last ? ` ${lead.last}` : ''}</span>
      </div>

      <div className="res-head">
        <span className="res-ix">Output</span>
        <div>
          <h1 className="res-title">Your AI<br/><em>Opportunity Map.</em></h1>
          <p className="res-deck">
            Based on your answers, here are the highest-leverage AI moves for your team right now, sequenced and not stacked.
          </p>
        </div>
      </div>

      <div className="res-meta">
        <div><span className="k">Prepared for</span><span className="v">{lead.first}{lead.last ? ` ${lead.last}` : ''}</span></div>
        <div><span className="k">Team size</span><span className="v">{size}</span></div>
        <div><span className="k">Goal</span><span className="v">{goal}</span></div>
        <div><span className="k">Biggest blocker</span><span className="v">{blocker}</span></div>
      </div>

      <div className="opp-section-head">
        <h3>{map.length} <em>opportunities</em>, in order</h3>
        <span className="count">{enriching ? 'Personalising · live' : `Time sink · ${timesink}`}</span>
      </div>

      {map.map(({ opp, why }, i) => {
        const aiWhy = whyLines[opp.id];
        return (
          <div className="opp" key={opp.id}>
            <span className="opp-num">No.<br/><em>{String(i + 1).padStart(2, '0')}</em></span>
            <div className="opp-body">
              <h4 className="opp-title">{opp.title}.</h4>
              <p className="opp-desc">{opp.desc}</p>
              <div className="opp-badges">
                <ImpactBadge level={opp.impact} />
                <EffortBadge level={opp.effort} />
              </div>
              <p className="opp-why"><span style={{ fontFamily: 'var(--font-mono)', fontStyle: 'normal', fontSize: 10, letterSpacing: '.14em', textTransform: 'uppercase', color: 'var(--anchor)', marginRight: 10 }}>Why this matters for you ·</span>{aiWhy || why}</p>
            </div>
          </div>
        );
      })}

      <PromptBlock answers={answers} opportunityMap={map} aiPrompt={enrichment && enrichment.prompt} followupPairs={followupPairs} />

      <div className="res-cta">
        <button className="btn btn-primary" onClick={onBookCall}>
          Book a full AI audit call&nbsp;&nbsp;→
        </button>
        <button className="btn btn-ghost" onClick={onDownload}>Download as PDF&nbsp;&nbsp;↓</button>
        <button className="btn-text" onClick={onRestart} style={{ marginLeft: 'auto' }}>↺&nbsp;&nbsp;Start over</button>
      </div>

      <div className="res-footer">
        Built by Eduardo de la Espriella · A simplified preview of the full AI for Marketing Audit · eddieespriella.com
      </div>
    </div>
  );
}

Object.assign(window, { Masthead, Progress, Intro, QuestionStage, Capture, Results });
