// Shared components: topbar, sidebar, TOC, code blocks, feedback, search, tweaks
// Note: dangerouslySetInnerHTML is used only for our own hardcoded syntax-highlighted
// code templates below — no user input ever reaches it.

const Icon = ({ name, size = 16, stroke = 1.6 }) => {
  const paths = {
    search: <><circle cx="11" cy="11" r="7" /><path d="m20 20-3.5-3.5" /></>,
    sun: <><circle cx="12" cy="12" r="4" /><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41" /></>,
    moon: <path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z" />,
    chev: <path d="m6 9 6 6 6-6" />,
    chevR: <path d="m9 6 6 6-6 6" />,
    chevL: <path d="m15 6-6 6 6 6" />,
    copy: <><rect x="9" y="9" width="11" height="11" rx="2" /><path d="M5 15V6a2 2 0 0 1 2-2h9" /></>,
    check: <path d="m5 12 4.5 4.5L19 7" />,
    ext: <><path d="M15 3h6v6" /><path d="M10 14 21 3" /><path d="M21 14v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5" /></>,
    arrowR: <path d="M5 12h14M13 5l7 7-7 7" />,
    arrowL: <path d="M19 12H5M11 5l-7 7 7 7" />,
    arrowUp: <path d="M7 17 17 7M8 7h9v9" />,
    bolt: <path d="M13 2 4 14h7l-1 8 9-12h-7l1-8z" />,
    book: <><path d="M4 4v16a2 2 0 0 0 2 2h14V4" /><path d="M4 4h14v16H6a2 2 0 0 1-2-2Z" /></>,
    code: <><path d="m16 18 6-6-6-6M8 6l-6 6 6 6" /></>,
    puzzle: <path d="M19.44 12.56a2 2 0 1 0 0-3.12V7a2 2 0 0 0-2-2h-2.44a2 2 0 1 0-3.12 0H9.44a2 2 0 0 0-2 2v2.44a2 2 0 1 1 0 3.12V17a2 2 0 0 0 2 2h2.44a2 2 0 1 0 3.12 0h2.44a2 2 0 0 0 2-2z" />,
    cpu: <><rect x="5" y="5" width="14" height="14" rx="2" /><rect x="9" y="9" width="6" height="6" /><path d="M9 2v2M15 2v2M9 20v2M15 20v2M2 9h2M2 15h2M20 9h2M20 15h2" /></>,
    shield: <path d="M12 2 4 6v6c0 5 3.5 9 8 10 4.5-1 8-5 8-10V6Z" />,
    zap: <path d="M13 2 3 14h9l-1 8 10-12h-9z" />,
    terminal: <><path d="m6 9 4 3-4 3" /><path d="M12 15h6" /><rect x="3" y="4" width="18" height="16" rx="2" /></>,
    link: <><path d="M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1" /><path d="M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1" /></>,
    info: <><circle cx="12" cy="12" r="9" /><path d="M12 8h.01M11 12h1v5h1" /></>,
    warn: <><path d="M12 3 2 21h20z" /><path d="M12 9v5M12 18h.01" /></>,
    sparkle: <path d="M12 3v4M12 17v4M3 12h4M17 12h4M5.6 5.6l2.8 2.8M15.6 15.6l2.8 2.8M5.6 18.4l2.8-2.8M15.6 8.4l2.8-2.8" />,
    thumbUp: <path d="M7 10v11H3V10zm4 0 3-7a2 2 0 0 1 4 1l-2 6h5a2 2 0 0 1 2 2l-2 8a2 2 0 0 1-2 2h-8z" />,
    thumbDown: <path d="M17 14V3h4v11zm-4 0-3 7a2 2 0 0 1-4-1l2-6H3a2 2 0 0 1-2-2l2-8a2 2 0 0 1 2-2h8z" />,
    hash: <path d="M4 9h16M4 15h16M10 3 8 21M16 3l-2 18" />,
    clock: <><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3 2" /></>,
    github: <path d="M9 19c-4 1.5-4-2-6-2m12 4v-3.5c0-1 .1-1.4-.5-2 2.8-.3 5.5-1.4 5.5-6a4.6 4.6 0 0 0-1.3-3.2 4.2 4.2 0 0 0-.1-3.2s-1.1-.3-3.5 1.3a12 12 0 0 0-6.2 0C6.5 2.8 5.4 3.1 5.4 3.1a4.2 4.2 0 0 0-.1 3.2A4.6 4.6 0 0 0 4 9.5c0 4.6 2.7 5.7 5.5 6-.6.6-.6 1.2-.5 2V21" />,
    command: <path d="M15 6a3 3 0 1 1 3 3h-3zm0 0v12m0 0a3 3 0 1 0 3-3h-3zm0 0H9m0 0a3 3 0 1 1-3-3h3zm0 0V6m0 0a3 3 0 1 0-3 3h3z" />,
    return: <path d="m9 10-3 3 3 3M6 13h10a4 4 0 0 0 4-4V6" />,
    x: <path d="M18 6 6 18M6 6l12 12" />,
    plus: <path d="M12 5v14M5 12h14" />,
    rocket: <><path d="M4.5 16.5c-1.5 1.3-2 5-2 5s3.7-.5 5-2c.7-.8.7-2.1-.1-3-.8-.8-2.1-.8-2.9 0Z"/><path d="M12 15 9 12a11 11 0 0 1 7-7c3 0 6 1 6 1s0 3-1 6a11 11 0 0 1-7 7Z"/><path d="M9 12H4s.5-3 2-4 5 0 5 0M12 15v5s3-.5 4-2 0-5 0-5"/><circle cx="15" cy="9" r="1.2"/></>,
    leaf: <path d="M11 20A7 7 0 0 1 4 13c0-7 8-11 16-11 0 8-4 16-11 16-3 0-4-3-4-3m0 0c0-5 4-9 8-10"/>,
    at: <><circle cx="12" cy="12" r="4"/><path d="M16 8v5a3 3 0 0 0 6 0v-1A10 10 0 1 0 18 20"/></>,
    database: <><ellipse cx="12" cy="5" rx="8" ry="3"/><path d="M4 5v6c0 1.7 3.6 3 8 3s8-1.3 8-3V5M4 11v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6"/></>,
    globe: <><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c3 3 3 15 0 18M12 3c-3 3-3 15 0 18"/></>,
    list: <><path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"/></>,
    filter: <path d="M3 4h18l-7 9v6l-4 2v-8z"/>,
    webhook: <><circle cx="12" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="18" r="3"/><path d="m9 8-3 7M15 8l3 7M9 18h6"/></>,
    key: <><circle cx="7.5" cy="15.5" r="4.5"/><path d="m11 12 9-9 3 3-3 3 2 2-2 2-2-2-3 3"/></>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke="currentColor" strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round">
      {paths[name]}
    </svg>
  );
};

