/* Endpoint catalog — mirrors the live Artemis City API surface
   (see `api/index.ts` + `api/v1/*` in the AgenticGovernance-ArtemisCity repo).

   All routes are mounted under `/api/v1/` except `/health` which is also
   exposed unversioned at the root. Auth = Bearer JWT (`authMiddleware`)
   on every group except health. */

const ENDPOINT_GROUPS = [
  {
    name: 'Health',
    items: [
      {
        id: 'health-root',
        method: 'GET', path: '/health',
        desc: 'Basic liveness ping. No auth.',
        params: [],
        sample: () => ({
          status: 'ok',
          timestamp: new Date().toISOString(),
          service: 'Artemis City API',
          version: '1.0.0',
        }),
      },
      {
        id: 'health-detailed',
        method: 'GET', path: '/api/v1/health/detailed',
        desc: 'Component-level health: api, mcp, vault, agents.',
        params: [],
        sample: () => ({
          status: 'healthy',
          timestamp: new Date().toISOString(),
          checks: { api: 'ok', mcp: 'ok', vault: 'ok', agents: 'ok' },
          uptime: 14233.42,
        }),
      },
      {
        id: 'health-ready',
        method: 'GET', path: '/api/v1/health/ready',
        desc: 'Readiness probe for orchestration.',
        params: [],
        sample: () => ({ ready: true }),
      },
    ],
  },
  {
    name: 'Agents',
    items: [
      {
        id: 'agents-list',
        method: 'GET', path: '/api/v1/agents',
        desc: 'List all registered agents and their roles (from `agent_router.yaml`).',
        params: [
          { name: 'keyword', type: 'string', desc: 'Filter agents whose router keywords include this term.' },
        ],
        sample: () => ({
          agents: [
            { id: 'artemis',  role: 'Mayor protocol, governance',          keywords: ['governance', 'policy', 'audit', 'dispute', 'review'], trust: 0.94, status: 'idle' },
            { id: 'planner',  role: 'Architect, planning and contextual',  keywords: ['plan', 'roadmap', 'blueprint', 'schedule', 'help'],    trust: 0.88, status: 'idle' },
            { id: 'pack_rat', role: 'Courier role, safe transfer',          keywords: ['transfer', 'send', 'receive', 'courier', 'secure'],   trust: 0.91, status: 'idle' },
            { id: 'daemon',   role: 'System anchor, memory interface',      keywords: ['memory', 'system', 'config', 'status', 'health'],     trust: 0.97, status: 'running' },
          ],
        }),
      },
      {
        id: 'agents-execute',
        method: 'POST', path: '/api/v1/agents/{agent_id}/execute',
        desc: 'Execute a task on a specific agent. Returns the agent\'s structured perform_task result.',
        params: [
          { name: 'agent_id', type: 'string', required: true, default: 'artemis', desc: 'Target agent id.' },
          { name: 'title',    type: 'string', required: true, default: 'Review Q1 governance audit',  desc: 'Task title (becomes synthesis focus).' },
          { name: 'context',  type: 'string', required: true, multi: true, default: 'Audit log: 318 events in 24h, 0 violations. Trust decay deltas attached.', desc: 'Task context blob the agent reflects on.' },
          { name: 'atp_mode', type: 'enum:BUILD,REVIEW,ORGANIZE,CAPTURE,SYNTHESIZE,COMMIT', default: 'REVIEW' },
          { name: 'request_feedback', type: 'enum:true,false', default: 'true' },
        ],
        sample: (p) => ({
          status: 'success',
          summary: `Artemis reviewed '${p.title}'. Initial themes: governance, trust-decay, audit-coverage.`,
          narrative: 'Across the last 24h cycle, the kernel logged 318 audits with 0 violations. Trust decay registered against pack_rat after a single timed-out transfer; reflection recommends a re-key cycle next term.',
          semantic_tags: ['governance', 'trust', 'audit', 'kernel'],
          concepts: ['trust-decay', 'audit-coverage', 'mayor-protocol'],
          persona_context: { tone: 'engineering-serious', mode: p.atp_mode || 'REVIEW' },
          recent_context: ['Q1 OKR doc · last reviewed 2d', 'Kernel session #a4f3-elect-12'],
        }),
      },
      {
        id: 'agents-status',
        method: 'GET', path: '/api/v1/agents/{agent_id}/status',
        desc: 'Live status for a single agent: current task, last run, trust score.',
        params: [
          { name: 'agent_id', type: 'string', required: true, default: 'daemon' },
        ],
        sample: (p) => ({
          id: p.agent_id,
          status: 'running',
          current_task: 'memory bus heartbeat · 2.1s',
          last_run_s: 2,
          trust: 0.97,
          capabilities: ['system_management', 'memory_interface'],
        }),
      },
    ],
  },
  {
    name: 'Memory',
    items: [
      {
        id: 'memory-search',
        method: 'GET', path: '/api/v1/memory/search',
        desc: 'Hybrid search across the user\'s memory bus (Obsidian vault + Notion + vector store).',
        params: [
          { name: 'q',      type: 'string', required: true, default: 'hebbian routing', desc: 'Query string.' },
          { name: 'source', type: 'enum:obsidian,notion,vector,all', default: 'all' },
          { name: 'limit',  type: 'number', default: 10 },
        ],
        sample: (p) => ({
          query: p.q,
          source: p.source || 'all',
          hits: [
            { source: 'obsidian', path: '/kb/Hebbian routing benchmarks.md', score: 0.91, snippet: 'Across 12k runs, adaptive routing improved Sharpe-of-quality by 1.4...' },
            { source: 'notion',   page: 'ATP Protocol Spec',                  score: 0.82, snippet: '#Mode: Build · #ActionType: Execute · #TargetZone: agents/' },
            { source: 'vector',   id: '0x7d3f',                                score: 0.78, snippet: 'Cluster topic: trust-decay model in agent registry' },
          ],
        }),
      },
      {
        id: 'memory-write',
        method: 'POST', path: '/api/v1/memory/write',
        desc: 'Persist a note to the user vault (routed through pack_rat; governance-checked).',
        params: [
          { name: 'path',    type: 'string',  required: true, default: '/kb/notes/scratch.md' },
          { name: 'content', type: 'string',  required: true, multi: true, default: '## Scratch\n\nKernel routes the task, not the LLM.' },
          { name: 'source',  type: 'enum:obsidian,notion', default: 'obsidian' },
        ],
        sample: (p) => ({
          ok: true,
          path: p.path,
          source: p.source || 'obsidian',
          bytes: (p.content || '').length,
          courier: 'pack_rat',
          audit_id: 'audit_' + Math.random().toString(16).slice(2, 8),
        }),
      },
    ],
  },
  {
    name: 'ATP',
    items: [
      {
        id: 'atp-parse',
        method: 'POST', path: '/api/v1/atp/parse',
        desc: 'Parse a #-prefixed ATP text block into a typed ATPMessage (mode / context / priority / action_type / target_zone).',
        params: [
          { name: 'text', type: 'string', required: true, multi: true, default: '#Mode: Build\n#Context: Add semantic tagging to research agent\n#Priority: High\n#ActionType: Execute\n#TargetZone: agents/\n#SpecialNotes: Validate against existing concept graph' },
        ],
        sample: (p) => ({
          message: {
            mode: 'BUILD',
            context: 'Add semantic tagging to research agent',
            priority: 'HIGH',
            action_type: 'EXECUTE',
            target_zone: 'agents/',
            special_notes: 'Validate against existing concept graph',
            content: p.text || '',
          },
          parsed_at: new Date().toISOString(),
        }),
      },
      {
        id: 'atp-validate',
        method: 'POST', path: '/api/v1/atp/validate',
        desc: 'Run an ATPMessage through the validator. Rejects missing context or empty content.',
        params: [
          { name: 'mode',          type: 'enum:BUILD,REVIEW,ORGANIZE,CAPTURE,SYNTHESIZE,COMMIT', required: true, default: 'BUILD' },
          { name: 'context',       type: 'string', required: true, default: 'Add semantic tagging to research agent' },
          { name: 'priority',      type: 'enum:CRITICAL,HIGH,NORMAL,LOW', default: 'NORMAL' },
          { name: 'action_type',   type: 'enum:SUMMARIZE,SCAFFOLD,EXECUTE,REFLECT', default: 'EXECUTE' },
          { name: 'target_zone',   type: 'string', default: 'agents/' },
          { name: 'special_notes', type: 'string', default: '' },
        ],
        sample: (p) => ({
          is_valid: !!(p.context && p.mode),
          error: !p.context ? 'Context is required' : null,
          message: {
            mode: p.mode, context: p.context, priority: p.priority,
            action_type: p.action_type, target_zone: p.target_zone, special_notes: p.special_notes,
          },
        }),
      },
      {
        id: 'atp-dispatch',
        method: 'POST', path: '/api/v1/atp/dispatch',
        desc: 'Route a sealed ATP message to the kernel; returns the elected agent + receipt.',
        params: [
          { name: 'mode',        type: 'enum:BUILD,REVIEW,ORGANIZE,CAPTURE,SYNTHESIZE,COMMIT', required: true, default: 'SYNTHESIZE' },
          { name: 'context',     type: 'string', required: true, default: 'Compress Q1 desk notes into briefing' },
          { name: 'target_zone', type: 'string', default: 'kb/briefings/' },
        ],
        sample: (p) => ({
          envelope_id: 'env_' + Math.random().toString(16).slice(2, 10),
          routed_to: p.mode === 'SYNTHESIZE' ? 'planner' : p.mode === 'CAPTURE' ? 'pack_rat' : 'artemis',
          weight: 0.91,
          alternates: [{ agent: 'artemis', weight: 0.74 }, { agent: 'daemon', weight: 0.58 }],
          receipt: 'rcpt_' + Math.random().toString(16).slice(2, 6),
          ack_in_ms: 18,
        }),
      },
    ],
  },
  {
    name: 'Trust',
    items: [
      {
        id: 'trust-registry',
        method: 'GET', path: '/api/v1/trust',
        desc: 'Current trust scores across the registry, with decay deltas from the last cycle.',
        params: [],
        sample: () => ({
          term: 12,
          decay_per_failure: 0.02,
          scores: [
            { agent: 'artemis',  trust: 0.94, delta_24h: +0.01 },
            { agent: 'daemon',   trust: 0.97, delta_24h:  0.00 },
            { agent: 'pack_rat', trust: 0.91, delta_24h: -0.02 },
            { agent: 'planner',  trust: 0.88, delta_24h: +0.02 },
          ],
        }),
      },
      {
        id: 'trust-adjust',
        method: 'POST', path: '/api/v1/trust/{agent_id}/adjust',
        desc: 'Apply a trust delta (e.g. on failed transfer or successful audit). Requires `governance:write`.',
        params: [
          { name: 'agent_id', type: 'string', required: true, default: 'pack_rat' },
          { name: 'delta',    type: 'number', required: true, default: -0.02, desc: 'Signed delta to apply.' },
          { name: 'reason',   type: 'enum:failed_transfer,audit_pass,policy_violation,manual', default: 'failed_transfer' },
        ],
        sample: (p) => ({
          agent: p.agent_id,
          trust_before: 0.93,
          trust_after: 0.93 + (p.delta || 0),
          reason: p.reason,
          audit_id: 'audit_' + Math.random().toString(16).slice(2, 8),
        }),
      },
    ],
  },
  {
    name: 'LLM',
    items: [
      {
        id: 'llm-complete',
        method: 'POST', path: '/api/v1/llm/complete',
        desc: 'Direct LLM completion (bypasses kernel routing). Honors per-user rate limits.',
        params: [
          { name: 'prompt', type: 'string', required: true, multi: true, default: 'Summarize the kernel-first philosophy in three sentences.' },
          { name: 'model',  type: 'enum:claude-haiku-4-5,claude-sonnet-4-5,local-exo', default: 'claude-haiku-4-5' },
          { name: 'max_tokens', type: 'number', default: 512 },
        ],
        sample: (p) => ({
          completion: 'The kernel decides routing, not the LLM. Governance, memory, and trust are first-class — the model is a callable, not the captain. This is what makes agents production-ready.',
          model: p.model || 'claude-haiku-4-5',
          usage: { input_tokens: 24, output_tokens: 48 },
          latency_ms: 412,
        }),
      },
    ],
  },
];

const ENDPOINTS = ENDPOINT_GROUPS.flatMap((g) => g.items.map((e) => ({ ...e, group: g.name })));

Object.assign(window, { ENDPOINT_GROUPS, ENDPOINTS });
