import React, { useEffect, useState } from 'react';
import { createRoot } from 'react-dom/client';
import {
  Activity,
  ArrowRight,
  BookOpen,
  Brain,
  Briefcase,
  Check,
  CheckCircle2,
  ChevronRight,
  CircleDollarSign,
  ClipboardList,
  Code2,
  Copy,
  Moon,
  Play,
  RefreshCw,
  ShieldAlert,
  Sun,
  Zap,
} from 'lucide-react';

const HASH_ALIASES = {
  command: 'home',
  queues: 'work',
  desk: 'lab',
  playbook: 'method',
  finance: 'economics',
  review: 'diagnostic',
  engineering: 'delivery',
};

const NAV = [
  { id: 'home', label: 'The firm', hint: 'We implement Jev for companies', icon: Briefcase },
  { id: 'work', label: 'Client work', hint: 'Systems we installed', icon: Activity },
  { id: 'lab', label: 'Scoping lab', hint: 'Prove a client question', icon: Brain },
  { id: 'method', label: 'Method', hint: 'How we implement', icon: BookOpen },
  { id: 'economics', label: 'Economics', hint: 'What clients stop paying', icon: CircleDollarSign },
  { id: 'diagnostic', label: 'Diagnostic', hint: 'Find the leak first', icon: ShieldAlert },
  { id: 'delivery', label: 'Delivery', hint: 'What we ship into the repo', icon: Code2 },
];

const SERVICES = [
  { id: 'support', name: 'Support routing', type: 'Choice', install: 'We put Jev between tickets and teams', volume: 'Helio · Harbor' },
  { id: 'refunds', name: 'Refund review', type: 'Noul + Score', install: 'Policy gates before money moves', volume: 'Northline · Atlas' },
  { id: 'gates', name: 'Auto-mode gates', type: 'Noul', install: 'Tool calls blocked before bash runs', volume: 'Every cutover' },
  { id: 'router', name: 'Model router', type: 'Choice', install: 'Cheapest competent writer, not default frontier', volume: 'Platform layer' },
];

const CLIENTS = [
  { name: 'Northline Commerce', work: 'Refund + support cutover', status: 'Live' },
  { name: 'Harbor Health', work: 'SSO / incident routing', status: 'Live' },
  { name: 'Atlas Freight', work: 'Policy refunds', status: 'Live' },
  { name: 'Helio Labs', work: 'Payout desk', status: 'Live' },
];

const FEED_SEED = [
  { id: 'd-18421', ago: '12s', client: 'Helio Labs', pipeline: 'Support', question: 'Which team owns this ticket?', answer: 'billing', confidence: 0.91, latency: 7, action: 'auto_dispatch' },
  { id: 'd-18420', ago: '41s', client: 'Harbor Health', pipeline: 'Gates', question: 'Is this bash call safe?', answer: 'BLOCKED', confidence: 0.97, latency: 6, action: 'block' },
  { id: 'd-18419', ago: '1m', client: 'Northline', pipeline: 'Refunds', question: 'Does this refund meet policy?', answer: 'APPROVED', confidence: 0.88, latency: 8, action: 'auto_dispatch' },
  { id: 'd-18418', ago: '2m', client: 'Atlas Freight', pipeline: 'Router', question: 'Cheapest competent model?', answer: 'haiku-fast', confidence: 0.98, latency: 5, action: 'auto_dispatch' },
  { id: 'd-18417', ago: '3m', client: 'Harbor Health', pipeline: 'Support', question: 'Which team owns this ticket?', answer: 'technical', confidence: 0.79, latency: 9, action: 'human_review' },
  { id: 'd-18416', ago: '4m', client: 'Northline', pipeline: 'Compaction', question: 'Keep this history turn?', answer: 'drop · 0.11', confidence: 0.94, latency: 11, action: 'auto_dispatch' },
];

const FEED_INCOMING = [
  { client: 'Helio Labs', pipeline: 'Support', question: 'Which team owns this ticket?', answer: 'sales', confidence: 0.86, action: 'auto_dispatch' },
  { client: 'Northline', pipeline: 'Refunds', question: 'How policy-aligned is this request?', answer: '0.93 · in window', confidence: 0.93, action: 'auto_dispatch' },
  { client: 'Harbor Health', pipeline: 'Gates', question: 'Approve SQL write?', answer: 'APPROVED', confidence: 0.96, action: 'auto_dispatch' },
  { client: 'Atlas Freight', pipeline: 'Support', question: 'Which team owns this ticket?', answer: 'risk', confidence: 0.72, action: 'human_review' },
  { client: 'Northline', pipeline: 'Router', question: 'Cheapest competent model?', answer: 'sonnet-frontier', confidence: 0.9, action: 'auto_dispatch' },
];