function Topbar({ onSearch, theme, setTheme, section }) {
  const sections = [
    { id: 'docs', label: 'Documentation', href: 'index.html' },
    { id: 'api', label: 'API Reference', href: 'api-reference.html' },
    { id: 'guides', label: 'Guides', href: 'guide.html' },
    { id: 'changelog', label: 'Changelog', href: 'changelog.html' },
  ];
  return (
    <header className="topbar">
      <a className="brand" href="index.html">
        <div className="brand-mark">C</div>
        <span>ClawAgen</span>
        <span className="brand-tag">v0.1</span>
      </a>
      <nav className="topnav">
        {sections.map(s => (
          <a key={s.id} href={s.href} className={section === s.id ? 'active' : ''}>{s.label}</a>
        ))}
      </nav>
      <div className="topbar-right">
        <button className="search-trigger" onClick={onSearch}>
          <Icon name="search" size={14} />
          <span>Search documentation…</span>
          <span className="kbd">⌘K</span>
        </button>
        <button className="icon-btn" onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')} title="Toggle theme">
          <Icon name={theme === 'dark' ? 'sun' : 'moon'} size={16} />
        </button>
        <a className="icon-btn" href="https://github.com/carrickcheah/ai-agents" title="GitHub"><Icon name="github" size={16} /></a>
        <a className="btn-primary" href="#">Dashboard <Icon name="arrowR" size={12} stroke={2} /></a>
      </div>
    </header>
  );
}

