// ----- Documentation content + helpers -----

const DOCS_NAV = [
  {
    section: "Get started",
    pages: [
      { slug: "overview", title: "Overview", description: "What OmnisysX is and how the Trinity agents work together." },
      { slug: "setup", title: "Setup", description: "From clean machine to working install." },
      { slug: "running", title: "Running it", description: "Starting the Agent and the Discord Bot." }
    ]
  },
  {
    section: "Concepts",
    pages: [
      { slug: "architecture", title: "Architecture", description: "Multi-agent pipeline: perceive, plan, act, verify." },
      { slug: "agents", title: "The Trinity", description: "Observer, Task Manager, Auditor, and the Executor." },
      { slug: "pipeline", title: "Pipeline", description: "Six stages from OBSERVE to VERIFY." },
      { slug: "security", title: "Security model", description: "Defense in depth and the Golden Rule." }
    ]
  },
  {
    section: "Integrations",
    pages: [
      { slug: "zerion-stack", title: "The Zerion stack", description: "CLI, MCP, and x402 — the Zerion building blocks." },
      { slug: "discord-bot", title: "Discord Bot", description: "Full guide to the Trinity commands." }
    ]
  },
  {
    section: "Reference",
    pages: [
      { slug: "forking", title: "Forking guide", description: "Common fork patterns and stable contracts." },
      { slug: "api-reference", title: "API reference", description: "Environment variables and technical patches." },
      { slug: "faq", title: "Troubleshooting & FAQ", description: "Common issues and hackathon tips." }
    ]
  }
];

const DOCS_FLAT = DOCS_NAV.flatMap(s => s.pages);

function findDocBySlug(slug) {
  return DOCS_FLAT.find(p => p.slug === slug) || null;
}

function getAdjacentDocs(slug) {
  const i = DOCS_FLAT.findIndex(p => p.slug === slug);
  if (i < 0) return { prev: null, next: null };
  return {
    prev: i > 0 ? DOCS_FLAT[i - 1] : null,
    next: i < DOCS_FLAT.length - 1 ? DOCS_FLAT[i + 1] : null
  };
}

function getDoc(slug) {
  return DOCS_CONTENT[slug] ? DOCS_CONTENT[slug]() : null;
}

function textOf(node) {
  if (node == null || typeof node === "boolean") return "";
  if (typeof node === "string" || typeof node === "number") return String(node);
  if (Array.isArray(node)) return node.map(textOf).join("");
  if (node.props && node.props.children != null) return textOf(node.props.children);
  return "";
}

function slugify(text) {
  return String(text).toLowerCase().replace(/[^\w\s-]/g, "").trim().replace(/\s+/g, "-");
}

// ----- JSX helpers -----
function P({ children }) { return <p>{children}</p>; }
function H2({ children, id }) { return <h2 id={id || slugify(textOf(children))}>{children}</h2>; }
function H3({ children, id }) { return <h3 id={id || slugify(textOf(children))}>{children}</h3>; }
function Code({ children }) { return <code>{children}</code>; }
function Quote({ children }) { return <blockquote>{children}</blockquote>; }
function UL({ children }) { return <ul>{children}</ul>; }
function OL({ children }) { return <ol>{children}</ol>; }
function LI({ children }) { return <li>{children}</li>; }
function HR() { return <hr />; }

function Pre({ children }) {
  const ref = useRef(null);
  const [copied, setCopied] = useState(false);
  const onCopy = () => {
    if (!ref.current) return;
    const text = ref.current.innerText;
    if (navigator.clipboard && navigator.clipboard.writeText) {
      navigator.clipboard.writeText(text);
    }
    setCopied(true);
    setTimeout(() => setCopied(false), 1400);
  };
  return (
    <pre>
      <button className="copy-btn" onClick={onCopy}>{copied ? "✓ copied" : "copy"}</button>
      <code ref={ref}>{children}</code>
    </pre>
  );
}