const CASES = [
  {
    id: 'HEL-1842',
    pipeline: 'support',
    client: 'Helio Labs',
    title: 'Payouts have failed for three days',
    installed: 'Support router we shipped',
    question_type: 'choice',
    prompt: 'Which team should handle this support request?',
    options: ['billing', 'technical', 'sales', 'risk'],
    state: {
      client: 'Helio Labs',
      plan: 'Growth',
      message: 'Help. Our payouts have been failing for 3 days and finance cannot close the week.',
      signals: ['payout_failed', 'invoice_overdue'],
      last_payment: '2026-09-17',
    },
  },
  {
    id: 'HAR-1847',
    pipeline: 'support',
    client: 'Harbor Health',
    title: 'Cannot sign in after SSO cutover',
    installed: 'Incident router we shipped',
    question_type: 'choice',
    prompt: 'Which team should handle this support request?',
    options: ['billing', 'technical', 'sales', 'risk'],
    state: {
      client: 'Harbor Health',
      plan: 'Enterprise',
      message: 'Login fails with a 500 after yesterday’s SSO cutover. Whole clinic is blocked.',
      signals: ['login_500', 'sso', 'outage_suspect'],
    },
  },
  {
    id: 'NOR-2201',
    pipeline: 'refunds',
    client: 'Northline Commerce',
    title: 'Refund request · order 88421',
    installed: 'Refund policy gate we shipped',
    question_type: 'noul',
    prompt: 'Does this refund meet the client refund policy?',
    options: [],
    state: {
      order_id: '88421',
      item: 'Annual seat expansion',
      requested_amount_usd: 2400,
      reason: 'Duplicate charge after seat sync',
      days_since_purchase: 11,
      policy_window_days: 30,
      item_condition: 'unused',
    },
  },
  {
    id: 'ATL-2218',
    pipeline: 'refunds',
    client: 'Atlas Freight',
    title: 'Refund outside policy window',
    installed: 'Refund policy gate we shipped',
    question_type: 'noul',
    prompt: 'Does this refund meet the client refund policy?',
    options: [],
    state: {
      order_id: '89002',
      item: 'Onsite onboarding',
      requested_amount_usd: 6800,
      reason: 'Changed rollout date',
      days_since_purchase: 54,
      policy_window_days: 30,
      item_condition: 'used item',
      note: 'outside window',
    },
  },
  {
    id: 'HAR-091',
    pipeline: 'gates',
    client: 'Harbor Health',
    title: 'Agent requested rm -rf on cache',
    installed: 'Auto-mode gate we shipped',
    question_type: 'noul',
    prompt: 'Is this tool execution safe to proceed?',
    options: [],
    state: {
      requested_action: 'Execute Bash Command',
      command: 'rm -rf /tmp/cache_folder',
      user_role: 'agent_worker',
      environment: 'sandbox_isolated',
    },
  },
  {
    id: 'NOR-440',
    pipeline: 'router',
    client: 'Northline Commerce',
    title: 'FAQ lookup vs contract rewrite',
    installed: 'Model router we shipped',
    question_type: 'choice',
    prompt: 'Which model is the cheapest competent choice?',
    options: ['haiku-fast', 'sonnet-frontier', 'gpt-4o'],
    state: {
      task: 'Answer a billing FAQ from the help center',
      complexity: 'simple lookup',
      needs_tools: false,
      latency_budget_ms: 800,
    },
  },
];

const SESSION_TURNS = [
  { id: 1, role: 'user', content: 'Goal: compare three agent tools for the Monday briefing.' },
  { id: 2, role: 'assistant', content: 'Understood, I will start gathering sources.' },
  { id: 3, role: 'tool', content: 'Key finding: TypeSafe Jev is $0.042/M with no output fee.' },
  { id: 4, role: 'user', content: 'Thanks!' },
  { id: 5, role: 'system', content: 'Constraint: save drafts. Do not publish.' },
  { id: 6, role: 'assistant', content: 'Hello, pulling more tabs.' },
  { id: 7, role: 'tool', content: 'Result: latency measured at 8ms on the routing path.' },
];

function resolvePage(raw) {
  const mapped = HASH_ALIASES[raw] || raw;
  return NAV.some((item) => item.id === mapped) ? mapped : 'home';
}

function formatUsd(value, digits = 2) {
  return value.toLocaleString(undefined, { minimumFractionDigits: digits, maximumFractionDigits: digits });
}

function actionBadge(action) {
  if (action === 'block') return 'badge bad';
  if (action === 'human_review') return 'badge warn';
  return 'badge good';
}

function actionLabel(action) {
  if (action === 'block') return 'Blocked';
  if (action === 'human_review') return 'Client review';
  return 'Auto-dispatch';
}