const NAV = [
  {
    title: 'Getting started',
    items: [
      { label: 'Introduction', href: 'index.html', id: 'introduction' },
      { label: 'Quickstart', href: 'quickstart.html', id: 'quickstart' },
      { label: 'Authentication', href: '#', id: 'auth' },
      { label: 'Errors & retries', href: '#', id: 'errors' },
    ]
  },
  {
    title: 'Concepts',
    items: [
      { label: 'Architecture', href: 'guide.html', id: 'arch' },
      { label: 'Agents (Admin + CS)', href: '#', id: 'agents' },
      { label: 'Skills', href: '#', id: 'skills' },
      { label: 'Memory & context files', href: '#', id: 'memory', badge: 'new' },
      { label: '2-tool runtime', href: '#', id: 'tools' },
    ]
  },
  {
    title: 'Channels',
    items: [
      { label: 'WhatsApp', href: '#', id: 'wa' },
      { label: 'Telegram', href: '#', id: 'tg' },
      { label: 'Facebook Messenger', href: '#', id: 'fb' },
      { label: 'Instagram DM', href: '#', id: 'ig' },
      { label: 'Web Widget', href: '#', id: 'webw' },
    ]
  },
  {
    title: 'SDKs',
    items: [
      { label: 'Node.js', href: '#', id: 'node' },
      { label: 'Python', href: '#', id: 'py' },
    ]
  },
  {
    title: 'API',
    items: [
      { label: 'Overview', href: 'api-reference.html', id: 'api-overview' },
      { label: 'Chat — Admin', href: 'api-reference.html', id: 'api-admin' },
      { label: 'Chat — CS', href: 'api-reference.html', id: 'api-cs' },
      { label: 'Sessions', href: '#', id: 'api-sess' },
      { label: 'Skills', href: '#', id: 'api-skills' },
      { label: 'Webhooks', href: '#', id: 'api-webhook' },
      { label: 'Rate limits', href: '#', id: 'api-rate' },
    ]
  },
];

function Sidebar({ activeId }) {
  const [collapsed, setCollapsed] = React.useState({});
  const toggle = (t) => setCollapsed(s => ({ ...s, [t]: !s[t] }));
  return (
    <aside className="sidebar">
      {NAV.map((section, idx) => (
        <div key={idx} className={`side-section ${collapsed[section.title] ? 'collapsed' : ''}`}>
          <button className="side-section-header" onClick={() => toggle(section.title)}>
            {section.title}
            <span className="chev"><Icon name="chev" size={12} stroke={2} /></span>
          </button>
          <div className="side-items">
            {section.items.map(it => (
              <a key={it.id} href={it.href}
                 className={`side-link ${activeId === it.id ? 'active' : ''}`}>
                {it.label}
                {it.badge && <span className={`badge ${it.badge}`}>{it.badge}</span>}
              </a>
            ))}
          </div>
        </div>
      ))}
    </aside>
  );
}

