/* Shared components for the Artemis chat prototype.
   Exposes Icon, Avatar, Auth, Sidebar, RightPanel, TaskModal on window. */

const { useState, useEffect, useRef } = React;

/* ---------- Icon set (Lucide-aligned 1.8px outlines) ---------- */
const ICON_PATHS = {
  send: 'M22 2L11 13M22 2l-7 20-4-9-9-4z',
  plus: 'M12 5v14M5 12h14',
  clipboard: 'M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v0a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2v0z',
  brain: 'M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 1.32-4.24 2.5 2.5 0 0 1 1.98-3A2.5 2.5 0 0 1 9.5 2zM14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24 2.5 2.5 0 0 0-1.98-3A2.5 2.5 0 0 0 14.5 2z',
  database: 'M21 5c0 1.66-4.03 3-9 3S3 6.66 3 5s4.03-3 9-3 9 1.34 9 3zM3 5v14c0 1.66 4.03 3 9 3s9-1.34 9-3V5M3 12c0 1.66 4.03 3 9 3s9-1.34 9-3',
  search: 'M21 21l-4.35-4.35M10 17a7 7 0 1 1 0-14 7 7 0 0 1 0 14z',
  shield: 'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z',
  zap: 'M13 2L3 14h9l-1 8 10-12h-9l1-8z',
  terminal: 'M4 17l6-6-6-6M12 19h8',
  x: 'M18 6L6 18M6 6l12 12',
  check: 'M5 12l5 5L20 7',
  cpu: 'M9 2v3M15 2v3M9 19v3M15 19v3M2 9h3M2 15h3M19 9h3M19 15h3M5 4h14a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1zM9 9h6v6H9z',
  layers: 'M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5',
  file: 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6zM14 2v6h6',
  globe: 'M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2zM2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z',
  wrench: 'M14.7 6.3a4 4 0 1 1-5.6 5.6L3 18l3 3 6.1-6.1a4 4 0 0 0 5.6-5.6z',
  trending: 'M23 6L13.5 15.5 8.5 10.5 1 18M17 6h6v6',
  mail: 'M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2zM22 6L12 13 2 6',
  flag: 'M4 22V2M4 14h10l2 4h6V6h-6L14 2H4',
};
const Icon = ({ name, size = 16, color = 'currentColor', style }) => (
  <svg
    width={size} height={size} viewBox="0 0 24 24"
    fill="none" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"
    style={style}
  >
    <path d={ICON_PATHS[name] || ICON_PATHS.zap} />
  </svg>
);

/* ---------- Agent + tool catalogs ---------- */
const AGENTS = [
  {
    id: 'artemis',
    name: 'Artemis',
    color: '#22d3ee',
    role: 'Orchestrator',
    desc: 'Routes tasks across the kernel. Default entry agent.',
    prompt: 'You are Artemis, the orchestrator agent of the Artemis City kernel. You speak with engineering rigor and brevity. You coordinate other agents (Planner, Research, Summarizer) and surface trade-offs explicitly. When a request would benefit from another agent, say so and route. You never invent capabilities. Quote sources from the knowledge base when relevant.'
  },
  {
    id: 'planner',
    name: 'Planner',
    color: '#fbbf24',
    role: 'Strategist',
    desc: 'Decomposes goals into ordered steps with governance hooks.',
    prompt: 'You are Planner, an Artemis agent. You decompose user goals into a short ordered checklist of concrete steps, each with: action, expected output, required tools, governance flag (auto / approval / review). Use markdown checkboxes. Be terse.'
  },
  {
    id: 'research',
    name: 'Research',
    color: '#a855f7',
    role: 'Investigator',
    desc: 'Pulls from memory bus (Obsidian + vector) + cited web.',
    prompt: 'You are Research, an Artemis agent. You synthesize findings from the user\'s knowledge base and external sources. Always cite sources with bracketed indices [obsidian:notename] or [notion:pageid]. If you cannot find evidence, say so plainly.'
  },
  {
    id: 'summarizer',
    name: 'Summarizer',
    color: '#86efac',
    role: 'Condenser',
    desc: 'Compresses long notes / threads to ATP-shaped envelopes.',
    prompt: 'You are Summarizer, an Artemis agent. You produce tight, structured summaries: 1) one-line TL;DR, 2) 3-5 bullet points, 3) recommended next action. Maximum 120 words total.'
  },
];