function App() {
  const hashPage = () => resolvePage(window.location.hash.replace('#/', '').replace('#', ''));
  const [page, setPage] = useState(hashPage);
  const [darkMode, setDarkMode] = useState(false);
  const [copiedCode, setCopiedCode] = useState(null);
  const [clock, setClock] = useState(() => new Date());

  useEffect(() => {
    document.documentElement.classList.toggle('dark', darkMode);
  }, [darkMode]);

  useEffect(() => {
    if (!window.location.hash) window.location.hash = '/home';
  }, []);

  useEffect(() => {
    const onHash = () => setPage(hashPage());
    window.addEventListener('hashchange', onHash);
    const timer = setInterval(() => setClock(new Date()), 15000);
    return () => {
      window.removeEventListener('hashchange', onHash);
      clearInterval(timer);
    };
  }, []);

  const go = (id) => {
    setPage(id);
    window.location.hash = `/${id}`;
  };

  const handleCopy = async (text, id) => {
    await navigator.clipboard.writeText(text);
    setCopiedCode(id);
    setTimeout(() => setCopiedCode(null), 1800);
  };

  const current = NAV.find((item) => item.id === page) || NAV[0];

  return (
    <div className="app-shell">
      <aside className="sidebar">
        <div className="brand-lockup">
          <div className="brand-mark">J</div>
          <div>
            <div className="text-[15px] font-semibold">Jevineering</div>
            <div className="text-[11px] text-[#9a9286]">We implement Jev for companies</div>
          </div>
        </div>

        <div className="workspace-chip">
          <div className="flex items-center justify-between text-[11px] font-mono uppercase tracking-wider text-[#9a9286]">
            <span>Studio</span>
            <span className="badge live">live</span>
          </div>
          <div className="mt-1 text-sm font-semibold">Implementation partner</div>
          <div className="mt-1 text-[11px] text-[#9a9286]">TypeSafe Jev · 4 active clients</div>
        </div>

        <nav className="flex-1 space-y-1 overflow-y-auto px-1">
          {NAV.map((item) => {
            const Icon = item.icon;
            const active = page === item.id;
            return (
              <button key={item.id} className={`nav-btn ${active ? 'active' : ''}`} onClick={() => go(item.id)}>
                <Icon className="h-4 w-4 shrink-0" />
                <span>
                  <span className="block text-[13px] font-medium">{item.label}</span>
                  <span className="hint">{item.hint}</span>
                </span>
              </button>
            );
          })}
        </nav>

        <div className="mt-4 px-2 text-[11px] leading-relaxed text-[#9a9286]">
          We install the split: LLM writes. Jev decides. Code executes.
        </div>
      </aside>

      <div className="canvas">
        <header className="topbar">
          <div>
            <div className="text-[11px] font-mono uppercase tracking-[0.14em] text-[var(--ink-3)]">Jevineering · {current.label}</div>
            <div className="text-lg font-semibold">{current.hint}</div>
          </div>
          <div className="flex items-center gap-2">
            <span className="badge live hidden sm:inline-flex">Clients live</span>
            <span className="badge hidden md:inline-flex tabular">{clock.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</span>
            <button className="btn" onClick={() => setDarkMode((v) => !v)} aria-label="Toggle theme">
              {darkMode ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}
            </button>
            {page !== 'diagnostic' && (
              <button className="btn btn-primary" onClick={() => go('diagnostic')}>
                <span className="hidden sm:inline">Start a diagnostic</span>
                <span className="sm:hidden">Diagnostic</span>
                <ArrowRight className="h-4 w-4" />
              </button>
            )}
          </div>
        </header>

        <div className="mobile-nav">
          {NAV.map((item) => (
            <button
              key={item.id}
              onClick={() => go(item.id)}
              className={`whitespace-nowrap rounded-full px-3 py-1.5 text-xs ${page === item.id ? 'bg-[#ff4801] text-white' : 'bg-[var(--bg-soft)] border border-[var(--line)]'}`}
            >
              {item.label}
            </button>
          ))}
        </div>

        <main className="page">
          {page === 'home' && <HomePage onOpenWork={() => go('work')} onOpenLab={() => go('lab')} />}
          {page === 'work' && <WorkPage />}
          {page === 'lab' && <LabPage />}
          {page === 'method' && <MethodPage onOpenLab={() => go('lab')} />}
          {page === 'economics' && <EconomicsPage />}
          {page === 'diagnostic' && <DiagnosticPage />}
          {page === 'delivery' && <DeliveryPage onCopy={handleCopy} copiedCode={copiedCode} />}
        </main>
      </div>
    </div>
  );
}

function HomePage({ onOpenWork, onOpenLab }) {
  const [feed, setFeed] = useState(FEED_SEED);
  const [tick, setTick] = useState(0);

  useEffect(() => {
    const timer = setInterval(() => {
      setTick((n) => n + 1);
      setFeed((prev) => {
        const incoming = FEED_INCOMING[Math.floor(Math.random() * FEED_INCOMING.length)];
        const next = {
          ...incoming,
          id: `d-${18422 + prev.length + Math.floor(Math.random() * 80)}`,
          ago: 'now',
          latency: 5 + Math.floor(Math.random() * 6),
        };
        return [next, ...prev.slice(0, 8)].map((row, idx) => ({
          ...row,
          ago: idx === 0 ? 'now' : idx === 1 ? '12s' : `${idx + 1}m`,
        }));
      });
    }, 4200);
    return () => clearInterval(timer);
  }, []);

  return (
    <div className="space-y-6">
      <section className="panel overflow-hidden">
        <div className="grid gap-0 lg:grid-cols-[1.4fr_1fr]">
          <div className="p-6 sm:p-8">
            <div className="badge accent">Implementation partner for TypeSafe Jev</div>
            <h1 className="mt-4 max-w-xl text-3xl font-semibold sm:text-4xl">
              We implement Jev for companies.
            </h1>
            <p className="mt-3 max-w-xl text-[15px] leading-relaxed text-[var(--ink-2)]">
              Your writing model stays. We install the decision layer — routing, scoring, gates, and compaction — so agents stop paying frontier prices for yes-or-no work.
            </p>
            <div className="mt-6 flex flex-wrap gap-3">
              <button className="btn btn-primary" onClick={onOpenWork}>
                See client systems we shipped
              </button>
              <button className="btn" onClick={onOpenLab}>
                <Play className="h-4 w-4" /> Scope a question
              </button>
            </div>
          </div>
          <div className="border-t border-[var(--line)] bg-[var(--bg-soft)] p-6 lg:border-l lg:border-t-0">
            <div className="text-[11px] font-mono uppercase tracking-wider text-[var(--ink-3)]">Across client cutovers</div>
            <div className="mt-4 grid grid-cols-2 gap-3">
              <div className="metric panel">
                <div className="label">Active clients</div>
                <div className="value">4</div>
              </div>
              <div className="metric panel">
                <div className="label">Decisions / day</div>
                <div className="value tabular">{(18420 + tick * 3).toLocaleString()}</div>
              </div>
              <div className="metric panel">
                <div className="label">Auto-cleared</div>
                <div className="value">{91 + (tick % 3)}%</div>
              </div>
              <div className="metric panel">
                <div className="label">Client spend avoided</div>
                <div className="value text-[#ff4801]">${formatUsd(18420 * 0.018 + tick * 0.05, 0)}</div>
              </div>
            </div>
          </div>
        </div>
      </section>

      <section className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
        {CLIENTS.map((client) => (
          <article key={client.name} className="panel p-4">
            <div className="badge good">{client.status}</div>
            <h3 className="mt-3 text-base font-semibold">{client.name}</h3>
            <p className="mt-1 text-xs text-[var(--ink-3)]">{client.work}</p>
          </article>
        ))}
      </section>

      <section className="grid gap-4 lg:grid-cols-4">
        {SERVICES.map((service) => (
          <article key={service.id} className="panel p-4">
            <span className="badge accent">{service.type}</span>
            <h3 className="mt-3 text-base font-semibold">{service.name}</h3>
            <p className="mt-1 text-xs text-[var(--ink-2)]">{service.install}</p>
            <p className="mt-3 font-mono text-[11px] text-[var(--ink-3)]">{service.volume}</p>
          </article>
        ))}
      </section>

      <section className="grid gap-4 lg:grid-cols-[1.4fr_.8fr]">
        <div className="panel">
          <div className="flex items-center justify-between px-4 py-3">
            <div>
              <div className="text-sm font-semibold">Decisions from systems we operate for clients</div>
              <div className="text-xs text-[var(--ink-3)]">Typed Jev answers after a Jevineering cutover — not chat completions.</div>
            </div>
            <span className="badge live">live</span>
          </div>
          <div className="feed-row text-[11px] font-mono uppercase tracking-wider text-[var(--ink-3)]">
            <span className="hide-sm">When</span>
            <span>Decision</span>
            <span className="hide-sm">Confidence</span>
            <span>Policy</span>
          </div>
          {feed.map((row) => (
            <div key={row.id} className="feed-row text-sm">
              <div className="hide-sm font-mono text-xs text-[var(--ink-3)]">{row.ago}</div>
              <div>
                <div className="font-medium">{row.question}</div>
                <div className="mt-0.5 text-xs text-[var(--ink-3)]">
                  {row.client} · {row.pipeline} · {row.answer} · {row.latency}ms
                </div>
              </div>
              <div className="hide-sm">
                <div className="tabular text-xs font-medium">{Math.round(row.confidence * 100)}%</div>
                <div className="conf mt-1"><span style={{ width: `${row.confidence * 100}%` }} /></div>
              </div>
              <div><span className={actionBadge(row.action)}>{actionLabel(row.action)}</span></div>
            </div>
          ))}
        </div>

        <div className="space-y-4">
          <div className="panel p-5">
            <div className="text-sm font-semibold">How we engage</div>
            <ol className="mt-3 space-y-2 text-sm text-[var(--ink-2)]">
              <li>1. Diagnostic — find generation leak</li>
              <li>2. State design — evidence, not vibes</li>
              <li>3. Install dispatcher, gates, router</li>
              <li>4. Hand over policy, harness, and runbook</li>
            </ol>
          </div>
          <div className="panel p-5">
            <div className="text-sm font-semibold">The split we install</div>
            <div className="mt-3 space-y-2 text-sm">
              <div className="rounded-xl bg-[var(--bg-soft)] px-3 py-2">1. Client LLM creates the work</div>
              <div className="rounded-xl border border-[#ff4801]/30 bg-[var(--accent-soft)] px-3 py-2 font-medium text-[#ff4801]">2. Jev decides what happens next</div>
              <div className="rounded-xl bg-[var(--bg-soft)] px-3 py-2">3. Client code executes the decision</div>
            </div>
          </div>
        </div>
      </section>
    </div>
  );
}

function WorkPage() {
  const [activeId, setActiveId] = useState(CASES[0].id);
  const [filter, setFilter] = useState('all');
  const [loading, setLoading] = useState(false);
  const [result, setResult] = useState(null);
  const [error, setError] = useState('');

  const visible = CASES.filter((item) => filter === 'all' || item.pipeline === filter);
  const active = visible.find((item) => item.id === activeId) || visible[0] || CASES[0];

  useEffect(() => {
    setResult(null);
    setError('');
  }, [activeId]);

  const runCase = async () => {
    setLoading(true);
    setError('');
    try {
      const res = await fetch('./api/simulate-decision', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          state: active.state,
          question_type: active.question_type,
          prompt: active.prompt,
          options: active.options,
        }),
      });
      if (!res.ok) throw new Error('Scoping lab is unreachable');
      setResult(await res.json());
    } catch (err) {
      setError(err.message || 'Could not reach Jev');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="space-y-5">
      <div className="flex flex-wrap items-end justify-between gap-3">
        <div>
          <h2 className="text-2xl font-semibold">Client systems we installed</h2>
          <p className="mt-1 text-sm text-[var(--ink-2)]">Replay a path from a live cutover. This is the work Jevineering ships — not a demo agent of our own.</p>
        </div>
        <div className="flex flex-wrap gap-2">
          {[
            ['all', 'All installs'],
            ['support', 'Routing'],
            ['refunds', 'Refunds'],
            ['gates', 'Gates'],
            ['router', 'Router'],
          ].map(([id, label]) => (
            <button
              key={id}
              onClick={() => {
                setFilter(id);
                const next = CASES.find((item) => id === 'all' || item.pipeline === id);
                if (next) setActiveId(next.id);
              }}
              className={`btn ${filter === id ? 'btn-primary' : ''}`}
            >
              {label}
            </button>
          ))}
        </div>
      </div>

      <div className="grid gap-4 lg:grid-cols-[.9fr_1.1fr]">
        <div className="panel overflow-hidden">
          {visible.map((item) => (
            <button
              key={item.id}
              onClick={() => setActiveId(item.id)}
              className={`case-row ${active.id === item.id ? 'active' : ''}`}
            >
              <span className="font-mono text-[11px] text-[var(--ink-3)]">{item.id}</span>
              <span className="min-w-0">
                <span className="block truncate text-sm font-medium">{item.title}</span>
                <span className="block truncate text-xs text-[var(--ink-3)]">{item.client} · {item.installed}</span>
              </span>
              <ChevronRight className="h-4 w-4 text-[var(--ink-3)]" />
            </button>
          ))}
        </div>

        <div className="panel space-y-4 p-5">
          <div className="flex items-start justify-between gap-3">
            <div>
              <div className="font-mono text-[11px] text-[var(--ink-3)]">{active.client} · {active.id}</div>
              <h3 className="text-xl font-semibold">{active.title}</h3>
              <p className="mt-1 text-sm text-[var(--ink-2)]">{active.prompt}</p>
            </div>
            <span className="badge accent">{active.question_type}</span>
          </div>

          <div className="codebox text-xs">
            <pre>{JSON.stringify(active.state, null, 2)}</pre>
          </div>

          {active.options.length > 0 && (
            <div className="flex flex-wrap gap-2">
              {active.options.map((option) => (
                <span key={option} className="badge">{option}</span>
              ))}
            </div>
          )}

          <button className="btn btn-primary w-full" onClick={runCase} disabled={loading}>
            {loading ? <RefreshCw className="h-4 w-4 animate-spin" /> : <Zap className="h-4 w-4" />}
            {loading ? 'Jev is deciding…' : 'Run the path we shipped'}
          </button>

          {error && <div className="rounded-xl bg-[var(--bad-soft)] px-3 py-2 text-sm text-[var(--bad)]">{error}</div>}
          {result && <DecisionCard result={result} />}
        </div>
      </div>
    </div>
  );
}

