export type Command =
  | { type: 'quit' }
  | { type: 'reset' }
  | { type: 'help' }
  | { type: 'multiline' }
  | { type: 'status' }
  | { type: 'tools' }
  | { type: 'research'; task: string }
  | { type: 'council'; task: string }
  | { type: 'fullscreen' }
  | { type: 'compact' }
  | { type: 'usage' }
  | { type: 'context' }
  | { type: 'verbose' }
  | { type: 'model'; name?: string; providerModel?: string }
  | { type: 'backend'; provider?: string }
  | { type: 'runtime'; input?: string }
  | { type: 'login'; provider?: string }
  | { type: 'transfer'; target: string }
  | { type: 'pair'; action?: 'generate' | 'list' | 'revoke'; args?: string }
  | { type: 'queue'; action?: 'show' | 'set' | 'reset'; args?: string }
  | { type: 'elevate'; args?: string }
  | { type: 'message'; content: string };

export function isToolInventoryQuery(input: string): boolean {
  const normalized = input.trim().toLowerCase();
  if (!normalized) {
    return false;
  }
  if (
    normalized.includes('available tools')
    || normalized.includes('what tools')
    || normalized.includes('which tools')
    || normalized.includes('tool list')
    || normalized.includes('list tools')
    || normalized.includes('what can you do')
  ) {
    return true;
  }

  return (
    /\b(?:show|list|check)\s+(?:me\s+)?(?:your\s+)?(?:available\s+|new\s+)?tools?\b/.test(normalized)
    || /\b(?:what|which)\s+tools?\b/.test(normalized)
    || /\btools?\s+(?:do\s+you\s+have|are\s+available)\b/.test(normalized)
    || /\b(?:show|list|what\s+are)\s+(?:your\s+)?capabilities\b/.test(normalized)
  );
}