const TOOLS = [
  { id: 'memory.read',   name: 'Memory read',   desc: 'Read from Obsidian vault + vector store', risk: 'low'    },
  { id: 'memory.write',  name: 'Memory write',  desc: 'Persist notes to user vault',             risk: 'medium' },
  { id: 'web.fetch',     name: 'Web fetch',     desc: 'Retrieve a public URL',                   risk: 'medium' },
  { id: 'web.search',    name: 'Web search',    desc: 'Brave / Tavily search API',               risk: 'medium' },
  { id: 'kb.search',     name: 'KB search',     desc: 'Hybrid search across vaults',             risk: 'low'    },
  { id: 'code.execute',  name: 'Code execute',  desc: 'Run Python in a sandboxed runner',        risk: 'high'   },
  { id: 'shell.run',     name: 'Shell run',     desc: 'POSIX commands in an isolated env',       risk: 'high'   },
  { id: 'notion.api',    name: 'Notion API',    desc: 'Read pages / databases from Notion',      risk: 'low'    },
  { id: 'github.api',    name: 'GitHub API',    desc: 'List issues, read repos, create PRs',     risk: 'medium' },
];

const MEMORY = [
  { src: 'obsidian', title: 'Artemis City - Architecture',     snip: 'Kernel routes tasks deterministically across registry-ranked agents...', tag: 'architecture' },
  { src: 'obsidian', title: 'Hebbian routing benchmarks',      snip: 'Across 12k runs, adaptive routing improved Sharpe-of-quality by 1.4...', tag: 'research'    },
  { src: 'notion',   title: 'ATP Protocol Spec v0.4',          snip: 'Envelope: {agent, intent, payload, governance, trust_decay}...', tag: 'protocol' },
  { src: 'notion',   title: 'Q1 Planning · Artemis OKRs',      snip: 'O1: Ship kernel governance layer · KR1: 99% audit coverage...', tag: 'planning' },
  { src: 'vector',   title: 'Embedding 0x7d3f · trust-decay',  snip: 'Cluster topic: trust-decay model in agent registry · 0.91 cos', tag: 'kernel'      },
  { src: 'obsidian', title: 'Why LLM Wrappers Fail',           snip: 'Wrapper-first systems are useful for prototyping but weak...', tag: 'doctrine' },
  { src: 'notion',   title: 'BRYPTOS · Options Greeks',        snip: 'Δ/Γ/Θ/Vega for BTC options · weekly desk update', tag: 'trading' },
  { src: 'vector',   title: 'Embedding 0xa4f3 · postal',       snip: 'Cluster topic: memory bus postal-service metaphor · 0.88 cos', tag: 'memory' },
];

const SEED_THREADS = [
  { id: 't_kernel', title: 'Routing policy for new agent', agent: 'artemis', when: 'Just now', last: 'kernel decides, not LLM' },
  { id: 't_atp',    title: 'ATP envelope shape · v0.4',    agent: 'planner', when: '2h',       last: 'review governance fields' },
  { id: 't_bench',  title: 'Hebbian benchmark deltas',      agent: 'research',when: 'Yesterday',last: '12k runs analyzed' },
  { id: 't_okrs',   title: 'Q1 OKRs · summarize for board', agent: 'summarizer', when: '3d',   last: 'TL;DR draft ready' },
];