function DecisionCard({ result }) {
  const decision = result.jev_response || {};
  const policy = decision.policy || {};
  const headline = decision.selected_option || decision.action || decision.top_pick?.name || 'Decision';

  return (
    <div className="rounded-2xl border border-[var(--line)] bg-[var(--bg-soft)] p-4">
      <div className="flex items-center justify-between gap-3">
        <div>
          <div className="text-[11px] font-mono uppercase tracking-wider text-[var(--ink-3)]">Jev typed response</div>
          <div className="mt-1 text-xl font-semibold">{headline}</div>
        </div>
        <span className={actionBadge(policy.action)}>{actionLabel(policy.action)}</span>
      </div>
      <div className="mt-3 grid grid-cols-3 gap-2 text-xs">
        <div className="rounded-xl bg-[var(--bg-elev)] p-2">
          <div className="text-[var(--ink-3)]">Confidence</div>
          <div className="tabular font-semibold">{decision.confidence ? `${Math.round(decision.confidence * 100)}%` : '—'}</div>
        </div>
        <div className="rounded-xl bg-[var(--bg-elev)] p-2">
          <div className="text-[var(--ink-3)]">Latency</div>
          <div className="tabular font-semibold">{result.telemetry?.latency_ms}ms</div>
        </div>
        <div className="rounded-xl bg-[var(--bg-elev)] p-2">
          <div className="text-[var(--ink-3)]">Cost</div>
          <div className="tabular font-semibold">${result.telemetry?.jev_cost_usd}</div>
        </div>
      </div>
      <div className="mt-3 text-xs text-[var(--ink-2)]">
        Owner: {policy.owner || 'Client dispatcher'} · {result.telemetry?.savings_multiplier}× cheaper than a frontier loop
      </div>
      <div className="codebox mt-3 text-[11px]">
        <pre>{JSON.stringify(decision, null, 2)}</pre>
      </div>
    </div>
  );
}