function TOC({ items }) {
  const [active, setActive] = React.useState(items[0]?.id);
  React.useEffect(() => {
    const handler = () => {
      let current = items[0]?.id;
      for (const it of items) {
        const el = document.getElementById(it.id);
        if (el && el.getBoundingClientRect().top < 120) current = it.id;
      }
      setActive(current);
    };
    handler();
    window.addEventListener('scroll', handler, { passive: true });
    return () => window.removeEventListener('scroll', handler);
  }, [items]);
  return (
    <aside className="toc">
      <div className="toc-label">On this page</div>
      <ul>
        {items.map(it => (
          <li key={it.id} className={`lvl-${it.level || 2}`}>
            <a href={`#${it.id}`} className={active === it.id ? 'active' : ''}>{it.label}</a>
          </li>
        ))}
      </ul>
      <div className="toc-foot">
        <a href="https://github.com/carrickcheah/ai-agents" target="_blank" rel="noreferrer"><Icon name="ext" size={12} /> Edit this page</a>
        <a href="https://github.com/carrickcheah/ai-agents" target="_blank" rel="noreferrer"><Icon name="github" size={12} /> View on GitHub</a>
        <a href="#" onClick={(e) => { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth' }); }}>
          <Icon name="arrowUp" size={12} /> Back to top
        </a>
      </div>
    </aside>
  );
}

function CodeBlock({ tabs, filename, defaultTab = 0 }) {
  const [active, setActive] = React.useState(defaultTab);
  const [copied, setCopied] = React.useState(false);
  const current = tabs[active];
  const copy = () => {
    const text = current.raw || current.code.replace(/<[^>]+>/g, '');
    navigator.clipboard?.writeText(text);
    setCopied(true);
    setTimeout(() => setCopied(false), 1400);
  };
  return (
    <div className="code-block">
      <div className="code-head">
        {tabs.length > 1 ? (
          <div className="code-tabs">
            {tabs.map((t, i) => (
              <button key={i} className={`code-tab ${i === active ? 'active' : ''}`} onClick={() => setActive(i)}>
                {t.label}
              </button>
            ))}
          </div>
        ) : (
          <span className="code-filename">{filename || tabs[0].label}</span>
        )}
        <div className="code-actions">
          <button className={`code-icon-btn ${copied ? 'copied' : ''}`} onClick={copy} title="Copy">
            <Icon name={copied ? 'check' : 'copy'} size={14} />
          </button>
        </div>
      </div>
      <pre className="code-body" dangerouslySetInnerHTML={{ __html: current.code }} />
    </div>
  );
}

function Callout({ type = 'info', title, children }) {
  const icons = { info: 'info', warn: 'warn', note: 'sparkle', danger: 'warn' };
  return (
    <div className={`callout ${type}`}>
      <div className="ico"><Icon name={icons[type]} size={14} /></div>
      <div>
        {title && <div className="callout-title">{title}</div>}
        <div>{children}</div>
      </div>
    </div>
  );
}

function Feedback() {
  const [rating, setRating] = React.useState(null);
  const [sent, setSent] = React.useState(false);
  if (sent) {
    return (
      <div className="feedback">
        <div>
          <h4>Thanks for the feedback.</h4>
          <p>We read every note and use it to improve these docs.</p>
        </div>
        <div>
          <div className="card-ico" style={{marginBottom:0, background:'var(--accent-soft)', color:'var(--accent-ink)'}}>
            <Icon name="check" size={16} stroke={2.2} />
          </div>
        </div>
      </div>
    );
  }
  return (
    <div className={`feedback ${rating !== null ? 'open' : ''}`}>
      <div>
        <h4>Was this page helpful?</h4>
        <p>Your feedback helps us sharpen the docs.</p>
      </div>
      <div className="fb-actions">
        <button className={`fb-btn ${rating === 'up' ? 'selected' : ''}`} onClick={() => setRating('up')}>
          <Icon name="thumbUp" size={14} /> Yes
        </button>
        <button className={`fb-btn ${rating === 'down' ? 'selected' : ''}`} onClick={() => setRating('down')}>
          <Icon name="thumbDown" size={14} /> No
        </button>
      </div>
      <div className="feedback-form">
        <textarea placeholder={rating === 'up' ? 'What worked well?' : 'What could be better? Be specific — we read everything.'} />
        <div className="row">
          <button className="btn-ghost" onClick={() => setRating(null)}>Cancel</button>
          <button className="btn-primary" onClick={() => setSent(true)}>Send feedback</button>
        </div>
      </div>
    </div>
  );
}

function PageFoot({ prev, next }) {
  return (
    <div className="page-foot">
      {prev ? (
        <a href={prev.href}>
          <div className="label">← Previous</div>
          <div className="title"><Icon name="arrowL" size={12} /> {prev.label}</div>
        </a>
      ) : <div />}
      {next ? (
        <a href={next.href} className="next">
          <div className="label">Next →</div>
          <div className="title">{next.label} <Icon name="arrowR" size={12} /></div>
        </a>
      ) : <div />}
    </div>
  );
}

const SEARCH_INDEX = [
  { group: 'Getting started', title: 'Introduction', path: '/', href: 'index.html', icon: 'book' },
  { group: 'Getting started', title: 'Quickstart — your first agent reply', path: '/quickstart', href: 'quickstart.html', icon: 'rocket' },
  { group: 'Getting started', title: 'Authentication with API keys', path: '/auth', href: '#', icon: 'key' },
  { group: 'Getting started', title: 'Errors & retries', path: '/errors', href: '#', icon: 'warn' },
  { group: 'Concepts', title: 'Architecture — multi-tenant, filesystem-first', path: '/concepts/architecture', href: 'guide.html', icon: 'puzzle' },
  { group: 'Concepts', title: 'Admin & CS agents', path: '/concepts/agents', href: '#', icon: 'cpu' },
  { group: 'Concepts', title: 'Skills — Markdown, progressive disclosure', path: '/concepts/skills', href: '#', icon: 'puzzle' },
  { group: 'Concepts', title: 'Memory & the eight context files', path: '/concepts/memory', href: '#', icon: 'database' },
  { group: 'Concepts', title: '2-tool runtime (bash + load_skill)', path: '/concepts/tools', href: '#', icon: 'terminal' },
  { group: 'Channels', title: 'WhatsApp Cloud API', path: '/channels/whatsapp', href: '#', icon: 'at' },
  { group: 'Channels', title: 'Telegram Bot', path: '/channels/telegram', href: '#', icon: 'at' },
  { group: 'API', title: 'POST /api/admin — owner-facing agent', path: '/api/admin', href: 'api-reference.html', icon: 'code' },
  { group: 'API', title: 'POST /api/cs — customer-facing agent', path: '/api/cs', href: 'api-reference.html', icon: 'code' },
  { group: 'API', title: 'Rate limits & quotas', path: '/api/rate-limits', href: '#', icon: 'bolt' },
  { group: 'API', title: 'Webhooks reference', path: '/api/webhooks', href: '#', icon: 'webhook' },
  { group: 'Changelog', title: 'v0.1 — Phase 8/9 channels ship', path: '/changelog#0.1', href: 'changelog.html', icon: 'sparkle' },
];

function SearchOverlay({ open, onClose }) {
  const [q, setQ] = React.useState('');
  const [focus, setFocus] = React.useState(0);
  const inputRef = React.useRef();
  React.useEffect(() => {
    if (open) {
      setTimeout(() => inputRef.current?.focus(), 20);
      setQ(''); setFocus(0);
    }
  }, [open]);
  const results = React.useMemo(() => {
    if (!q.trim()) return SEARCH_INDEX;
    const needle = q.toLowerCase();
    return SEARCH_INDEX.filter(r =>
      r.title.toLowerCase().includes(needle) ||
      r.path.toLowerCase().includes(needle) ||
      r.group.toLowerCase().includes(needle)
    );
  }, [q]);
  const grouped = React.useMemo(() => {
    const g = {};
    results.forEach(r => { (g[r.group] = g[r.group] || []).push(r); });
    return g;
  }, [results]);
  const flat = results;

  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === 'Escape') onClose();
      if (e.key === 'ArrowDown') { e.preventDefault(); setFocus(f => Math.min(flat.length - 1, f + 1)); }
      if (e.key === 'ArrowUp') { e.preventDefault(); setFocus(f => Math.max(0, f - 1)); }
      if (e.key === 'Enter' && flat[focus]) {
        window.location.href = flat[focus].href;
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, flat, focus, onClose]);

  const highlight = (text) => {
    if (!q.trim()) return text;
    const i = text.toLowerCase().indexOf(q.toLowerCase());
    if (i < 0) return text;
    return <>{text.slice(0,i)}<mark>{text.slice(i, i+q.length)}</mark>{text.slice(i+q.length)}</>;
  };

  let counter = 0;
  return (
    <div className={`search-overlay ${open ? 'open' : ''}`} onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
      <div className="search-modal" onMouseDown={e => e.stopPropagation()}>
        <div className="search-input-wrap">
          <Icon name="search" size={16} />
          <input ref={inputRef} className="search-input" placeholder="Search for anything…"
                 value={q} onChange={e => { setQ(e.target.value); setFocus(0); }} />
          <button className="icon-btn" onClick={onClose} style={{width: 28, height: 28}}>
            <span className="kbd" style={{fontSize:10}}>ESC</span>
          </button>
        </div>
        <div className="search-results">
          {flat.length === 0 ? (
            <div className="search-empty">No results for “{q}”. Try a different term.</div>
          ) : Object.entries(grouped).map(([group, rows]) => (
            <div key={group}>
              <div className="search-group-label">{group}</div>
              {rows.map((r) => {
                const idx = counter++;
                return (
                  <a key={r.title} href={r.href}
                     className={`search-result ${idx === focus ? 'focused' : ''}`}
                     onMouseEnter={() => setFocus(idx)}>
                    <span className="res-ico"><Icon name={r.icon} size={14} /></span>
                    <span className="res-title">{highlight(r.title)}</span>
                    <span className="res-path">{r.path}</span>
                  </a>
                );
              })}
            </div>
          ))}
        </div>
        <div className="search-foot">
          <div className="item"><span className="kbd">↑</span><span className="kbd">↓</span> navigate</div>
          <div className="item"><span className="kbd">↵</span> select</div>
          <div className="item"><span className="kbd">ESC</span> close</div>
          <div className="item" style={{marginLeft:'auto'}}>Powered by local index</div>
        </div>
      </div>
    </div>
  );
}