function Table({ headers, rows }) {
  return (
    <table>
      <thead>
        <tr>{headers.map((h, i) => <th key={i}>{h}</th>)}</tr>
      </thead>
      <tbody>
        {rows.map((r, i) => (
          <tr key={i}>{r.map((c, j) => <td key={j}>{c}</td>)}</tr>
        ))}
      </tbody>
    </table>
  );
}

// ----- Page content -----
const DOCS_CONTENT = {
  overview: () => (
    <>
      <h1>OmnisysX — Multi-Agent DeFi Pipeline</h1>
      <P>
        OmnisysX is an autonomous DeFi pipeline orchestrated by a <strong>Trinity of specialized agents</strong> —
        <strong> Observer</strong>, <strong>Task Manager</strong>, and <strong>Auditor</strong> —
        plus a deterministic <strong>Executor</strong>. It runs a hardened six-stage flow, using the full Zerion stack.
      </P>

      <H2>The Trinity Architecture</H2>
      <UL>
        <LI><strong>Observer Agent:</strong> The "Eyes". Scans wallet data, DeFi positions, and gas prices via Zerion CLI/API.</LI>
        <LI><strong>Task Manager:</strong> The "Brain". Analyzes opportunities and drafts intents (TIS) based on persona goals.</LI>
        <LI><strong>Auditor:</strong> The "Shield". Independently verifies every intent against the Golden Rule and security policies.</LI>
      </UL>

      <H2>TL;DR Setup</H2>
      <Pre>{`git clone https://github.com/cyberalt3/omnisysx
cd omnisysx
npm install
# Configure your .env then:
node agent/agent.mjs`}</Pre>

      <H2>The Golden Rule</H2>
      <Quote>The agent must never let ETH balance drop below 0.002.</Quote>
      <P>
        This invariant is checked at every single layer. If any operation would leave the wallet with less than 0.002 ETH, the pipeline halts immediately.
      </P>

      <H2>Stack at a glance</H2>
      <Table
        headers={["Layer", "Tech"]}
        rows={[
          ["On-chain perception", <><Code>Zerion CLI</Code> (Patched) + REST API</>],
          ["Agent connectivity", "Zerion API Tokens"],
          ["Autonomous execution", "Zerion Swap Infrastructure"],
          ["Orchestration LLM", "Claude 3.5 Haiku"],
          ["User Interface", "Discord Bot + Static Web Dashboard"],
          ["Runtime", "Node.js 22+"]
        ]}
      />
    </>
  ),

  setup: () => (
    <>
      <h1>Setup</h1>
      <P>Follow these steps to get OmnisysX running on your machine.</P>

      <H2>Prerequisites</H2>
      <UL>
        <LI>Node.js 22+</LI>
        <LI>npm 10+</LI>
        <LI>Zerion API Key (<Code>zk_...</Code>)</LI>
        <LI>OpenRouter/Anthropic API Key</LI>
      </UL>

      <H2>1. Clone and Install</H2>
      <Pre>{`git clone https://github.com/cyberalt3/omnisysx
cd omnisysx
npm install
npm install -g zerion-cli`}</Pre>

      <H2>2. Configuration</H2>
      <P>Create a <Code>.env</Code> file in the root:</P>
      <Pre>{`ZERION_API_KEY=zk_dev_...
OPENROUTER_API_KEY=sk-or-v1-...
AGENT_WALLET_ADDRESS=0x...
ZERION_PASSPHRASE=your_password
FORCE_DRY_RUN=true
DISCORD_TOKEN=your_bot_token`}</Pre>

      <H2>3. Zerion CLI Authentication</H2>
      <Pre>{`npx -y zerion-cli init -y --browser`}</Pre>
      <P>This links your local environment to your Zerion profile securely.</P>
    </>
  ),

  running: () => (
    <>
      <h1>Running it</h1>
      <P>OmnisysX runs in two primary parts: the Agent Pipeline and the Discord Bot interface.</P>

      <H2>1. The Agent (Backend)</H2>
      <Pre>{`node agent/agent.mjs`}</Pre>
      <P>This starts the orchestrator server. It listens for requests and manages the Trinity agents.</P>

      <H2>2. The Discord Bot (Interface)</H2>
      <Pre>{`node bot/bot.mjs`}</Pre>
      <P>This connects the Trinity agents to your Discord server, allowing you to trigger runs and view reports in chat.</P>

      <H2>3. The Web Dashboard</H2>
      <P>Simply open the deployed Vercel link or <Code>web/index.html</Code> locally. It connects to the agent via SSE (Server-Sent Events) to show the live pipeline status.</P>
    </>
  ),

  architecture: () => (
    <>
      <h1>Architecture</h1>
      <P>A clean, modular design focused on transparency and security.</P>

      <H2>Data Flow Diagram</H2>
      <Pre>{`[ Observer ]  ->  [ Task Manager ]  ->  [ Auditor ]  ->  [ Executor ]
     |                  |                   |                 |
(Wallet Data)    (Draft Intent/TIS)   (Policy Decision)   (On-chain TX)`}</Pre>

      <H2>Security Layers</H2>
      <OL>
        <LI><strong>CLI Hardened Patch:</strong> Custom injection of missing parameters in the Zerion CLI output.</LI>
        <LI><strong>Golden Rule:</strong> 0.002 ETH minimum reserve forced by the Auditor.</LI>
        <LI><strong>Human-in-the-Loop:</strong> Discord approval required for high-value or high-slippage trades.</LI>
      </OL>
    </>
  ),

  agents: () => (
    <>
      <h1>The Trinity</h1>
      <P>OmnisysX splits decision-making across three distinct personas.</P>

      <H2>Observer Agent</H2>
      <P>Gathers "Ground Truth". It doesn't use an LLM for data collection to ensure 100% accuracy from the Zerion API.</P>

      <H2>Task Manager Agent</H2>
      <P>Uses Claude 3.5 Haiku to interpret wallet state. It looks for rebalancing needs, yield opportunities, or cross-chain bridges.</P>

      <H2>Auditor Agent</H2>
      <P>The security specialist. It runs a separate prompt focused entirely on "What could go wrong?". It is the only agent that can VETO a Task Manager's intent.</P>

      <H2>Executor</H2>
      <P>A deterministic script that pipes the finalized, audited intent into the Zerion Swap infrastructure for execution.</P>
    </>
  ),

  pipeline: () => (
    <>
      <h1>Pipeline</h1>
      <P>Every run follows a strict 6-stage lifecycle:</P>
      <OL>
        <LI><strong>OBSERVE:</strong> Fetch wallet balance and positions.</LI>
        <LI><strong>REASON:</strong> Analyze if any action is needed.</LI>
        <LI><strong>PLAN:</strong> Create a structured Task Intent Spec (TIS).</LI>
        <LI><strong>AUTHORIZE:</strong> Auditor reviews the TIS and issues a PDR.</LI>
        <LI><strong>EXECUTE:</strong> Broadcast the transaction to the network.</LI>
        <LI><strong>VERIFY:</strong> Wait for inclusion and log the result.</LI>
      </OL>
    </>
  ),

  security: () => (
    <>
      <h1>Security Model</h1>
      <H2>1. Golden Rule (Invariant)</H2>
      <P>The core invariant of OmnisysX: <strong>Reserve 0.002 ETH at all times.</strong> This ensures the wallet never becomes "stuck" without gas for future recovery.</P>

      <H2>2. Defense in Depth</H2>
      <UL>
        <LI><strong>Pre-flight check:</strong> Executor verifies the Auditor's signature.</LI>
        <LI><strong>Zerion CLI Patch:</strong> Fixes a known bug where target addresses could be lost during multi-hop swaps.</LI>
        <LI><strong>Dry-run Mode:</strong> Use <Code>FORCE_DRY_RUN=true</Code> to simulate everything without spending real funds.</LI>
      </UL>
    </>
  ),

  "discord-bot": () => (
    <>
      <h1>Discord Bot Guide</h1>
      <P>The primary way to interact with the Trinity agents.</P>

      <H2>Available Commands</H2>
      <Table
        headers={["Command", "Description"]}
        rows={[
          ["/run [address]", "Trigger the full 6-stage pipeline."],
          ["/swap", "Execute a same-chain token swap via Zerion."],
          ["/bridge", "Execute a cross-chain bridge via LI.FI / Zerion."],
          ["/portfolio", "Show a beautiful snapshot of the wallet positions."],
          ["/policy", "Show the active agent token policy and gas reserves."],
          ["/status", "Check the status of the last pipeline execution."],
          ["/watch [address] [name]", "Add a wallet to the server watchlist."],
          ["/watchlist", "Show all wallets being monitored."],
          ["/help", "List all available commands and their usage."]
        ]}
      />

      <H2>Trinity Reports</H2>
      <P>After every run, the bot posts a "Trinity Verification Report" which includes the Reasoning (Task Manager) and the Audit Log (Auditor) side-by-side.</P>
    </>
  ),

  "zerion-stack": () => (
    <>
      <h1>The Zerion Stack</h1>
      <P>OmnisysX utilizes Zerion's infrastructure for all on-chain operations.</P>

      <H2>1. Zerion CLI</H2>
      <P>We use the CLI for its robust portfolio normalization. OmnisysX includes a custom wrapper that adds missing safety parameters before execution.</P>

      <H2>2. Zerion API (REST)</H2>
      <P>Used for real-time gas monitoring and historical transaction auditing.</P>

      <H2>3. Zerion Swap</H2>
      <P>The core engine for routing trades with minimal slippage across 10+ chains.</P>
    </>
  ),

  forking: () => (
    <>
      <h1>Forking Guide</h1>
      <P>OmnisysX is designed to be easily modified for different strategies.</P>

      <H2>Adding a new Strategy</H2>
      <P>Simply modify the <Code>agent/agent.mjs</Code> logic to inject new system prompts into the Task Manager. You can define specific "Personas" (e.g., Yield Farmer, Stablecoin Maximizer) without changing the core pipeline.</P>

      <H2>Custom Auditors</H2>
      <P>You can add your own validation rules in the Auditor stage to enforce specific risk parameters (e.g., "Never trade more than 10% of total portfolio value").</P>
    </>
  ),

  "api-reference": () => (
    <>
      <h1>API Reference</h1>
      <H2>Environment Variables</H2>
      <Table
        headers={["Variable", "Default", "Description"]}
        rows={[
          ["ZERION_API_KEY", "-", "Your Zerion developer key."],
          ["OPENROUTER_API_KEY", "-", "LLM provider key."],
          ["AGENT_WALLET_ADDRESS", "-", "The public address to monitor."],
          ["FORCE_DRY_RUN", "true", "Safety switch for execution."],
          ["MIN_ETH_RESERVE", "0.002", "Golden Rule threshold."]
        ]}
      />
    </>
  ),

  faq: () => (
    <>
      <h1>Troubleshooting & FAQ</h1>

      <H3>The screen is black when I open index.html</H3>
      <P>Browsers block JSX loading from local files. You must run a server (like Vercel) or use the live link.</P>

      <H3>Pipeline halts with "CRITICAL gas alert"</H3>
      <P>Your wallet has less than 0.002 ETH. This is the Golden Rule. Add some ETH to continue.</P>

      <H3>Zerion CLI Authentication failed</H3>
      <P>Run <Code>npx -y zerion-cli init -y --browser</Code> to re-authenticate your machine.</P>
    </>
  )
};

Object.assign(window, {
  DOCS_NAV, DOCS_FLAT, DOCS_CONTENT,
  findDocBySlug, getAdjacentDocs, getDoc, textOf, slugify,
  P, H2, H3, Code, Pre, Quote, UL, OL, LI, HR, Table
});