function LabPage() {
  const [preset, setPreset] = useState('support');
  const [questionType, setQuestionType] = useState('choice');
  const [promptText, setPromptText] = useState(CASES[0].prompt);
  const [stateJson, setStateJson] = useState(JSON.stringify(CASES[0].state, null, 2));
  const [optionsList, setOptionsList] = useState(CASES[0].options);
  const [itemsList] = useState([
    { id: 'src_1', name: 'TypeSafe pricing note', content: 'Official latency and $0.042/M benchmark' },
    { id: 'src_2', name: 'Forum speculation', content: 'Unverified speculation' },
    { id: 'src_3', name: 'Invoice dispute thread', content: 'Critical payout error from Helio Labs' },
  ]);
  const [loading, setLoading] = useState(false);
  const [result, setResult] = useState(null);
  const [compact, setCompact] = useState(null);
  const [error, setError] = useState('');

  const applyPreset = (key) => {
    setPreset(key);
    setResult(null);
    setError('');
    if (key === 'support') {
      setQuestionType('choice');
      setPromptText(CASES[0].prompt);
      setStateJson(JSON.stringify(CASES[0].state, null, 2));
      setOptionsList(CASES[0].options);
    } else if (key === 'refund') {
      setQuestionType('noul');
      setPromptText(CASES[2].prompt);
      setStateJson(JSON.stringify(CASES[2].state, null, 2));
    } else if (key === 'gate') {
      setQuestionType('noul');
      setPromptText(CASES[4].prompt);
      setStateJson(JSON.stringify(CASES[4].state, null, 2));
    } else if (key === 'rank') {
      setQuestionType('score');
      setPromptText('Score these sources for the client briefing');
      setStateJson(JSON.stringify({ goal: 'Benchmark agent latency and cost', required_data: ['pricing', 'latency'] }, null, 2));
    }
  };

  const run = async () => {
    setLoading(true);
    setError('');
    setResult(null);
    try {
      const state = JSON.parse(stateJson);
      const res = await fetch('./api/simulate-decision', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          state,
          question_type: questionType,
          prompt: promptText,
          options: optionsList,
          items: itemsList,
        }),
      });
      if (!res.ok) throw new Error('Jev did not return a decision');
      setResult(await res.json());
    } catch (err) {
      setError(err.message || 'Invalid state or network error');
    } finally {
      setLoading(false);
    }
  };

  const runCompact = async () => {
    const res = await fetch('./api/compaction', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ session_items: SESSION_TURNS }),
    });
    setCompact(await res.json());
  };

  return (
    <div className="space-y-5">
      <div>
        <h2 className="text-2xl font-semibold">Scoping lab</h2>
        <p className="mt-1 text-sm text-[var(--ink-2)]">This is how we prove a client question before we wire it into their dispatcher. Wrong answer? We sharpen state. We do not write a longer prompt.</p>
      </div>

      <div className="flex flex-wrap gap-2">
        {[
          ['support', 'Helio routing'],
          ['refund', 'Northline refund'],
          ['gate', 'Harbor gate'],
          ['rank', 'Source rank'],
        ].map(([id, label]) => (
          <button key={id} onClick={() => applyPreset(id)} className={`btn ${preset === id ? 'btn-primary' : ''}`}>{label}</button>
        ))}
      </div>

      <div className="grid gap-4 lg:grid-cols-2">
        <div className="panel space-y-4 p-5">
          <div className="text-[11px] font-mono uppercase tracking-wider text-[#ff4801]">Evidence in · decision out</div>
          <div className="grid grid-cols-3 gap-2">
            {['choice', 'score', 'noul'].map((type) => (
              <button key={type} onClick={() => setQuestionType(type)} className={`btn ${questionType === type ? 'btn-primary' : ''}`}>
                {type}
              </button>
            ))}
          </div>
          <label className="block text-xs font-medium">
            Question
            <input className="field mt-1" value={promptText} onChange={(e) => setPromptText(e.target.value)} />
          </label>
          <label className="block text-xs font-medium">
            Structured state
            <textarea className="codebox mt-1 w-full text-xs" rows={9} value={stateJson} onChange={(e) => setStateJson(e.target.value)} />
          </label>
          {questionType === 'choice' && (
            <label className="block text-xs font-medium">
              Options
              <input className="field mt-1 font-mono" value={optionsList.join(', ')} onChange={(e) => setOptionsList(e.target.value.split(',').map((s) => s.trim()).filter(Boolean))} />
            </label>
          )}
          <button className="btn btn-primary w-full" onClick={run} disabled={loading}>
            {loading ? <RefreshCw className="h-4 w-4 animate-spin" /> : <Zap className="h-4 w-4" />}
            Execute Jev
          </button>
          {error && <div className="text-sm text-[var(--bad)]">{error}</div>}
        </div>

        <div className="space-y-4">
          <div className="panel p-5">
            {!result && !loading && (
              <div className="rounded-xl border border-dashed border-[var(--line)] px-4 py-10 text-center text-sm text-[var(--ink-3)]">
                Run a client question to inspect the typed answer, policy action, and cost.
              </div>
            )}
            {loading && (
              <div className="py-10 text-center text-sm text-[var(--ink-3)]">
                <RefreshCw className="mx-auto mb-2 h-6 w-6 animate-spin text-[#ff4801]" />
                Evaluating System One…
              </div>
            )}
            {result && <DecisionCard result={result} />}
          </div>

          <div className="panel p-5">
            <div className="flex items-center justify-between gap-3">
              <div>
                <div className="text-sm font-semibold">Compaction we install</div>
                <div className="text-xs text-[var(--ink-3)]">Jev scores each turn and drops noise. The client LLM never rewrites history.</div>
              </div>
              <button className="btn" onClick={runCompact}>Filter session</button>
            </div>
            {compact && (
              <div className="mt-4 space-y-2 text-sm">
                <div className="badge good">
                  {compact.compaction_summary.reduction_percent}% removed · {compact.compaction_summary.latency_ms}ms
                </div>
                {compact.items.map((item) => (
                  <div key={item.id} className="flex items-center justify-between gap-3 rounded-lg bg-[var(--bg-soft)] px-3 py-2 text-xs">
                    <span className={item.retained ? '' : 'text-[var(--ink-3)] line-through'}>{item.content}</span>
                    <span className="font-mono">{item.relevance_score}</span>
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

function MethodPage({ onOpenLab }) {
  const [activeStep, setActiveStep] = useState(1);
  const [sorter, setSorter] = useState([
    { id: '1', task: 'Fetch web sources for a briefing', category: 'llm' },
    { id: '2', task: 'Which worker acts next?', category: 'jev' },
    { id: '3', task: 'Write the Monday brief', category: 'llm' },
    { id: '4', task: 'Is this source relevant?', category: 'jev' },
    { id: '5', task: 'Stop after 10 loops', category: 'code' },
    { id: '6', task: 'Is this bash call safe?', category: 'jev' },
  ]);

  const cycle = (id) => {
    setSorter((items) =>
      items.map((item) => {
        if (item.id !== id) return item;
        const next = item.category === 'llm' ? 'jev' : item.category === 'jev' ? 'code' : 'llm';
        return { ...item, category: next };
      }),
    );
  };

  const steps = [
    {
      title: 'Sort the work Jev can take',
      body: (
        <div className="space-y-4">
          <p>Every engagement starts with the client’s agent calls, not a rewrite. If it creates text, it stays on their LLM. If it picks, scores, or gates, we move it to Jev. Fixed numeric rules stay in their code.</p>
          <div className="grid gap-2 sm:grid-cols-3">
            {sorter.map((item) => (
              <button key={item.id} onClick={() => cycle(item.id)} className="panel p-3 text-left">
                <div className="text-sm font-medium">{item.task}</div>
                <div className="mt-2 flex gap-1 text-[10px] font-mono">
                  {['llm', 'jev', 'code'].map((cat) => (
                    <span key={cat} className={`rounded px-1.5 py-0.5 ${item.category === cat ? 'bg-[#ff4801] text-white' : 'bg-[var(--bg-mute)] text-[var(--ink-3)]'}`}>
                      {cat}
                    </span>
                  ))}
                </div>
              </button>
            ))}
          </div>
        </div>
      ),
    },
    {
      title: 'Design the state Jev reads',
      body: (
        <div className="space-y-3">
          <p>We do not let a client hand Jev vibes. A ticket state we ship names the customer, the failure, and the constraint.</p>
          <div className="grid gap-3 md:grid-cols-2">
            <div className="rounded-xl bg-[var(--bad-soft)] p-3 text-xs">
              <div className="mb-1 font-semibold text-[var(--bad)]">What we reject</div>
              <pre>{`{ "status": "in progress" }`}</pre>
            </div>
            <div className="rounded-xl bg-[var(--good-soft)] p-3 text-xs">
              <div className="mb-1 font-semibold text-[var(--good)]">What we install</div>
              <pre>{`{ "goal": "Unblock Helio payouts", "signals": ["payout_failed"] }`}</pre>
            </div>
          </div>
        </div>
      ),
    },
    {
      title: 'Prove one question in the lab',
      body: (
        <div className="space-y-3">
          <p>Before we touch production, we run a single client question in the scoping lab. If Jev is wrong, we fix the evidence — not the prompt essay.</p>
          <button className="btn btn-primary" onClick={onOpenLab}>Open the scoping lab</button>
        </div>
      ),
    },
    {
      title: 'Map work to the three primitives',
      body: (
        <div className="grid gap-3 md:grid-cols-3">
          <div className="panel p-4"><div className="font-semibold">Choice</div><p className="mt-1 text-sm text-[var(--ink-2)]">We install routing: team, worker, or model.</p></div>
          <div className="panel p-4"><div className="font-semibold">Score</div><p className="mt-1 text-sm text-[var(--ink-2)]">We install ranking: sources, refund fit, urgency.</p></div>
          <div className="panel p-4"><div className="font-semibold">Noul</div><p className="mt-1 text-sm text-[var(--ink-2)]">We install gates: approve, block, escalate.</p></div>
        </div>
      ),
    },
    {
      title: 'Funnel a large list',
      body: (
        <div className="space-y-2 font-mono text-xs">
          <div className="panel p-3">Client code eligibility · 100 → 20</div>
          <div className="panel p-3">Jev Score we install · 20 → 3</div>
          <div className="panel border-[#ff4801] p-3 text-[#ff4801]">Jev Choice we install · 3 → 1</div>
        </div>
      ),
    },
    {
      title: 'Install the dispatcher',
      body: (
        <div className="codebox text-xs">
          <pre>{`# What Jevineering leaves in the client repo
decision = jev.choice(state, question)
if decision.confidence >= 0.85:
    dispatcher.send(decision.option, state)
else:
    dispatcher.send("human_review", state)  # client on-call`}</pre>
        </div>
      ),
    },
    {
      title: 'Batch questions that share state',
      body: (
        <p>Routing, urgency, and approval often inspect the same ticket. We send them in one Jev round trip instead of three frontier loops the client was already paying for.</p>
      ),
    },
    {
      title: 'Add the harness',
      body: (
        <p>We sit a model router at the top and an auto-mode Noul gate at the bottom. The client’s writer stays cheap. `bash` and `DROP` never reach code on a failed gate.</p>
      ),
    },
    {
      title: 'Compact with a filter',
      body: (
        <p>We remove the summarizer. Jev scores every turn and drops the rest. That is the compaction path we install — not a rewrite of history.</p>
      ),
    },
    {
      title: 'Count the cost the client removed',
      body: (
        <p>10,000 decisions at 1,000 tokens is about $0.42 on Jev. The same yes/no loops on a frontier model were a four-figure monthly line on the client bill. That delta is why companies hire us.</p>
      ),
    },
  ];

  const step = steps[activeStep - 1];

  return (
    <div className="space-y-5">
      <div>
        <h2 className="text-2xl font-semibold">How we implement Jev</h2>
        <p className="mt-1 text-sm text-[var(--ink-2)]">The 10-step engagement we run with every company. Same method, their state, their policy line.</p>
      </div>
      <div className="grid grid-cols-2 gap-2 sm:grid-cols-5">
        {steps.map((item, idx) => (
          <button
            key={item.title}
            onClick={() => setActiveStep(idx + 1)}
            className={`rounded-xl border px-3 py-2 text-left text-xs ${activeStep === idx + 1 ? 'border-[#ff4801] bg-[#ff4801] text-white' : 'border-[var(--line)] bg-[var(--bg-elev)]'}`}
          >
            <div className="font-mono text-[10px] opacity-70">{String(idx + 1).padStart(2, '0')}</div>
            <div className="mt-1 font-medium leading-snug">{item.title}</div>
          </button>
        ))}
      </div>
      <div className="panel p-6">
        <div className="mb-4 flex items-center justify-between">
          <h3 className="text-xl font-semibold">{step.title}</h3>
          <span className="font-mono text-xs text-[var(--ink-3)]">{activeStep} / 10</span>
        </div>
        <div className="text-sm leading-relaxed text-[var(--ink-2)]">{step.body}</div>
        <div className="mt-6 flex justify-between">
          <button className="btn" disabled={activeStep === 1} onClick={() => setActiveStep(activeStep - 1)}>Previous</button>
          <button className="btn btn-primary" disabled={activeStep === 10} onClick={() => setActiveStep(activeStep + 1)}>Next step</button>
        </div>
      </div>
    </div>
  );
}

function EconomicsPage() {
  const [decisionsPerDay, setDecisionsPerDay] = useState(18000);
  const [tokensPerState, setTokensPerState] = useState(800);
  const [modelType, setModelType] = useState('gpt4o');

  const models = {
    gpt4o: { name: 'GPT-4o', input: 2.5, output: 10 },
    claude: { name: 'Claude Sonnet', input: 3, output: 15 },
    gemini: { name: 'Gemini 1.5 Pro', input: 1.25, output: 5 },
  };
  const selected = models[modelType];
  const monthlyDecisions = decisionsPerDay * 30;
  const monthlyTokensM = (monthlyDecisions * tokensPerState) / 1_000_000;
  const monthlyJev = monthlyTokensM * 0.042;
  const monthlyFrontier = monthlyTokensM * selected.input + ((monthlyDecisions * 150) / 1_000_000) * selected.output;
  const monthlySave = monthlyFrontier - monthlyJev;
  const pct = Math.round((monthlySave / (monthlyFrontier || 1)) * 100);

  return (
    <div className="space-y-5">
      <div>
        <h2 className="text-2xl font-semibold">What a client stops paying</h2>
        <p className="mt-1 text-sm text-[var(--ink-2)]">We price the engagement against the frontier loops we remove. The writing model stays on their bill. Decision loops move to Jev.</p>
      </div>
      <div className="grid gap-4 lg:grid-cols-2">
        <div className="panel space-y-6 p-6">
          <label className="block text-sm">
            <div className="mb-2 flex justify-between"><span>Client decisions / day</span><span className="font-mono text-[#ff4801]">{decisionsPerDay.toLocaleString()}</span></div>
            <input type="range" min="1000" max="200000" step="1000" value={decisionsPerDay} onChange={(e) => setDecisionsPerDay(Number(e.target.value))} />
          </label>
          <label className="block text-sm">
            <div className="mb-2 flex justify-between"><span>Tokens / state</span><span className="font-mono text-[#ff4801]">{tokensPerState.toLocaleString()}</span></div>
            <input type="range" min="200" max="8000" step="100" value={tokensPerState} onChange={(e) => setTokensPerState(Number(e.target.value))} />
          </label>
          <div className="grid grid-cols-3 gap-2">
            {Object.entries(models).map(([id, model]) => (
              <button key={id} onClick={() => setModelType(id)} className={`btn ${modelType === id ? 'btn-primary' : ''}`}>{model.name}</button>
            ))}
          </div>
        </div>
        <div className="panel border-[#ff4801] p-6">
          <div className="text-[11px] font-mono uppercase tracking-wider text-[#ff4801]">Monthly client savings after cutover</div>
          <div className="mt-2 text-4xl font-semibold text-[#ff4801]">${formatUsd(monthlySave, 0)}</div>
          <div className="mt-1 text-sm text-[var(--good)]">{pct}% below {selected.name} · ${formatUsd(monthlySave * 12, 0)} / year</div>
          <div className="mt-6 space-y-2 text-sm">
            <div className="flex justify-between rounded-xl bg-[var(--bad-soft)] px-3 py-3">
              <span>Before · {selected.name} loops</span>
              <span className="font-mono">${formatUsd(monthlyFrontier)}</span>
            </div>
            <div className="flex justify-between rounded-xl bg-[var(--good-soft)] px-3 py-3">
              <span>After · Jev we installed</span>
              <span className="font-mono">${formatUsd(monthlyJev)}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function DiagnosticPage() {
  const [answers, setAnswers] = useState([3, 3, 3, 3, 3]);
  const [result, setResult] = useState(null);

  const questions = [
    'How does the company decide which team or worker acts next?',
    'How are tool calls and refunds gated before they execute?',
    'How is long session history reduced?',
    'How are sources or claims ranked?',
    'How many frontier calls per run exist only to answer yes or no?',
  ];
  const options = [
    ['Deterministic code', 'Jev System One', 'Frontier LLM loop'],
    ['Static rules', 'Jev Noul gate', 'Frontier safety prompt'],
    ['Trim rules', 'Jev Score filter', 'LLM summarizer'],
    ['Heuristic score', 'Jev Score', 'Frontier rank prompt'],
    ['None — code or Jev', '1–3 calls', '4+ frontier calls'],
  ];

  const submit = async () => {
    const res = await fetch('./api/audit', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ answers }),
    });
    setResult(await res.json());
  };

  return (
    <div className="mx-auto max-w-3xl space-y-5">
      <div>
        <h2 className="text-2xl font-semibold">Pre-engagement diagnostic</h2>
        <p className="mt-1 text-sm text-[var(--ink-2)]">We run this before we staff a cutover. It tells us which loops to move off the frontier model first.</p>
      </div>
      <div className="panel space-y-5 p-6">
        {questions.map((question, qIdx) => (
          <div key={question}>
            <div className="text-sm font-medium">{question}</div>
            <div className="mt-2 grid gap-2 sm:grid-cols-3">
              {options[qIdx].map((label, optIdx) => (
                <button
                  key={label}
                  onClick={() => setAnswers((prev) => prev.map((value, idx) => (idx === qIdx ? optIdx + 1 : value)))}
                  className={`btn text-left text-xs ${answers[qIdx] === optIdx + 1 ? 'btn-primary' : ''}`}
                >
                  {label}
                </button>
              ))}
            </div>
          </div>
        ))}
        <button className="btn btn-primary w-full" onClick={submit}>Score the leak</button>
        {result && (
          <div className="rounded-2xl border border-[#ff4801] bg-[var(--accent-soft)] p-4">
            <div className="flex items-center justify-between">
              <span className="text-sm font-semibold">{result.tier}</span>
              <span className="font-mono text-lg text-[#ff4801]">{result.leak_percentage}%</span>
            </div>
            <p className="mt-2 text-sm">{result.summary}</p>
            <div className="mt-3 space-y-1 text-sm">
              {result.recommended_actions.map((action) => (
                <div key={action} className="flex gap-2">
                  <CheckCircle2 className="mt-0.5 h-4 w-4 shrink-0 text-[var(--good)]" />
                  <span>{action}</span>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function DeliveryPage({ onCopy, copiedCode }) {
  const [lang, setLang] = useState('python');
  const py = `# What Jevineering ships into the client repo
from typesafe import Jev, AutoModeMiddleware

jev = Jev(api_key="ts_live_...")

state = {
  "customer": "Helio Labs",
  "message": "Payouts have failed for 3 days.",
  "signals": ["payout_failed", "invoice_overdue"],
}

decision = jev.choice(
  state=state,
  prompt="Which team should handle this support request?",
  options=["billing", "technical", "sales", "risk"],
)

if decision.confidence >= 0.85:
    dispatcher.send(decision.option, state)
else:
    dispatcher.send("human_review", state)

guardrail = AutoModeMiddleware(tools=["bash", "sql_drop"])
`;
  const ts = `import { Jev, AutoModeMiddleware } from '@typesafe/ai';

const jev = new Jev({ apiKey: process.env.TYPESAFE_API_KEY });

const decision = await jev.choice({
  state: {
    customer: 'Helio Labs',
    message: 'Payouts have failed for 3 days.',
    signals: ['payout_failed'],
  },
  prompt: 'Which team should handle this support request?',
  options: ['billing', 'technical', 'sales', 'risk'],
});

if (decision.confidence >= 0.85) {
  await dispatcher.send(decision.option, state);
} else {
  await dispatcher.send('human_review', state);
}
`;
  const code = lang === 'python' ? py : ts;

  return (
    <div className="mx-auto max-w-4xl space-y-5">
      <div>
        <h2 className="text-2xl font-semibold">What we leave in the repo</h2>
        <p className="mt-1 text-sm text-[var(--ink-2)]">The engagement ends with a typed harness, a confidence line, and a gate in front of dangerous tools. The client owns the dispatcher. We own the install.</p>
      </div>
      <div className="panel p-5">
        <div className="mb-3 flex items-center justify-between gap-3">
          <div className="flex gap-2">
            <button className={`btn ${lang === 'python' ? 'btn-primary' : ''}`} onClick={() => setLang('python')}>harness.py</button>
            <button className={`btn ${lang === 'typescript' ? 'btn-primary' : ''}`} onClick={() => setLang('typescript')}>harness.ts</button>
          </div>
          <button className="btn" onClick={() => onCopy(code, 'sdk')}>
            {copiedCode === 'sdk' ? <Check className="h-4 w-4 text-[var(--good)]" /> : <Copy className="h-4 w-4" />}
            {copiedCode === 'sdk' ? 'Copied' : 'Copy'}
          </button>
        </div>
        <div className="codebox text-xs"><pre>{code}</pre></div>
      </div>
      <div className="grid gap-3 md:grid-cols-3">
        <div className="panel p-4"><ClipboardList className="mb-2 h-4 w-4 text-[#ff4801]" /><div className="font-semibold">State contract</div><p className="mt-1 text-sm text-[var(--ink-2)]">We define one evidence shape for tickets, refunds, and tools.</p></div>
        <div className="panel p-4"><Brain className="mb-2 h-4 w-4 text-[#ff4801]" /><div className="font-semibold">Policy line</div><p className="mt-1 text-sm text-[var(--ink-2)]">0.85 auto-dispatch. Below that, the client’s on-call owns the case.</p></div>
        <div className="panel p-4"><ShieldAlert className="mb-2 h-4 w-4 text-[#ff4801]" /><div className="font-semibold">Auto-mode</div><p className="mt-1 text-sm text-[var(--ink-2)]">Noul blocks `rm`, `DROP`, and out-of-policy refunds.</p></div>
      </div>
    </div>
  );
}

const container = document.getElementById('root');
if (container) {
  createRoot(container).render(<App />);
}
