/* eslint-disable */
const { useState, useEffect, useRef } = React;

const WORKSPACE_DEFAULTS = {
  product: "",
  description: "",
  stage: "Pre-launch",
  region: "Global EN",
  budget: "",
  tone: "Editorial",
};

const AGENT_NAMES = [
  "Analyze Marketing Opportunity",
  "Develop Content Strategy",
  "Develop Campaign Plan",
  "Define Analytics Framework",
];

// ───────────────────────────── Generation progress overlay
function GeneratingView({ workspace, onComplete, onError }) {
  const [steps, setSteps] = useState(
    AGENT_NAMES.map(name => ({ name, status: "pending" }))
  );
  const [errorMsg, setErrorMsg] = useState(null);
  const started = useRef(false);

  useEffect(() => {
    if (started.current) return;
    started.current = true;

    (async () => {
      try {
        const res = await fetch("/api/generate", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ workspace }),
        });

        const reader = res.body.getReader();
        const decoder = new TextDecoder();
        let buffer = "";

        while (true) {
          const { done, value } = await reader.read();
          if (done) break;
          buffer += decoder.decode(value, { stream: true });
          const lines = buffer.split("\n");
          buffer = lines.pop();

          for (const line of lines) {
            if (!line.startsWith("data: ")) continue;
            try {
              const evt = JSON.parse(line.slice(6));
              if (evt.type === "agent_start") {
                setSteps(s => s.map((step, i) =>
                  i === evt.index ? { ...step, status: "running" } : step
                ));
              } else if (evt.type === "agent_complete") {
                setSteps(s => s.map((step, i) =>
                  i === evt.index ? { ...step, status: "done" } : step
                ));
              } else if (evt.type === "complete") {
                onComplete(evt.results);
              } else if (evt.type === "error") {
                setErrorMsg(evt.message);
              }
            } catch {}
          }
        }
      } catch (err) {
        setErrorMsg(err.message);
      }
    })();
  }, []);

  return (
    <div className="ws-page">
      <header className="ws-topbar">
        <div className="brand">
          <div className="brand-mark"></div>
          <div className="brand-word">getplan.today</div>
          <div className="brand-tag">PLAN</div>
        </div>
      </header>
      <div className="ws-body">
        <div className="ws-hero">
          <div className="ws-hero-label">Building your plan</div>
          <h1 className="ws-hero-title">
            Analyzing <em>{workspace.product}</em>
          </h1>
          <p className="ws-hero-sub">
            Four AI agents are working through your marketing strategy.
            This takes about 30–60 seconds.
          </p>
        </div>

        <div className="gen-steps">
          {steps.map((step, i) => (
            <div key={i} className={`gen-step gen-step--${step.status}`}>
              <div className="gen-step-icon">
                {step.status === "done"    && <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M5 13l4 4L19 7"/></svg>}
                {step.status === "running" && <div className="gen-spinner"/>}
                {step.status === "pending" && <div className="gen-dot"/>}
              </div>
              <span className="gen-step-num">{String(i + 1).padStart(2, "0")}</span>
              <span className="gen-step-name">{step.name}</span>
            </div>
          ))}
        </div>

        {errorMsg && (
          <div className="gen-error">
            <strong>Error:</strong> {errorMsg}
            <button className="btn btn-ghost" style={{marginLeft:12}} onClick={onError}>← Try again</button>
          </div>
        )}
      </div>
    </div>
  );
}