export function parseCommand(input: string): Command | null {
  const trimmed = input.trim();
  if (!trimmed) {return null;}

  // Quit
  if (trimmed === '/quit' || trimmed === '/exit') {
    return { type: 'quit' };
  }

  // Reset
  if (trimmed === '/reset' || trimmed === '/clear' || trimmed === '/new') {
    return { type: 'reset' };
  }

  // Help
  if (trimmed === '/help' || trimmed === '/?') {
    return { type: 'help' };
  }

  // Multiline paste mode
  if (trimmed === '/paste' || trimmed === '/multiline') {
    return { type: 'multiline' };
  }

  // Status
  if (trimmed === '/status') {
    return { type: 'status' };
  }

  // Tools
  if (trimmed === '/tools') {
    return { type: 'tools' };
  }

  // Research
  if (trimmed.startsWith('/research ')) {
    const task = trimmed.slice('/research '.length).trim();
    return { type: 'research', task };
  }
  if (trimmed === '/research') {
    return { type: 'research', task: '' };
  }

  // Council
  if (trimmed.startsWith('/council ')) {
    const task = trimmed.slice('/council '.length).trim();
    return { type: 'council', task };
  }
  if (trimmed === '/council') {
    return { type: 'council', task: '' };
  }
  // Natural-language council shortcut for common flows.
  const councilShortcut = trimmed.match(/^(?:yes\s+)?run\s+(?:the\s+)?council(?:\s+on)?(?:\s+(.+))?$/i);
  if (councilShortcut) {
    return { type: 'council', task: (councilShortcut[1] ?? '').trim() };
  }

  // Fullscreen
  if (trimmed === '/fullscreen' || trimmed === '/fs') {
    return { type: 'fullscreen' };
  }

  // Compact
  if (trimmed === '/compact') {
    return { type: 'compact' };
  }

  // Usage
  if (trimmed === '/usage') {
    return { type: 'usage' };
  }

  // Context
  if (trimmed === '/context') {
    return { type: 'context' };
  }

  // Verbose
  if (trimmed === '/verbose') {
    return { type: 'verbose' };
  }

  // Model (with optional argument)
  if (trimmed === '/model') {
    return { type: 'model' };
  }
  if (trimmed.startsWith('/model ')) {
    const args = trimmed.slice('/model '.length).trim();
    const parts = args.split(/\s+/);

    // /model <tier> <provider/model> - change tier's provider/model
    if (parts.length === 2 && parts[1].includes('/')) {
      return { type: 'model', name: parts[0], providerModel: parts[1] };
    }

    // /model <name> - single word (backward compatibility)
    const name = parts[0];
    return { type: 'model', name };
  }

  // Backend (with optional argument)
  if (trimmed === '/backend') {
    return { type: 'backend' };
  }
  if (trimmed.startsWith('/backend ')) {
    const provider = trimmed.slice('/backend '.length).trim();
    return { type: 'backend', provider };
  }

  // Runtime backend mode control (forwarded via gateway/daemon command service)
  if (trimmed === '/runtime') {
    return { type: 'runtime' };
  }
  if (trimmed.startsWith('/runtime ')) {
    const input = trimmed.slice('/runtime '.length).trim();
    return { type: 'runtime', input };
  }

  // Transfer
  if (trimmed === '/transfer') {
    return { type: 'transfer', target: '' };
  }
  if (trimmed.startsWith('/transfer ')) {
    const target = trimmed.slice('/transfer '.length).trim();
    return { type: 'transfer', target };
  }

  // Login
  if (trimmed === '/login') {
    return { type: 'login' };
  }
  if (trimmed.startsWith('/login ')) {
    const provider = trimmed.slice('/login '.length).trim();
    return { type: 'login', provider: provider || undefined };
  }

  // Pair
  if (trimmed === '/pair' || trimmed === '/pair list') {
    return { type: 'pair', action: 'list' };
  }
  if (trimmed === '/pair generate' || trimmed.startsWith('/pair generate ')) {
    const label = trimmed.slice('/pair generate'.length).trim() || undefined;
    return { type: 'pair', action: 'generate', args: label };
  }
  if (trimmed.startsWith('/pair revoke ')) {
    const args = trimmed.slice('/pair revoke '.length).trim();
    return { type: 'pair', action: 'revoke', args };
  }

  // Queue
  if (trimmed === '/queue' || trimmed === '/queue show') {
    return { type: 'queue', action: 'show' };
  }
  if (trimmed === '/queue reset') {
    return { type: 'queue', action: 'reset' };
  }
  if (trimmed.startsWith('/queue set ')) {
    const args = trimmed.slice('/queue set '.length).trim();
    return { type: 'queue', action: 'set', args };
  }
  if (trimmed.startsWith('/queue ')) {
    const args = trimmed.slice('/queue '.length).trim();
    return { type: 'queue', action: 'set', args };
  }

  // Elevate
  if (trimmed === '/elevate') {
    return { type: 'elevate' };
  }
  if (trimmed.startsWith('/elevate ')) {
    const args = trimmed.slice('/elevate '.length).trim();
    return { type: 'elevate', args };
  }

  // Regular message
  return { type: 'message', content: trimmed };
}

export function getHelpText(): string {
  return `
Commands:
  /help, /?              Show this help
  /paste, /multiline     Enter multiline mode (finish with single '.' line)
  /tools                 Show available tools in this session
  /model [name]          Show or switch model tier (local, default, fast, complex)
  /model <tier> <p/m>    Change tier's provider/model (e.g. /model default anthropic/claude-sonnet-4)
  /backend [provider]    Show or switch local backend (ollama, llamacpp)
  /runtime [args]        Runtime backend mode control (forwarded via gateway/daemon command service)
  /research <task>       Delegate a task to the configured research agent
  /council <task>        Run the councils pipeline for a task
  /council preflight     Check council tier routing, endpoint/auth mode, and probe latency
  /login [provider]      Authenticate with GitHub, OpenAI, Anthropic, or Z.AI
  /pair                  List pending pairing codes and approved senders
  /pair generate [label] Generate a new DM pairing code
  /pair revoke <ch> <id> Revoke an approved sender
  /queue                 Show queue policy for this session
  /queue set <k> <v>     Set queue override (mode/cap/overflow/debounce_ms/summarize_overflow)
  /queue reset           Clear queue overrides for this session
  /approvals             List pending guarded actions for this session
  /approve [id]          Approve latest pending action (or specific id)
  /deny [id] [reason]    Deny latest pending action (or specific id)
  /elevate [args]        Show or manage elevated mode
  /reset, /clear, /new   Clear conversation history
  /compact               Compact conversation history
  /usage                 Show token usage and estimated cost
  /context               Show estimated context-window usage
  /verbose               Toggle verbose mode (show raw streaming and tool output)
  /status                Show session info and token usage
  /fullscreen, /fs       Switch to fullscreen mode
  /transfer <dest>       Transfer session to another frontend (telegram|tui)
  /quit, /exit           Exit TUI
`.trim();
}