/* ---------- Auth shell (Descope-style) ---------- */
function Auth({ onIn }) {
  const [email, setEmail] = useState('');
  const [stage, setStage] = useState('email'); // email | otp
  const [otp, setOtp] = useState(['', '', '', '', '', '']);
  const refs = useRef([]);

  function submitEmail(e) {
    e?.preventDefault();
    if (!email) return;
    setStage('otp');
  }

  function setOtpDigit(i, v) {
    const next = [...otp];
    next[i] = v.slice(-1);
    setOtp(next);
    if (v && i < 5) refs.current[i + 1]?.focus();
    if (next.every((d) => d)) {
      setTimeout(() => onIn({ email, name: email.split('@')[0] }), 400);
    }
  }

  return (
    <div className="auth-stage">
      <div className="auth-card">
        <div className="mark">A</div>
        <span className="auth-eyebrow">●  Artemis City · Kernel for AI Agents</span>
        <h1>{stage === 'email' ? 'Sign in' : 'Verify it\'s you'}</h1>
        <p>
          {stage === 'email'
            ? 'Authenticated via Descope · passkey + email OTP. No passwords stored.'
            : `We sent a 6-digit code to ${email}. Type it below — autoadvances.`}
        </p>

        {stage === 'email' ? (
          <form onSubmit={submitEmail} style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <input className="auth-input" type="email" placeholder="you@quantumharmony.ai"
                   value={email} onChange={(e) => setEmail(e.target.value)} autoFocus required />
            <button className="auth-btn" type="submit">Continue with email →</button>
            <div className="auth-divider">OR</div>
            <button type="button" className="sso-btn" onClick={() => onIn({ email: 'guest@artemis.city', name: 'guest' })}>
              <Icon name="zap" size={14} color="#fbbf24" /> Continue as guest (preview mode)
            </button>
            <button type="button" className="sso-btn">
              <Icon name="globe" size={14} color="#67e8f9" /> Continue with Google
            </button>
            <button type="button" className="sso-btn">
              <Icon name="terminal" size={14} color="#d8b4fe" /> Continue with passkey
            </button>
          </form>
        ) : (
          <>
            <div style={{ display: 'flex', gap: 8, justifyContent: 'center', margin: '6px 0' }}>
              {otp.map((d, i) => (
                <input
                  key={i}
                  ref={(el) => (refs.current[i] = el)}
                  className="auth-input"
                  style={{ width: 44, height: 52, textAlign: 'center', fontSize: 22, fontFamily: 'JetBrains Mono', padding: 0 }}
                  maxLength={1}
                  value={d}
                  onChange={(e) => setOtpDigit(i, e.target.value)}
                  autoFocus={i === 0}
                />
              ))}
            </div>
            <button type="button" className="sso-btn" onClick={() => setStage('email')}>← Use a different email</button>
          </>
        )}
        <div className="descope-chip" style={{ marginTop: 4 }}>
          <span className="pulse"></span> Powered by Descope · session JWT · 24h
        </div>
      </div>
    </div>
  );
}

/* ---------- Sidebar ---------- */
function Sidebar({ threads, activeId, onPickThread, onNewThread, onOpenTask }) {
  return (
    <aside className="sidebar">
      <button className="task-btn" onClick={onOpenTask}>
        <Icon name="clipboard" size={14} /> Create Task
      </button>
      <button className="new-chat" onClick={onNewThread}>
        <Icon name="plus" size={14} style={{ marginRight: 6, verticalAlign: -2 }} /> New chat
      </button>

      <div>
        <h4>Threads</h4>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
          {threads.map((t) => (
            <div
              key={t.id}
              className={'thread ' + (t.id === activeId ? 'active' : '')}
              onClick={() => onPickThread(t.id)}
            >
              <span className="ttl">{t.title}</span>
              <span className="meta">{t.agent} · {t.when}</span>
            </div>
          ))}
        </div>
      </div>

      <div>
        <h4>Pinned vaults</h4>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 4, padding: '0 6px' }}>
          <a className="thread" style={{ cursor: 'default' }}><span className="ttl" style={{ display: 'flex', gap: 6, alignItems: 'center' }}><Icon name="file" size={12} color="#a855f7" /> Obsidian · /kb</span><span className="meta">412 notes · synced</span></a>
          <a className="thread" style={{ cursor: 'default' }}><span className="ttl" style={{ display: 'flex', gap: 6, alignItems: 'center' }}><Icon name="layers" size={12} color="#67e8f9" /> Notion · Workspace</span><span className="meta">8 dbs · 1.2k pages</span></a>
        </div>
      </div>
    </aside>
  );
}

/* ---------- Right panel ---------- */
function RightPanel({ tab, setTab, agentsState, tools, setTools }) {
  return (
    <aside className="right">
      <div className="right-tabs">
        <button className={tab === 'agents' ? 'on' : ''} onClick={() => setTab('agents')}>Agents</button>
        <button className={tab === 'memory' ? 'on' : ''} onClick={() => setTab('memory')}>Memory</button>
        <button className={tab === 'tools' ? 'on' : ''} onClick={() => setTab('tools')}>Tools</button>
      </div>
      <div className="right-body">
        {tab === 'agents' && <AgentsPanel agentsState={agentsState} />}
        {tab === 'memory' && <MemoryPanel />}
        {tab === 'tools' && <ToolsPanel tools={tools} setTools={setTools} />}
      </div>
    </aside>
  );
}

