/**
 * Agent Templates Library
 *
 * Defines agent archetypes that can be used as starting points for new deployments.
 * Each template provides a full OpenClaw agent config structure that
 * can be customized before creating an agent.
 */

export interface AgentToolsConfig {
  allow: string[]
  deny: string[]
}

export interface AgentSandboxConfig {
  mode: 'all' | 'non-main'
  workspaceAccess: 'rw' | 'ro' | 'none'
  scope: 'agent'
  docker?: {
    network: 'none' | 'bridge'
  }
}

export interface AgentModelConfig {
  primary: string
  fallbacks: string[]
}

export interface AgentIdentityConfig {
  name: string
  theme: string
  emoji: string
}

export interface AgentSubagentsConfig {
  allowAgents?: string[]
  model?: string
}

export interface AgentMemorySearchConfig {
  sources: string[]
  experimental?: {
    sessionMemory?: boolean
  }
}

export interface OpenClawAgentConfig {
  id: string
  name?: string
  workspace?: string
  agentDir?: string
  model: AgentModelConfig
  identity: AgentIdentityConfig
  subagents?: AgentSubagentsConfig
  sandbox: AgentSandboxConfig
  tools: AgentToolsConfig
  memorySearch?: AgentMemorySearchConfig
}

export interface AgentTemplate {
  type: string
  label: string
  description: string
  emoji: string
  modelTier: 'opus' | 'sonnet' | 'haiku'
  toolCount: number
  config: Omit<OpenClawAgentConfig, 'id' | 'workspace' | 'agentDir'>
}

import { getPluginToolProviders } from '@/lib/plugins'

// Tool groups for template composition
const TOOL_GROUPS: Record<string, readonly string[]> = {
  coding: ['read', 'write', 'edit', 'apply_patch', 'exec', 'bash', 'process'],
  browser: ['browser', 'web'],
  memory: ['memory_search', 'memory_get'],
  session: ['agents_list', 'sessions_list', 'sessions_history', 'sessions_send', 'sessions_spawn', 'session_status'],
  subagent: ['subagents', 'lobster', 'llm-task'],
  thinking: ['thinking', 'reactions', 'skills'],
  readonly: ['read', 'memory_search', 'memory_get', 'agents_list'],
}

/** Merge base TOOL_GROUPS with tools from plugin tool providers */
export function getEffectiveToolGroups(): Record<string, readonly string[]> {
  const merged: Record<string, string[]> = {}
  for (const [key, tools] of Object.entries(TOOL_GROUPS)) {
    merged[key] = [...tools]
  }
  for (const provider of getPluginToolProviders()) {
    const groupId = provider.id
    if (merged[groupId]) {
      // Append new tools that aren't already in the group
      const existing = new Set(merged[groupId])
      for (const tool of provider.tools) {
        if (!existing.has(tool)) merged[groupId].push(tool)
      }
    } else {
      merged[groupId] = [...provider.tools]
    }
  }
  return merged
}

const COMMON_DENY = ['clawhub', 'cron', 'gateway', 'nodes']

const SONNET_FALLBACKS = [
  'openrouter/anthropic/claude-sonnet-4',
  'moonshot/kimi-k2-thinking',
  'openrouter/moonshotai/kimi-k2.5',
  'nvidia/moonshotai/kimi-k2-instruct',
  'openai/codex-mini-latest',
  'ollama/qwen2.5-coder:14b',
]

const OPUS_FALLBACKS = [
  'anthropic/claude-sonnet-4-20250514',
  'moonshot/kimi-k2-thinking',
  'nvidia/moonshotai/kimi-k2-instruct',
  'openrouter/moonshotai/kimi-k2.5',
  'openai/codex-mini-latest',
]

const HAIKU_FALLBACKS = [
  'anthropic/claude-sonnet-4-20250514',
  'ollama/qwen2.5-coder:14b',
  'openai/codex-mini-latest',
]