import { MODEL_PROVIDERS } from '../../config/index.js';

export type ModelAlias = 'local' | 'default' | 'fast' | 'complex' | 'opus' | 'sonnet' | 'haiku' | 'ollama';

// List of all slash commands for autocompletion
export const SLASH_COMMANDS = [
  '/help',
  '/paste',
  '/multiline',
  '/tools',
  '/model',
  '/backend',
  '/runtime',
  '/research',
  '/council',
  '/reset',
  '/clear',
  '/new',
  '/compact',
  '/usage',
  '/context',
  '/verbose',
  '/status',
  '/fullscreen',
  '/fs',
  '/login',
  '/pair',
  '/queue',
  '/approvals',
  '/approve',
  '/deny',
  '/elevate',
  '/transfer',
  '/quit',
  '/exit',
];

// Command descriptions for tooltips
export const COMMAND_TOOLTIPS: Record<string, string> = {
  '/help': 'Show available commands',
  '/paste': 'Compose a multiline message; finish with a single "." line',
  '/multiline': 'Compose a multiline message; finish with a single "." line',
  '/tools': 'Show authoritative runtime tool list for this session',
  '/model': 'Show or switch model (local, default, fast, complex)',
  '/backend': 'Show or switch local backend (ollama, llamacpp)',
  '/runtime': 'Runtime backend mode control via gateway/daemon command service (not local /backend provider switch)',
  '/research': 'Delegate a task to the configured research agent',
  '/council': 'Run the councils pipeline for a task; use "/council preflight" for route/auth checks',
  '/reset': 'Clear conversation history',
  '/clear': 'Clear conversation history',
  '/new': 'Start a new conversation',
  '/compact': 'Compact conversation history to save context space',
  '/usage': 'Show token usage and estimated cost',
  '/context': 'Show estimated context-window usage',
  '/verbose': 'Toggle verbose mode (show raw streaming and tool output)',
  '/status': 'Show session info and token usage',
  '/fullscreen': 'Switch to fullscreen mode',
  '/fs': 'Switch to fullscreen mode',
  '/login': 'Authenticate with GitHub/OpenAI/Anthropic (OAuth/token or API key) or Z.AI (API key store)',
  '/pair': 'Generate/list/revoke DM pairing codes',
  '/queue': 'Show or update per-session queue policy',
  '/approvals': 'List pending guarded actions for this session',
  '/approve': 'Approve latest pending action (or specific id)',
  '/deny': 'Deny latest pending action (or specific id and reason)',
  '/elevate': 'Show or manage elevated mode',
  '/transfer': 'Transfer session to another frontend (telegram|tui)',
  '/quit': 'Exit TUI',
  '/exit': 'Exit TUI',
};

// Model aliases for /model command autocompletion
export const MODEL_ALIASES = ['local', 'default', 'fast', 'complex', 'opus', 'sonnet', 'haiku', 'ollama'];

// Provider names for /model <tier> <provider/model> syntax — derived from config schema
export const PROVIDER_NAMES: readonly string[] = MODEL_PROVIDERS;