function AgentsPanel({ agentsState }) {
  return (
    <div>
      {AGENTS.map((a) => {
        const s = agentsState[a.id] || { status: 'idle', task: 'awaiting work' };
        return (
          <div key={a.id} className={'agent-card ' + (s.status === 'running' ? 'active' : (s.status === 'idle' ? 'idle' : ''))}>
            <div className="row">
              <span className="name">
                <span className="agent-dot" style={{ background: a.color, color: a.color }}></span>
                {a.name} <span style={{ color: 'var(--fg-3)', fontWeight: 400, fontSize: 12 }}>· {a.role}</span>
              </span>
              <span className={'pill ' + s.status}>{s.status}</span>
            </div>
            <div className="task">{s.task}</div>
            {s.status === 'running' && <div className="bar"><div className="fill progress"></div></div>}
          </div>
        );
      })}
      <div style={{ marginTop: 14, padding: 10, border: '1px dashed rgba(255,255,255,0.10)', borderRadius: 10, fontSize: 11, color: 'var(--fg-3)', fontFamily: 'var(--font-mono)', letterSpacing: '0.08em' }}>
        ● 4 registered · kernel session #a4f3-elect-12
      </div>
    </div>
  );
}

function MemoryPanel() {
  const [q, setQ] = useState('');
  const [src, setSrc] = useState('all');
  const filtered = MEMORY.filter((m) => (src === 'all' || m.src === src) && (q === '' || (m.title + m.snip + m.tag).toLowerCase().includes(q.toLowerCase())));
  return (
    <div>
      <input className="mem-search" placeholder="Search memory…" value={q} onChange={(e) => setQ(e.target.value)} />
      <div className="mem-tabs">
        {['all', 'obsidian', 'notion', 'vector'].map((s) => (
          <button key={s} className={src === s ? 'on' : ''} onClick={() => setSrc(s)}>{s}</button>
        ))}
      </div>
      {filtered.length === 0 && <div style={{ color: 'var(--fg-3)', fontSize: 12, textAlign: 'center', padding: 20 }}>No matches.</div>}
      {filtered.map((m, i) => (
        <div key={i} className="mem-item">
          <span className={'src ' + m.src}><Icon name={m.src === 'obsidian' ? 'file' : m.src === 'notion' ? 'layers' : 'database'} size={10} /> {m.src} · #{m.tag}</span>
          <span className="ttl">{m.title}</span>
          <span className="snip">{m.snip}</span>
        </div>
      ))}
    </div>
  );
}

function ToolsPanel({ tools, setTools }) {
  return (
    <div>
      {TOOLS.map((t) => {
        const on = tools[t.id];
        return (
          <div key={t.id} className="tool-row">
            <div>
              <div className="name">{t.name}</div>
              <div className="desc">{t.desc}</div>
              <div className="meta" style={{ marginTop: 2 }}>risk: <span style={{ color: t.risk === 'high' ? '#fca5a5' : t.risk === 'medium' ? '#fcd34d' : '#86efac' }}>{t.risk}</span></div>
            </div>
            <div className={'toggle ' + (on ? 'on' : '')} onClick={() => setTools({ ...tools, [t.id]: !on })}></div>
          </div>
        );
      })}
    </div>
  );
}