export const AGENT_TEMPLATES: AgentTemplate[] = [
  {
    type: 'orchestrator',
    label: 'Orchestrator',
    description: 'Primary coordinator with full tool access. Routes tasks to specialist agents and manages workflows.',
    emoji: '\ud83e\udded',
    modelTier: 'opus',
    toolCount: 23,
    config: {
      model: {
        primary: 'anthropic/claude-opus-4-5',
        fallbacks: OPUS_FALLBACKS,
      },
      identity: {
        name: '',
        theme: 'operator strategist',
        emoji: '\ud83e\udded',
      },
      subagents: {
        allowAgents: [],
      },
      sandbox: {
        mode: 'non-main',
        workspaceAccess: 'rw',
        scope: 'agent',
      },
      tools: {
        allow: [
          ...TOOL_GROUPS.coding,
          ...TOOL_GROUPS.browser,
          ...TOOL_GROUPS.memory,
          ...TOOL_GROUPS.session,
          ...TOOL_GROUPS.subagent,
          ...TOOL_GROUPS.thinking,
        ],
        deny: COMMON_DENY,
      },
      memorySearch: {
        sources: ['memory', 'sessions'],
        experimental: { sessionMemory: true },
      },
    },
  },
  {
    type: 'developer',
    label: 'Developer',
    description: 'Full-stack builder with Docker bridge networking, exec/write access, and subagent spawning.',
    emoji: '\ud83d\udee0\ufe0f',
    modelTier: 'sonnet',
    toolCount: 21,
    config: {
      model: {
        primary: 'anthropic/claude-sonnet-4-20250514',
        fallbacks: SONNET_FALLBACKS,
      },
      identity: {
        name: '',
        theme: 'builder engineer',
        emoji: '\ud83d\udee0\ufe0f',
      },
      subagents: {
        allowAgents: [],
        model: 'openai/codex-mini-latest',
      },
      sandbox: {
        mode: 'all',
        workspaceAccess: 'rw',
        scope: 'agent',
        docker: { network: 'bridge' },
      },
      tools: {
        allow: [
          ...TOOL_GROUPS.coding,
          ...TOOL_GROUPS.browser,
          ...TOOL_GROUPS.memory,
          'agents_list', 'sessions_spawn', 'sessions_history', 'session_status',
          ...TOOL_GROUPS.subagent,
          ...TOOL_GROUPS.thinking,
        ],
        deny: [...COMMON_DENY, 'sessions_send'],
      },
      memorySearch: {
        sources: ['memory', 'sessions'],
        experimental: { sessionMemory: true },
      },
    },
  },
  {
    type: 'specialist-dev',
    label: 'Specialist Dev',
    description: 'Focused developer for specific domains (frontend, backend, blockchain). Docker bridge + write access.',
    emoji: '\u2699\ufe0f',
    modelTier: 'sonnet',
    toolCount: 15,
    config: {
      model: {
        primary: 'anthropic/claude-sonnet-4-20250514',
        fallbacks: SONNET_FALLBACKS,
      },
      identity: {
        name: '',
        theme: 'specialist developer',
        emoji: '\u2699\ufe0f',
      },
      subagents: {
        model: 'openai/codex-mini-latest',
      },
      sandbox: {
        mode: 'all',
        workspaceAccess: 'rw',
        scope: 'agent',
        docker: { network: 'bridge' },
      },
      tools: {
        allow: [
          ...TOOL_GROUPS.coding,
          ...TOOL_GROUPS.memory,
          'agents_list', 'sessions_spawn', 'session_status',
          'subagents', 'llm-task',
          'thinking', 'reactions', 'skills',
        ],
        deny: [...COMMON_DENY, 'sessions_send', 'browser', 'web', 'lobster'],
      },
      memorySearch: {
        sources: ['memory', 'sessions'],
        experimental: { sessionMemory: true },
      },
    },
  },
  {
    type: 'reviewer',
    label: 'Reviewer / QA',
    description: 'Read-only access for code review, quality gates, and auditing. Lightweight Haiku model.',
    emoji: '\ud83d\udd2c',
    modelTier: 'haiku',
    toolCount: 7,
    config: {
      model: {
        primary: 'anthropic/claude-haiku-4-5',
        fallbacks: HAIKU_FALLBACKS,
      },
      identity: {
        name: '',
        theme: 'quality reviewer',
        emoji: '\ud83d\udd2c',
      },
      sandbox: {
        mode: 'all',
        workspaceAccess: 'ro',
        scope: 'agent',
      },
      tools: {
        allow: [
          'read', 'memory_search', 'memory_get',
          'agents_list', 'thinking', 'reactions', 'skills',
        ],
        deny: [
          ...COMMON_DENY,
          'write', 'edit', 'apply_patch', 'exec', 'bash', 'process',
          'browser', 'web', 'sessions_send', 'sessions_spawn', 'lobster',
        ],
      },
      memorySearch: {
        sources: ['memory'],
      },
    },
  },
  {
    type: 'researcher',
    label: 'Researcher',
    description: 'Browser and web access for research tasks. No workspace or code execution.',
    emoji: '\ud83d\udd0d',
    modelTier: 'sonnet',
    toolCount: 8,
    config: {
      model: {
        primary: 'anthropic/claude-sonnet-4-20250514',
        fallbacks: SONNET_FALLBACKS,
      },
      identity: {
        name: '',
        theme: 'research analyst',
        emoji: '\ud83d\udd0d',
      },
      sandbox: {
        mode: 'all',
        workspaceAccess: 'none',
        scope: 'agent',
      },
      tools: {
        allow: [
          'browser', 'web',
          'memory_search', 'memory_get',
          'agents_list', 'thinking', 'reactions', 'skills',
        ],
        deny: [
          ...COMMON_DENY,
          'read', 'write', 'edit', 'apply_patch', 'exec', 'bash', 'process',
          'sessions_send', 'sessions_spawn', 'lobster',
        ],
      },
      memorySearch: {
        sources: ['memory', 'sessions'],
      },
    },
  },
  {
    type: 'content-creator',
    label: 'Content Creator',
    description: 'Write and edit access for content generation. No code execution or browser.',
    emoji: '\u270f\ufe0f',
    modelTier: 'haiku',
    toolCount: 9,
    config: {
      model: {
        primary: 'anthropic/claude-haiku-4-5',
        fallbacks: HAIKU_FALLBACKS,
      },
      identity: {
        name: '',
        theme: 'content creator',
        emoji: '\u270f\ufe0f',
      },
      sandbox: {
        mode: 'all',
        workspaceAccess: 'none',
        scope: 'agent',
      },
      tools: {
        allow: [
          'write', 'edit',
          'memory_search', 'memory_get',
          'agents_list',
          'thinking', 'reactions', 'skills',
          'web',
        ],
        deny: [
          ...COMMON_DENY,
          'read', 'apply_patch', 'exec', 'bash', 'process',
          'browser', 'sessions_send', 'sessions_spawn', 'lobster',
          'subagents', 'llm-task',
        ],
      },
      memorySearch: {
        sources: ['memory'],
      },
    },
  },
  {
    type: 'security-auditor',
    label: 'Security Auditor',
    description: 'Read-only workspace with bash for security scanning. No write access to prevent tampering.',
    emoji: '\ud83d\udee1\ufe0f',
    modelTier: 'sonnet',
    toolCount: 10,
    config: {
      model: {
        primary: 'anthropic/claude-sonnet-4-20250514',
        fallbacks: SONNET_FALLBACKS,
      },
      identity: {
        name: '',
        theme: 'security auditor',
        emoji: '\ud83d\udee1\ufe0f',
      },
      sandbox: {
        mode: 'all',
        workspaceAccess: 'ro',
        scope: 'agent',
      },
      tools: {
        allow: [
          'read', 'exec', 'bash',
          'memory_search', 'memory_get',
          'agents_list',
          'thinking', 'reactions', 'skills',
          'web',
        ],
        deny: [
          ...COMMON_DENY,
          'write', 'edit', 'apply_patch', 'process',
          'browser', 'sessions_send', 'sessions_spawn', 'lobster',
          'subagents', 'llm-task',
        ],
      },
      memorySearch: {
        sources: ['memory'],
      },
    },
  },
]