// Model alias descriptions
export const MODEL_TOOLTIPS: Record<string, string> = {
  local: 'Local model (Ollama/llama.cpp)',
  default: 'Default model tier',
  fast: 'Fast/lightweight model tier',
  complex: 'Complex reasoning model tier',
  opus: 'Alias for complex tier',
  sonnet: 'Alias for default tier',
  haiku: 'Alias for fast tier',
  ollama: 'Alias for local tier',
};

export function getCommandCompletions(partial: string): string[] {
  const trimmed = partial.trim();

  if (trimmed.startsWith('/council ')) {
    const suffix = trimmed.slice('/council '.length).toLowerCase();
    if ('preflight'.startsWith(suffix)) {
      return ['/council preflight'];
    }
    return [];
  }

  // Complete /model <tier> <provider/model>
  if (trimmed.startsWith('/model ')) {
    const args = trimmed.slice('/model '.length).trim();
    const parts = args.split(/\s+/);

    if (parts.length === 1) {
      // Single word - suggest model aliases
      const modelPartial = parts[0].toLowerCase();
      return MODEL_ALIASES
        .filter(alias => alias.startsWith(modelPartial))
        .map(alias => `/model ${alias}`);
    } else if (parts.length === 2) {
      // Two words - suggest provider prefixes
      const providerPartial = parts[1].toLowerCase();
      return PROVIDER_NAMES
        .filter(provider => provider.startsWith(providerPartial))
        .map(provider => `/model ${parts[0]} ${provider}`);
    }
  }

  // Complete slash commands
  if (trimmed.startsWith('/')) {
    return SLASH_COMMANDS.filter(cmd => cmd.startsWith(trimmed.toLowerCase()));
  }

  return [];
}

export function getCommandTooltip(partial: string): string | null {
  const trimmed = partial.trim().toLowerCase();

  // Tooltip for /model arguments
  if (trimmed.startsWith('/model ')) {
    const args = trimmed.slice('/model '.length).trim();
    const parts = args.split(/\s+/);

    if (parts.length === 1) {
      // Single word - model tier or provider
      const modelArg = parts[0].toLowerCase();
      if (modelArg && MODEL_TOOLTIPS[modelArg]) {
        return MODEL_TOOLTIPS[modelArg];
      }
      // Show tooltip for partial match
      const matches = MODEL_ALIASES.filter(a => a.startsWith(modelArg));
      if (matches.length === 1 && MODEL_TOOLTIPS[matches[0]]) {
        return MODEL_TOOLTIPS[matches[0]];
      }
      return 'Choose: local, default, fast, complex';
    } else if (parts.length === 2) {
      // Two words - tier + provider
      const providerPartial = parts[1].toLowerCase();
      const matches = PROVIDER_NAMES.filter(p => p.startsWith(providerPartial));
      if (matches.length === 1) {
        return `Enter provider/model (e.g. ${matches[0]}/...)`;
      }
      return 'Enter provider/model (e.g. anthropic/claude-sonnet-4)';
    }
  }

  // Exact match tooltip
  if (COMMAND_TOOLTIPS[trimmed]) {
    return COMMAND_TOOLTIPS[trimmed];
  }

  // Partial match - show tooltip if only one command matches
  if (trimmed.startsWith('/')) {
    const matches = SLASH_COMMANDS.filter(cmd => cmd.startsWith(trimmed));
    if (matches.length === 1 && COMMAND_TOOLTIPS[matches[0]]) {
      return COMMAND_TOOLTIPS[matches[0]];
    }
  }

  return null;
}

export function resolveModelAlias(alias: string): 'local' | 'default' | 'fast' | 'complex' {
  const map: Record<string, 'local' | 'default' | 'fast' | 'complex'> = {
    local: 'local',
    ollama: 'local',
    default: 'default',
    sonnet: 'default',
    fast: 'fast',
    haiku: 'fast',
    complex: 'complex',
    opus: 'complex',
  };
  return map[alias.toLowerCase()] ?? 'default';
}