/* ---------- Task creation modal ---------- */
function TaskModal({ onClose, onCreate, defaultTools }) {
  const [step, setStep] = useState(1);
  const [goal, setGoal] = useState('');
  const [desc, setDesc] = useState('');
  const [agent, setAgent] = useState('artemis');
  const [maxIter, setMaxIter] = useState(8);
  const [trust, setTrust] = useState(0.75);
  const [policy, setPolicy] = useState('approval');
  const [tools, setTools] = useState(defaultTools || { 'memory.read': true, 'kb.search': true });

  function next() { setStep(Math.min(3, step + 1)); }
  function prev() { setStep(Math.max(1, step - 1)); }
  function submit() {
    onCreate({ goal, desc, agent, policy, maxIter, trust, tools });
  }
  const enabledTools = Object.entries(tools).filter(([, v]) => v).map(([k]) => k);

  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <div className="head">
          <div>
            <h2>Create Task</h2>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--fg-3)', letterSpacing: '0.10em', textTransform: 'uppercase' }}>Step {step} of 3 · goal → policy → review</span>
          </div>
          <div className="x" onClick={onClose}><Icon name="x" size={14} /></div>
        </div>
        <div className="steps">
          <div className={'step ' + (step >= 1 ? 'done' : '')}></div>
          <div className={'step ' + (step >= 2 ? 'done' : '')}></div>
          <div className={'step ' + (step >= 3 ? 'done' : '')}></div>
        </div>

        {step === 1 && (
          <>
            <div>
              <label>Goal</label>
              <input value={goal} onChange={(e) => setGoal(e.target.value)} placeholder="e.g. Summarize last week's BRYPTOS desk notes into an ATP envelope" autoFocus />
            </div>
            <div>
              <label>Context (optional)</label>
              <textarea value={desc} onChange={(e) => setDesc(e.target.value)} placeholder="Anything else the kernel should know — references, constraints, deadlines…" />
            </div>
            <div>
              <label>Lead agent</label>
              <select value={agent} onChange={(e) => setAgent(e.target.value)}>
                {AGENTS.map((a) => <option key={a.id} value={a.id}>{a.name} — {a.role}</option>)}
              </select>
            </div>
          </>
        )}

        {step === 2 && (
          <>
            <div>
              <label>Governance policy</label>
              <div className="tool-pill-grid" style={{ marginBottom: 6 }}>
                {['auto', 'approval', 'review'].map((p) => (
                  <span key={p} className={'tp ' + (policy === p ? 'on' : '')} onClick={() => setPolicy(p)}>
                    <Icon name={p === 'auto' ? 'zap' : p === 'approval' ? 'shield' : 'flag'} size={12} /> {p}
                  </span>
                ))}
              </div>
              <span style={{ fontSize: 12, color: 'var(--fg-3)' }}>
                {policy === 'auto' && 'Kernel auto-executes within tool whitelist. Highest velocity.'}
                {policy === 'approval' && 'Each tool call requires user approval. Default.'}
                {policy === 'review' && 'Plan must be reviewed before execution. Safest.'}
              </span>
            </div>
            <div className="policy-grid">
              <div>
                <label>Max iterations</label>
                <input type="number" value={maxIter} onChange={(e) => setMaxIter(+e.target.value)} min={1} max={32} />
              </div>
              <div>
                <label>Trust threshold ({trust.toFixed(2)})</label>
                <input type="range" min="0.50" max="0.99" step="0.01" value={trust} onChange={(e) => setTrust(+e.target.value)} style={{ padding: 0, height: 36 }} />
              </div>
            </div>
            <div>
              <label>Tools allowed</label>
              <div className="tool-pill-grid">
                {TOOLS.map((t) => (
                  <span key={t.id} className={'tp ' + (tools[t.id] ? 'on' : '')} onClick={() => setTools({ ...tools, [t.id]: !tools[t.id] })}>
                    <Icon name="wrench" size={11} /> {t.name}
                  </span>
                ))}
              </div>
            </div>
          </>
        )}

        {step === 3 && (
          <div className="review-card">
            <div className="review-row"><span className="k">Goal</span><span className="v"><b>{goal || '—'}</b></span></div>
            {desc && <div className="review-row"><span className="k">Context</span><span className="v">{desc}</span></div>}
            <div className="review-row"><span className="k">Lead agent</span><span className="v">{AGENTS.find((a) => a.id === agent)?.name}</span></div>
            <div className="review-row"><span className="k">Policy</span><span className="v"><code>{policy}</code></span></div>
            <div className="review-row"><span className="k">Max iter</span><span className="v"><code>{maxIter}</code></span></div>
            <div className="review-row"><span className="k">Trust ≥</span><span className="v"><code>{trust.toFixed(2)}</code></span></div>
            <div className="review-row"><span className="k">Tools</span><span className="v" style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>
              {enabledTools.length === 0 && <span style={{ color: 'var(--fg-3)' }}>none</span>}
              {enabledTools.map((t) => <code key={t}>{t}</code>)}
            </span></div>
          </div>
        )}

        <div className="modal-foot">
          <button className="ghost" onClick={step === 1 ? onClose : prev}>{step === 1 ? 'Cancel' : '← Back'}</button>
          {step < 3
            ? <button className="primary" onClick={next} disabled={step === 1 && !goal}>Continue →</button>
            : <button className="primary" onClick={submit}>✓ Dispatch to kernel</button>}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Icon, AGENTS, TOOLS, MEMORY, SEED_THREADS, Auth, Sidebar, RightPanel, TaskModal });