/** Get a template by type name */
export function getTemplate(type: string): AgentTemplate | undefined {
  return AGENT_TEMPLATES.find(t => t.type === type)
}

/** Build a full OpenClaw agent config from a template + overrides */
export function buildAgentConfig(
  template: AgentTemplate,
  overrides: {
    id: string
    name: string
    workspace?: string
    agentDir?: string
    emoji?: string
    theme?: string
    model?: string
    workspaceAccess?: 'rw' | 'ro' | 'none'
    sandboxMode?: 'all' | 'non-main'
    dockerNetwork?: 'none' | 'bridge'
    subagentAllowAgents?: string[]
  }
): OpenClawAgentConfig {
  const config = structuredClone(template.config)

  config.identity.name = overrides.name
  if (overrides.emoji) config.identity.emoji = overrides.emoji
  if (overrides.theme) config.identity.theme = overrides.theme
  if (overrides.model) config.model.primary = overrides.model
  if (overrides.workspaceAccess) config.sandbox.workspaceAccess = overrides.workspaceAccess
  if (overrides.sandboxMode) config.sandbox.mode = overrides.sandboxMode

  if (overrides.dockerNetwork) {
    config.sandbox.docker = { network: overrides.dockerNetwork }
  }

  if (overrides.subagentAllowAgents && config.subagents) {
    config.subagents.allowAgents = overrides.subagentAllowAgents
  }

  return {
    id: overrides.id,
    name: overrides.name,
    workspace: overrides.workspace,
    agentDir: overrides.agentDir,
    ...config,
  }
}

/** Model tier display info for UI */
export const MODEL_TIERS = {
  opus: { label: 'Opus', color: 'purple', costIndicator: '$$$' },
  sonnet: { label: 'Sonnet', color: 'blue', costIndicator: '$$' },
  haiku: { label: 'Haiku', color: 'green', costIndicator: '$' },
} as const

/** Tool group labels for UI checkboxes */
export const TOOL_GROUP_LABELS = {
  coding: 'Coding (read/write/exec)',
  browser: 'Browser & Web',
  memory: 'Memory Search',
  session: 'Session Management',
  subagent: 'Subagents & LLM Tasks',
  thinking: 'Thinking & Skills',
  readonly: 'Read-only',
} as const