// ───────────────────────────── URL fetch helper
function UrlImport({ onImport }) {
  const [url, setUrl] = useState("");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  async function handleFetch() {
    const trimmed = url.trim();
    if (!trimmed) return;
    setLoading(true);
    setError(null);
    try {
      const res = await fetch("/api/fetch-url", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ url: trimmed }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Failed to fetch");
      onImport(data);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  }

  return (
    <div className="url-import">
      <div className="url-import-row">
        <input
          className="ws-field-input url-import-input"
          placeholder="Paste your product URL — e.g. https://automate.dev"
          value={url}
          onChange={e => { setUrl(e.target.value); setError(null); }}
          onKeyDown={e => e.key === "Enter" && handleFetch()}
          disabled={loading}
        />
        <button
          className={`url-import-btn${loading ? " url-import-btn--loading" : ""}`}
          onClick={handleFetch}
          disabled={loading || !url.trim()}
          type="button"
        >
          {loading ? <div className="gen-spinner gen-spinner--sm" /> : (
            <>
              Import
              <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2">
                <path d="M5 12h14M13 5l7 7-7 7"/>
              </svg>
            </>
          )}
        </button>
      </div>
      {error && <div className="url-import-error">{error}</div>}
      <div className="url-import-divider"><span>or fill in manually</span></div>
    </div>
  );
}

// ───────────────────────────── Workspace page
function WorkspacePage({ onGenerate, onBackToPlan }) {
  const [ws, setWs] = useState(WORKSPACE_DEFAULTS);
  const [generating, setGenerating] = useState(false);
  const set = k => e => setWs(v => ({ ...v, [k]: e.target.value }));
  const canSubmit = ws.product.trim().length > 0;

  function handleUrlImport({ product, description }) {
    setWs(v => ({
      ...v,
      product: product || v.product,
      description: description || v.description,
    }));
  }

  if (generating) {
    return (
      <GeneratingView
        workspace={ws}
        onComplete={results => onGenerate(ws, results)}
        onError={() => setGenerating(false)}
      />
    );
  }

  return (
    <div className="ws-page">
      <header className="ws-topbar">
        <div className="brand">
          <div className="brand-mark"></div>
          <div className="brand-word">getplan.today</div>
          <div className="brand-tag">PLAN</div>
        </div>
        <div style={{ marginLeft: 'auto', display: 'flex', gap: 8, alignItems: 'center' }}>
          {onBackToPlan && (
            <button className="btn btn-ghost" onClick={onBackToPlan}>← Back to plan</button>
          )}
          <UserMenu />
        </div>
      </header>

      <div className="ws-body">
        <div className="ws-hero">
          <div className="ws-hero-label">New marketing plan</div>
          <h1 className="ws-hero-title">
            Tell us about your <em>product</em>
          </h1>
          <p className="ws-hero-sub">
            Fill in the details below. getplan.today uses them to generate a
            tailored go-to-market plan with real numbers, real channels, and
            an AI assistant to refine it with you.
          </p>
        </div>

        <form
          className="ws-form"
          onSubmit={e => { e.preventDefault(); if (canSubmit) onGenerate(ws); }}
        >
          <UrlImport onImport={handleUrlImport} />

          <div className="ws-form-row ws-form-row--full">
            <label className="ws-form-label">
              Product name <span className="ws-required">*</span>
            </label>
            <input
              className="ws-field-input"
              placeholder="e.g. Automate.dev"
              value={ws.product}
              onChange={set("product")}
              autoFocus
            />
          </div>

          <div className="ws-form-row ws-form-row--full">
            <label className="ws-form-label">What does it do?</label>
            <textarea
              className="ws-field-input ws-field-textarea"
              placeholder="One or two sentences. e.g. Pay-as-you-go workflow automation for indie developers — 50–70% cheaper than Zapier."
              value={ws.description}
              onChange={set("description")}
              rows={3}
            />
          </div>

          <div className="ws-form-grid">
            <div className="ws-form-row">
              <label className="ws-form-label">Stage</label>
              <select className="ws-field-input ws-field-select" value={ws.stage} onChange={set("stage")}>
                <option>Pre-launch</option>
                <option>Launch</option>
                <option>Early growth</option>
                <option>Scale</option>
                <option>Mature</option>
              </select>
            </div>

            <div className="ws-form-row">
              <label className="ws-form-label">Region</label>
              <select className="ws-field-input ws-field-select" value={ws.region} onChange={set("region")}>
                <option>Global EN</option>
                <option>North America</option>
                <option>Europe</option>
                <option>LATAM</option>
                <option>APAC</option>
              </select>
            </div>

            <div className="ws-form-row">
              <label className="ws-form-label">Budget</label>
              <input
                className="ws-field-input"
                placeholder="e.g. $80k / 12 mo"
                value={ws.budget}
                onChange={set("budget")}
              />
            </div>

            <div className="ws-form-row">
              <label className="ws-form-label">Tone</label>
              <select className="ws-field-input ws-field-select" value={ws.tone} onChange={set("tone")}>
                <option>Editorial</option>
                <option>Casual</option>
                <option>Technical</option>
                <option>Bold</option>
                <option>Minimal</option>
              </select>
            </div>
          </div>

          <div className="ws-form-footer">
            <button
              type="submit"
              className={`ws-submit ${canSubmit ? "" : "ws-submit--disabled"}`}
              disabled={!canSubmit}
              onClick={() => canSubmit && setGenerating(true)}
            >
              Generate marketing plan
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2">
                <path d="M5 12h14M13 5l7 7-7 7"/>
              </svg>
            </button>
            <span className="ws-submit-note">
              Takes a few seconds · powered by Claude
            </span>
          </div>
        </form>
      </div>
    </div>
  );
}

// ───────────────────────────── Inline-editable field (sidebar)
function WorkspaceField({ label, value, onChange, options }) {
  const [editing, setEditing] = useState(false);
  const inputRef = useRef();

  useEffect(() => {
    if (editing && inputRef.current) inputRef.current.focus();
  }, [editing]);

  function commit(v) {
    setEditing(false);
    if (v.trim() && v.trim() !== value) onChange(v.trim());
  }

  return (
    <div className="row ws-row" onClick={() => !editing && setEditing(true)}>
      <span className="ws-label">{label}</span>
      {editing ? (
        options ? (
          <select
            ref={inputRef}
            className="ws-input"
            defaultValue={value}
            onBlur={e => commit(e.target.value)}
            onChange={e => commit(e.target.value)}
          >
            {options.map(o => <option key={o} value={o}>{o}</option>)}
          </select>
        ) : (
          <input
            ref={inputRef}
            className="ws-input"
            defaultValue={value}
            onBlur={e => commit(e.target.value)}
            onKeyDown={e => {
              if (e.key === "Enter") commit(e.target.value);
              if (e.key === "Escape") setEditing(false);
            }}
          />
        )
      ) : (
        <span className="ws-value" title="Click to edit">{value || <em style={{opacity:.4}}>—</em>}</span>
      )}
    </div>
  );
}

// ───────────────────────────── Sidebar
function Sidebar({ active, onJump, workspace, onWorkspace }) {
  function set(key) {
    return v => onWorkspace({ ...workspace, [key]: v });
  }

  return (
    <aside className="sidebar">
      <div className="side-section">
        <div className="side-label">
          <span>Document</span>
          <span style={{ fontFamily: "var(--mono)", color: "var(--accent)" }}>v3.2</span>
        </div>
        {SECTIONS.map(s => (
          <button
            key={s.id}
            className={`toc-item ${active === s.id ? "active" : ""}`}
            onClick={() => onJump(s.id)}
          >
            <span className="toc-num">{s.num}</span>
            <span className="toc-name">{s.name}</span>
            <span className="toc-meta">{s.meta}</span>
          </button>
        ))}
      </div>

      <div className="side-section">
        <div className="side-label"><span>Workspace</span></div>
        <div className="side-meta ws-fields">
          <WorkspaceField label="Product"  value={workspace.product}     onChange={set("product")} />
          <WorkspaceField label="Desc."    value={workspace.description} onChange={set("description")} />
          <WorkspaceField label="Stage"    value={workspace.stage}       onChange={set("stage")}
            options={["Pre-launch", "Launch", "Early growth", "Scale", "Mature"]} />
          <WorkspaceField label="Region"   value={workspace.region}      onChange={set("region")}
            options={["Global EN", "North America", "Europe", "LATAM", "APAC"]} />
          <WorkspaceField label="Budget"   value={workspace.budget}      onChange={set("budget")} />
          <WorkspaceField label="Tone"     value={workspace.tone}        onChange={set("tone")}
            options={["Editorial", "Casual", "Technical", "Bold", "Minimal"]} />
        </div>
      </div>

      <div className="side-section">
        <div className="side-label"><span>Activity</span></div>
        <div className="side-meta">
          <div className="row"><span>Regenerated</span><span>just now</span></div>
          <div className="row"><span>Sections edited</span><span>0 / 8</span></div>
          <div className="row"><span>Citations</span><span>34</span></div>
        </div>
      </div>
    </aside>
  );
}

// ───────────────────────────── Shared user menu
function getInitials(user) {
  const src = (user?.name || user?.email || '').trim();
  if (!src) return '?';
  const parts = src.split(/[\s@.]+/);
  if (parts.length >= 2 && user?.name) return (parts[0][0] + parts[1][0]).toUpperCase();
  return src[0].toUpperCase();
}

function UserMenu() {
  const user = window.__currentUser;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginLeft: 8, borderLeft: '1px solid var(--rule)', paddingLeft: 12 }}>
      <div style={{ width: 28, height: 28, borderRadius: '50%', background: 'var(--accent)', color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 11, fontWeight: 700, flexShrink: 0, letterSpacing: 0.2 }}>
        {getInitials(user)}
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', lineHeight: 1.35, maxWidth: 150 }}>
        {user?.name && (
          <span style={{ fontSize: 12, fontWeight: 500, color: 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{user.name}</span>
        )}
        <span style={{ fontSize: 11, color: 'var(--muted)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{user?.email || ''}</span>
      </div>
      <button
        className="btn btn-ghost"
        style={{ fontSize: 12, padding: '4px 8px', flexShrink: 0 }}
        onClick={async () => {
          await fetch('/api/auth/logout', { method: 'POST', credentials: 'include' });
          window.location.reload();
        }}
      >
        Sign out
      </button>
    </div>
  );
}

// ───────────────────────────── Export helpers
function slugify(str) {
  return (str || "plan").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
}

function triggerDownload(content, filename, mimeType) {
  const blob = new Blob([content], { type: mimeType });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  a.click();
  URL.revokeObjectURL(url);
}

function generateMarkdown(workspace, planData) {
  const ma  = planData?.market_analysis || {};
  const cp  = planData?.campaign_plan   || {};
  const af  = planData?.analytics_framework || {};

  const fit      = ma.market_fit           || TPL.market_fit;
  const size     = ma.market_size          || TPL.market_size;
  const segments = ma.target_segments      || TPL.target_segments;
  const vps      = ma.value_propositions   || TPL.value_propositions;
  const moats    = ma.competitive_advantages || TPL.competitive_advantages;
  const channels = ma.channels             || TPL.channels;
  const cacData  = ma.cac                  || TPL.cac;
  const phases   = cp.phases               || TPL.phases;
  const kpis     = af.kpi_dashboard
    ? af.kpi_dashboard.slice(0, 6).map(k => ({ kpi: k.kpi, target: k.target }))
    : TPL.kpis.map(k => ({ kpi: k.kpi, target: k.target }));
  const north    = af.north_star_metric    || TPL.north_star;

  const date = new Date().toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric" });

  const lines = [
    `# ${workspace.product || "Marketing Plan"} — Go-to-Market Plan`,
    ``,
    `| Field | Value |`,
    `|-------|-------|`,
    `| Stage | ${workspace.stage || "—"} |`,
    `| Region | ${workspace.region || "—"} |`,
    `| Budget | ${workspace.budget || "—"} |`,
    `| Tone | ${workspace.tone || "—"} |`,
    `| Prepared | ${date} |`,
    ``,
    `---`,
    ``,
    `## §01 Market Fit`,
    ``,
    `**Verdict:** ${fit.verdict || fitVerdict(fit.score)} (score: ${fit.score}/10)`,
    ``,
    fit.summary,
    ``,
    `| Metric | Value |`,
    `|--------|-------|`,
    `| TAM | ${size.tam} |`,
    `| CAGR | ${size.cagr} |`,
    `| Addressable users | ${size.users} |`,
    `| Pricing gap | ${size.gap} vs. incumbents |`,
    ``,
    fit.strengths?.length ? `**Strengths:** ${fit.strengths.join(" · ")}` : "",
    fit.risks?.length     ? `**Risks:** ${fit.risks.join(" · ")}`         : "",
    ``,
    `---`,
    ``,
    `## §02 Target Audience`,
    ``,
    `| # | Segment | Defining trait | TAM | Priority |`,
    `|---|---------|----------------|-----|----------|`,
    ...segments.map((s, i) => `| ${String(i+1).padStart(2,"0")} | ${s.name} | ${s.subtitle} | ${s.tam} | ${s.priority} |`),
    ``,
    `---`,
    ``,
    `## §03 Value Propositions`,
    ``,
    ...vps.map((v, i) => [`### ${String(i+1).padStart(2,"0")}. ${v.title}`, ``, v.description, ``, `*${v.tag}*`, ``]).flat(),
    `---`,
    ``,
    `## §04 Competitive Advantages`,
    ``,
    ...moats.map(m => [`### ${m.name} (strength: ${m.strength})`, ``, m.description, ``, `*Durability: ${m.durability}*`, ``]).flat(),
    `---`,
    ``,
    `## §05 Channels (Phase 1)`,
    ``,
    `| # | Channel | Tactic | Priority | CAC |`,
    `|---|---------|--------|----------|-----|`,
    ...channels.map((c, i) => `| ${String(i+1).padStart(2,"0")} | ${c.name} | ${c.tactic} | ${c.priority} | ${c.cac} |`),
    ``,
    `---`,
    ``,
    `## §06 CAC by Channel`,
    ``,
    `**Blended CAC:** $${cacData.blended_low}–${cacData.blended_high}`,
    `**Best channel:** ${cacData.best_channel}`,
    ``,
    cacData.tagline,
    ``,
    `---`,
    ``,
    `## §07 Execution Roadmap`,
    ``,
    ...phases.map(p => [
      `### ${p.when} — ${p.name}`,
      ``,
      ...(p.milestones || []).map(m => `- [ ] ${m}`),
      ``,
      `**Target:** ${p.target}`,
      ``,
    ]).flat(),
    `---`,
    ``,
    `## §08 Success Metrics`,
    ``,
    `| KPI | Target |`,
    `|-----|--------|`,
    ...kpis.map(k => `| ${k.kpi} | ${k.target} |`),
    ``,
    `**North star:** ${north.metric || north.definition}`,
    ``,
    north.target,
  ];

  return lines.filter(l => l !== undefined).join("\n");
}

async function generateHTMLExport(workspace, planData) {
  const cssText = await fetch("/styles.css").then(r => r.text());
  const docEl   = document.querySelector(".doc");
  if (!docEl) return;
  const docHTML  = docEl.outerHTML;
  const date     = new Date().toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric" });
  const title    = `${workspace.product || "Marketing Plan"} — Go-to-Market Plan`;

  const html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>${title}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=DM+Mono:wght@400;500&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<style>
${cssText}
.doc { max-width: 740px; margin: 0 auto; padding: 3rem 2rem; }
</style>
</head>
<body style="background:var(--bg,#FAF8F3);margin:0">
${docHTML}
</body>
</html>`;

  triggerDownload(html, `${slugify(workspace.product)}-marketing-plan.html`, "text/html");
}

function ExportMenu({ workspace, planData }) {
  const [open, setOpen] = useState(false);
  const menuRef = useRef();

  useEffect(() => {
    if (!open) return;
    function onOutside(e) {
      if (menuRef.current && !menuRef.current.contains(e.target)) setOpen(false);
    }
    document.addEventListener("mousedown", onOutside);
    return () => document.removeEventListener("mousedown", onOutside);
  }, [open]);

  function handlePDF() {
    setOpen(false);
    window.print();
  }

  function handleMarkdown() {
    setOpen(false);
    const md = generateMarkdown(workspace, planData);
    triggerDownload(md, `${slugify(workspace.product)}-marketing-plan.md`, "text/markdown");
  }

  async function handleHTML() {
    setOpen(false);
    await generateHTMLExport(workspace, planData);
  }

  return (
    <div className="export-menu" ref={menuRef}>
      <button className="btn btn-accent" onClick={() => setOpen(o => !o)}>
        <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
          <path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><path d="M7 10l5 5 5-5"/><path d="M12 15V3"/>
        </svg>
        Export
        <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" style={{marginLeft:2}}>
          <path d="M6 9l6 6 6-6"/>
        </svg>
      </button>
      {open && (
        <div className="export-dropdown">
          <button className="export-option" onClick={handlePDF}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" style={{marginRight:8,flexShrink:0}}>
              <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><path d="M14 2v6h6"/>
            </svg>
            PDF
          </button>
          <button className="export-option" onClick={handleMarkdown}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" style={{marginRight:8,flexShrink:0}}>
              <rect x="3" y="3" width="18" height="18" rx="2"/><path d="M7 15V9l3 3 3-3v6"/><path d="M17 9v6"/>
            </svg>
            Markdown
          </button>
          <button className="export-option" onClick={handleHTML}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" style={{marginRight:8,flexShrink:0}}>
              <polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/>
            </svg>
            HTML
          </button>
        </div>
      )}
    </div>
  );
}

// ───────────────────────────── Topbar
function Topbar({ workspace, planData, onBackToWorkspace, onHistory }) {
  return (
    <header className="topbar">
      <div className="brand" style={{ cursor: "pointer" }} onClick={onBackToWorkspace}>
        <div className="brand-mark"></div>
        <div className="brand-word">getplan.today</div>
        <div className="brand-tag">PLAN</div>
      </div>
      <div className="crumbs">
        <button className="crumb-link" onClick={onBackToWorkspace}>Workspace</button>
        <span className="sep">/</span>
        <span>{workspace.product || "Untitled"}</span>
        <span className="sep">/</span>
        <span className="doc-title">Go-to-market plan</span>
        <span className="doc-meta">· v3.2 · auto-saved</span>
      </div>
      <div className="top-actions">
        <button className="btn btn-ghost" title="History" onClick={onHistory}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8">
            <circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>
          </svg>
          History
        </button>
        <button className="btn btn-ghost">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8">
            <path d="M4 12v7a1 1 0 001 1h14a1 1 0 001-1v-7"/><path d="M16 6l-4-4-4 4"/><path d="M12 2v14"/>
          </svg>
          Share
        </button>
        <ExportMenu workspace={workspace} planData={planData} />
        <UserMenu />
      </div>
    </header>
  );
}

// ───────────────────────────── Refine panel
function RefinePanel({ workspace }) {
  const [scope, setScope] = useState("Whole plan");
  const [input, setInput] = useState("");
  const [thread, setThread] = useState([
    {
      role: "ai",
      text: `I've drafted a go-to-market plan for ${workspace.product || "your product"}. Ask me to adjust any section, change messaging, or rethink the channel strategy.`,
    },
  ]);
  const threadRef = useRef();

  useEffect(() => {
    if (threadRef.current) threadRef.current.scrollTop = threadRef.current.scrollHeight;
  }, [thread]);

  async function send(text) {
    if (!text.trim()) return;
    const history = thread;
    setThread(t => [...t, { role: "user", text }]);
    setInput("");
    setThread(t => [...t, { role: "ai", text: "", streaming: true }]);

    try {
      const res = await fetch("/api/refine", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ message: text, scope, history, workspace }),
      });

      const reader = res.body.getReader();
      const decoder = new TextDecoder();
      let buffer = "";
      let accumulated = "";

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split("\n");
        buffer = lines.pop();
        for (const line of lines) {
          if (!line.startsWith("data: ")) continue;
          const data = line.slice(6);
          if (data === "[DONE]") break;
          try {
            const { text: chunk, error } = JSON.parse(data);
            if (error) { accumulated = `Error: ${error}`; break; }
            if (chunk) {
              accumulated += chunk;
              setThread(t => {
                const next = [...t];
                next[next.length - 1] = { role: "ai", text: accumulated, streaming: true };
                return next;
              });
            }
          } catch {}
        }
      }

      setThread(t => {
        const next = [...t];
        next[next.length - 1] = { role: "ai", text: accumulated || next[next.length - 1].text };
        return next;
      });
    } catch (err) {
      setThread(t => {
        const next = [...t];
        next[next.length - 1] = { role: "ai", text: `Error: ${err.message}` };
        return next;
      });
    }
  }

  return (
    <aside className="refine">
      <div className="refine-head">
        <div className="refine-title">Refine</div>
        <div className="refine-sub">
          Ask for changes in plain language. Edits are applied scoped to the
          chips below and re-cited automatically.
        </div>
        <div className="scope-chips">
          {["Whole plan", "§01 Fit", "§03 Value", "§05 Channels", "§07 Roadmap"].map(s => (
            <button
              key={s}
              className={`scope-chip ${scope === s ? "active" : ""}`}
              onClick={() => setScope(s)}
            >{s}</button>
          ))}
        </div>
      </div>

      <div className="thread" ref={threadRef}>
        {thread.map((m, i) => (
          <div className={`msg ${m.role}`} key={i}>
            <div className="msg-meta">{m.role === "ai" ? "getplan.today" : "You"} · {timeAgo(i, thread.length)}</div>
            <div className={`msg-body${m.streaming ? " msg-streaming" : ""}`}>{m.text}</div>
            {m.diff && (
              <div className="msg-diff">
                {m.diff.map((d, j) => (
                  <span key={j} className={`diff-chip ${d.type === "minus" ? "minus" : ""}`}>{d.text}</span>
                ))}
              </div>
            )}
          </div>
        ))}
      </div>

      <div className="suggestions">
        {SUGGESTED.slice(0, 3).map(s => (
          <button key={s} className="suggestion" onClick={() => send(s)}>{s}</button>
        ))}
      </div>

      <div className="composer">
        <div className="composer-box">
          <textarea
            placeholder="Refine the plan — e.g. 'add a pricing experiment in month 4'"
            value={input}
            onChange={e => setInput(e.target.value)}
            onKeyDown={e => {
              if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); send(input); }
            }}
          />
          <div className="composer-actions">
            <div className="composer-tools">
              <button className="composer-tool" title="Attach">＋</button>
              <button className="composer-tool" title="Cite">"</button>
              <button className="composer-tool" title="Voice">●</button>
            </div>
            <button className="send-btn" onClick={() => send(input)}>
              Apply
              <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4">
                <path d="M5 12h14M13 5l7 7-7 7"/>
              </svg>
            </button>
          </div>
        </div>
      </div>

      <div className="refine-foot">
        <span>scope · {scope}</span>
        <span>haiku 4.5</span>
      </div>
    </aside>
  );
}