function TweaksPanel({ visible, theme, setTheme }) {
  if (!visible) return null;
  return (
    <div className="tweaks-panel visible">
      <div className="tweaks-title">Tweaks</div>
      <div className="tweaks-row">
        <span>Theme</span>
        <div className="toggle-group">
          <button className={`toggle-btn ${theme === 'light' ? 'active' : ''}`} onClick={() => setTheme('light')}>Light</button>
          <button className={`toggle-btn ${theme === 'dark' ? 'active' : ''}`} onClick={() => setTheme('dark')}>Dark</button>
        </div>
      </div>
    </div>
  );
}

function useShell(defaultTheme = 'light') {
  const [theme, setThemeState] = React.useState(() => localStorage.getItem('clawagen-theme') || defaultTheme);
  const [searchOpen, setSearchOpen] = React.useState(false);
  const [tweaksVisible, setTweaksVisible] = React.useState(false);

  const setTheme = React.useCallback((t) => {
    setThemeState(t);
    localStorage.setItem('clawagen-theme', t);
    document.documentElement.setAttribute('data-theme', t);
  }, []);

  React.useEffect(() => {
    document.documentElement.setAttribute('data-theme', theme);
  }, [theme]);

  React.useEffect(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault();
        setSearchOpen(s => !s);
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  return { theme, setTheme, searchOpen, setSearchOpen, tweaksVisible };
}

Object.assign(window, {
  Icon, Topbar, Sidebar, TOC, CodeBlock, Callout, Feedback, PageFoot,
  SearchOverlay, TweaksPanel, useShell, NAV, SEARCH_INDEX,
});
