import { Injectable, type OnModuleInit } from '@nestjs/common';
import type { CommandDef, CommandManifest } from '@mosaicstack/types';

@Injectable()
export class CommandRegistryService implements OnModuleInit {
  private readonly commands: CommandDef[] = [];

  registerCommand(def: CommandDef): void {
    const existing = this.commands.findIndex((c) => c.name === def.name);
    if (existing >= 0) {
      this.commands[existing] = def;
    } else {
      this.commands.push(def);
    }
  }

  registerCommands(defs: CommandDef[]): void {
    for (const def of defs) {
      this.registerCommand(def);
    }
  }

  getManifest(): CommandManifest {
    return {
      version: 1,
      commands: [...this.commands],
      skills: [],
    };
  }

  onModuleInit(): void {
    this.registerCommands([
      {
        name: 'model',
        description: 'Switch the active model',
        aliases: ['m'],
        args: [
          {
            name: 'model-name',
            type: 'string',
            optional: false,
            description: 'Model name to switch to',
          },
        ],
        scope: 'core',
        execution: 'socket',
        available: true,
      },
      {
        name: 'thinking',
        description: 'Set thinking level (none/low/medium/high/auto)',
        aliases: ['t'],
        args: [
          {
            name: 'level',
            type: 'enum',
            optional: false,
            values: ['none', 'low', 'medium', 'high', 'auto'],
            description: 'Thinking level',
          },
        ],
        scope: 'core',
        execution: 'socket',
        available: true,
      },
      {
        name: 'new',
        description: 'Start a new conversation',
        aliases: ['n'],
        scope: 'core',
        execution: 'socket',
        available: true,
      },
      {
        name: 'clear',
        description: 'Clear conversation context and GC session artifacts',
        aliases: [],
        scope: 'core',
        execution: 'socket',
        available: true,
      },
      {
        name: 'compact',
        description: 'Request context compaction',
        aliases: [],
        scope: 'core',
        execution: 'socket',
        available: true,
      },
      {
        name: 'retry',
        description: 'Retry the last message',
        aliases: [],
        scope: 'core',
        execution: 'socket',
        available: true,
      },
      {
        name: 'rename',
        description: 'Rename current conversation',
        aliases: [],
        args: [
          { name: 'name', type: 'string', optional: false, description: 'New conversation name' },
        ],
        scope: 'core',
        execution: 'rest',
        available: true,
      },
      {
        name: 'history',
        description: 'Show conversation history',
        aliases: [],
        args: [
          {
            name: 'limit',
            type: 'string',
            optional: true,
            description: 'Number of messages to show',
          },
        ],
        scope: 'core',
        execution: 'rest',
        available: true,
      },
      {
        name: 'export',
        description: 'Export conversation to markdown or JSON',
        aliases: [],
        args: [
          {
            name: 'format',
            type: 'enum',
            optional: true,
            values: ['md', 'json'],
            description: 'Export format',
          },
        ],
        scope: 'core',
        execution: 'rest',
        available: true,
      },
      {
        name: 'preferences',
        description: 'View or set user preferences',
        aliases: ['pref'],
        args: [
          {
            name: 'action',
            type: 'enum',
            optional: true,
            values: ['show', 'set', 'reset'],
            description: 'Action to perform',
          },
        ],
        scope: 'core',
        execution: 'rest',
        available: true,
      },
      {
        name: 'system',
        description: 'Set session-scoped system prompt override',
        aliases: [],
        args: [
          {
            name: 'override',
            type: 'string',
            optional: false,
            description: 'System prompt text to inject for this session',
          },
        ],
        scope: 'core',
        execution: 'socket',
        available: true,
      },
      {
        name: 'status',
        description: 'Show session and connection status',
        aliases: ['s'],
        scope: 'core',
        execution: 'hybrid',
        available: true,
      },
      {
        name: 'help',
        description: 'Show available commands',
        aliases: ['h'],
        scope: 'core',
        execution: 'local',
        available: true,
      },
      {
        name: 'gc',
        description: 'Trigger garbage collection sweep (admin only — system-wide)',
        aliases: [],
        scope: 'admin',
        execution: 'socket',
        available: true,
      },
      {
        name: 'agent',
        description: 'Switch or list available agents',
        aliases: ['a'],
        args: [
          {
            name: 'args',
            type: 'string',
            optional: true,
            description: 'list or <agent-id>',
          },
        ],
        scope: 'agent',
        execution: 'socket',
        available: true,
      },
      {
        name: 'provider',
        description: 'Manage LLM providers (list/login/logout)',
        aliases: [],
        args: [
          {
            name: 'args',
            type: 'string',
            optional: true,
            description: 'list | login <name> | logout <name>',
          },
        ],
        scope: 'agent',
        execution: 'hybrid',
        available: true,
      },
      {
        name: 'mission',
        description: 'View or set active mission',
        aliases: [],
        args: [
          {
            name: 'args',
            type: 'string',
            optional: true,
            description: 'status | set <id> | list | tasks',
          },
        ],
        scope: 'agent',
        execution: 'socket',
        available: true,
      },
      {
        name: 'prdy',
        description: 'Launch PRD wizard',
        aliases: [],
        scope: 'agent',
        execution: 'socket',
        available: true,
      },
      {
        name: 'tools',
        description: 'List available agent tools',
        aliases: [],
        scope: 'agent',
        execution: 'socket',
        available: true,
      },
      {
        name: 'mcp',
        description: 'Manage MCP server connections (status/reconnect/servers)',
        aliases: [],
        args: [
          {
            name: 'action',
            type: 'enum',
            optional: true,
            values: ['status', 'reconnect', 'servers'],
            description: 'Action: status (default), reconnect <name>, servers',
          },
        ],
        scope: 'agent',
        execution: 'socket',
        available: true,
      },
      {
        name: 'reload',
        description: 'Soft-reload gateway plugins and command manifest (admin)',
        aliases: [],
        scope: 'admin',
        execution: 'socket',
        available: true,
      },
    ]);
  }
}