function timeAgo(i, total) {
  const mins = [22, 18, 15, 11, 6, 2, 1];
  return `${mins[i % mins.length]}m`;
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "warm",
  "serif": "\"Instrument Serif\", Georgia, serif",
  "showRefine": true
}/*EDITMODE-END*/;

// ───────────────────────────── History page
function HistoryPage({ onBack, onLoad }) {
  const [plans, setPlans] = useState([]);
  const [fetching, setFetching] = useState(true);

  useEffect(() => {
    fetch("/api/plans", { credentials: "include" })
      .then(r => r.json())
      .then(d => { setPlans(d.plans || []); setFetching(false); })
      .catch(() => setFetching(false));
  }, []);

  function formatDate(str) {
    return new Date(str).toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric" });
  }

  return (
    <div className="ws-page">
      <header className="ws-topbar">
        <div className="brand" style={{ cursor: "pointer" }} onClick={onBack}>
          <div className="brand-mark"></div>
          <div className="brand-word">getplan.today</div>
          <div className="brand-tag">PLAN</div>
        </div>
        <div style={{ marginLeft: "auto", display: "flex", gap: 8, alignItems: "center" }}>
          <button className="btn btn-ghost" onClick={onBack}>← Back</button>
          <UserMenu />
        </div>
      </header>
      <div className="ws-body">
        <div className="ws-hero">
          <div className="ws-hero-label">History</div>
          <h1 className="ws-hero-title">Past <em>plans</em></h1>
          <p className="ws-hero-sub">Click any plan to load it into the editor.</p>
        </div>
        {fetching ? (
          <div style={{ display: "flex", justifyContent: "center", padding: "3rem 0" }}>
            <div className="gen-spinner" />
          </div>
        ) : plans.length === 0 ? (
          <p style={{ color: "var(--muted)", fontSize: 14 }}>
            No plans yet.{" "}
            <button className="btn btn-ghost" onClick={onBack} style={{ fontSize: 13 }}>Create one →</button>
          </p>
        ) : (
          <div className="hist-grid">
            {plans.map(p => (
              <button key={p.id} className="hist-card" onClick={() => onLoad(p.id)}>
                <div className="hist-card-product">{p.workspace.product || "Untitled"}</div>
                <div className="hist-card-badges">
                  {p.workspace.stage  && <span className="hist-badge">{p.workspace.stage}</span>}
                  {p.workspace.region && <span className="hist-badge">{p.workspace.region}</span>}
                </div>
                {p.workspace.description && (
                  <div className="hist-card-desc">{p.workspace.description}</div>
                )}
                <div className="hist-card-footer">
                  <span>{formatDate(p.created_at)}</span>
                  <span className="hist-card-cta">Load →</span>
                </div>
              </button>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

// ───────────────────────────── Main shell
function App() {
  const [view, setView] = useState("workspace"); // "workspace" | "plan" | "history"
  const [loading, setLoading] = useState(!!window.__currentUser);
  const [active, setActive] = useState("fit");
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [workspace, setWorkspace] = useState(WORKSPACE_DEFAULTS);
  const [planData, setPlanData] = useState(null);
  const mainRef = useRef();

  useEffect(() => {
    if (!window.__currentUser) return;
    fetch("/api/plans/latest", { credentials: "include" })
      .then(r => r.ok ? r.json() : null)
      .then(data => {
        if (data?.plan) {
          setWorkspace(data.plan.workspace);
          setPlanData(data.plan.plan_data);
          setView("plan");
        }
        setLoading(false);
      })
      .catch(() => setLoading(false));
  }, []);

  async function loadPlan(id) {
    const res = await fetch(`/api/plans/${id}`, { credentials: "include" });
    const data = await res.json();
    if (data.plan) {
      setWorkspace(data.plan.workspace);
      setPlanData(data.plan.plan_data);
      setView("plan");
    }
  }

  function handleGenerate(ws, results) {
    setWorkspace(ws);
    setPlanData(results);
    setView("plan");
  }

  function jump(id) {
    setActive(id);
    const el = document.getElementById(id);
    if (el && mainRef.current) {
      mainRef.current.scrollTo({ top: el.offsetTop - 20, behavior: "smooth" });
    }
  }

  useEffect(() => {
    const main = mainRef.current;
    if (!main) return;
    const onScroll = () => {
      const top = main.scrollTop + 120;
      let cur = SECTIONS[0].id;
      for (const s of SECTIONS) {
        const el = document.getElementById(s.id);
        if (el && el.offsetTop <= top) cur = s.id;
      }
      setActive(cur);
    };
    main.addEventListener("scroll", onScroll, { passive: true });
    return () => main.removeEventListener("scroll", onScroll);
  }, [view]);

  if (loading) {
    return (
      <div style={{ display: "flex", alignItems: "center", justifyContent: "center", height: "100vh", background: "var(--bg, #FAF8F3)" }}>
        <div className="gen-spinner" />
      </div>
    );
  }

  if (view === "workspace") {
    return <WorkspacePage onGenerate={handleGenerate} onBackToPlan={planData ? () => setView("plan") : null} />;
  }

  if (view === "history") {
    return <HistoryPage onBack={() => setView(planData ? "plan" : "workspace")} onLoad={loadPlan} />;
  }

  const themeClass = t.theme === "warm" ? "" : `theme-${t.theme}`;
  const layoutStyle = {
    "--serif": t.serif,
    gridTemplateColumns: t.showRefine ? "248px 1fr 360px" : "248px 1fr",
  };

  return (
    <div className={`app ${themeClass}`} style={layoutStyle}>
      <Topbar workspace={workspace} planData={planData} onBackToWorkspace={() => setView("workspace")} onHistory={() => setView("history")} />
      <Sidebar active={active} onJump={jump} workspace={workspace} onWorkspace={setWorkspace} />
      <main className="main" ref={mainRef}>
        <div className="doc">
          <BriefCard workspace={workspace} planData={planData} />
          <SectionFit       data={planData?.market_analysis} />
          <SectionAudience  data={planData?.market_analysis} />
          <SectionValue     data={planData?.market_analysis} />
          <SectionMoats     data={planData?.market_analysis} />
          <SectionChannels  data={planData?.market_analysis} campaignData={planData?.campaign_plan} />
          <SectionCAC       data={planData?.market_analysis} />
          <SectionRoadmap   data={planData?.campaign_plan} />
          <SectionMetrics   data={planData?.analytics_framework} />
        </div>
      </main>
      {t.showRefine && <RefinePanel workspace={workspace} />}

      <TweaksPanel>
        <TweakSection label="Palette">
          <TweakRadio
            label="Theme"
            value={t.theme}
            options={[
              { label: "Auto",  value: "warm"  },
              { label: "Grove", value: "grove" },
              { label: "Noir",  value: "noir"  },
              { label: "Ink",   value: "ink"   },
            ]}
            onChange={v => setTweak("theme", v)}
          />
        </TweakSection>
        <TweakSection label="Type">
          <TweakSelect
            label="Display serif"
            value={t.serif}
            options={[
              { label: "Instrument Serif",  value: "\"Instrument Serif\", Georgia, serif" },
              { label: "Newsreader",        value: "\"Newsreader\", Georgia, serif" },
              { label: "Source Serif",      value: "\"Source Serif Pro\", Georgia, serif" },
              { label: "Crimson Pro",       value: "\"Crimson Pro\", Georgia, serif" },
            ]}
            onChange={v => setTweak("serif", v)}
          />
        </TweakSection>
        <TweakSection label="Layout">
          <TweakToggle
            label="Refine panel"
            value={t.showRefine}
            onChange={v => setTweak("showRefine", v)}
          />
        </TweakSection>
      </TweaksPanel>
    </div>
  );
}

// Auth shell (auth.jsx) renders first and calls this when the user is authenticated.
window.__renderApp = (user) => {
  window.__currentUser = user;
  if (window.__authRoot) {
    window.__authRoot.render(<App />);
  } else {
    ReactDOM.createRoot(document.getElementById("root")).render(<App />);
  }
};
