import type { SlashCommandMeta } from '@shared/types/team';

export interface KnownSlashCommandDefinition {
  name: string;
  command: `/${string}`;
  description: string;
}

export interface ParsedStandaloneSlashCommand {
  name: string;
  command: `/${string}`;
  args?: string;
  raw: string;
  startIndex: number;
  endIndex: number;
}

const SLASH_COMMAND_NAME_PATTERN = /^[a-z][a-z0-9:-]{0,63}$/i;
const STANDALONE_SLASH_COMMAND_PATTERN = /^\/([a-z][a-z0-9:-]{0,63})(?:\s+([\s\S]*\S))?$/i;

export const KNOWN_SLASH_COMMANDS: readonly KnownSlashCommandDefinition[] = [
  {
    name: 'compact',
    command: '/compact',
    description: 'Compact conversation with optional focus instructions.',
  },
  {
    name: 'clear',
    command: '/clear',
    description: 'Clear conversation history and free up context.',
  },
  {
    name: 'reset',
    command: '/reset',
    description: 'Alias of /clear. Clear conversation history and free up context.',
  },
  {
    name: 'new',
    command: '/new',
    description: 'Alias of /clear. Start a fresh conversation.',
  },
  {
    name: 'plan',
    command: '/plan',
    description: 'Enter plan mode with an optional task description.',
  },
  {
    name: 'model',
    command: '/model',
    description: 'Select or change the Claude model.',
  },
  {
    name: 'effort',
    command: '/effort',
    description: 'Set reasoning effort for the current session.',
  },
  {
    name: 'fast',
    command: '/fast',
    description: 'Toggle fast mode on or off.',
  },
  {
    name: 'cost',
    command: '/cost',
    description: 'Show token usage statistics.',
  },
  {
    name: 'usage',
    command: '/usage',
    description: 'Show plan usage limits and rate-limit status.',
  },
] as const;

const KNOWN_SLASH_COMMANDS_BY_NAME = new Map(
  KNOWN_SLASH_COMMANDS.map((command) => [command.name.toLowerCase(), command] as const)
);

export function getKnownSlashCommand(name: string): KnownSlashCommandDefinition | null {
  return KNOWN_SLASH_COMMANDS_BY_NAME.get(name.trim().toLowerCase()) ?? null;
}

export function isSupportedSlashCommandName(name: string): boolean {
  return SLASH_COMMAND_NAME_PATTERN.test(name.trim());
}

export function buildSlashCommandMeta(
  name: string,
  args?: string,
  command?: `/${string}`
): SlashCommandMeta {
  const normalizedName = name.trim().toLowerCase();
  const normalizedCommand = command ?? `/${normalizedName}`;
  const known = getKnownSlashCommand(normalizedName);
  return {
    name: normalizedName,
    command: normalizedCommand,
    ...(args ? { args } : {}),
    ...(known ? { knownDescription: known.description } : {}),
  };
}

export function buildStandaloneSlashCommandMeta(text: string): SlashCommandMeta | null {
  const parsed = parseStandaloneSlashCommand(text);
  if (!parsed) return null;
  return buildSlashCommandMeta(parsed.name, parsed.args, parsed.command);
}

export function parseStandaloneSlashCommand(text: string): ParsedStandaloneSlashCommand | null {
  const trimmed = text.trim();
  if (!trimmed) return null;

  const match = STANDALONE_SLASH_COMMAND_PATTERN.exec(trimmed);
  if (!match) return null;

  const name = match[1].toLowerCase();
  const args = match[2]?.trim();
  const startIndex = text.indexOf(trimmed);
  const endIndex = startIndex + trimmed.length;

  return {
    name,
    command: `/${name}`,
    args: args || undefined,
    raw: trimmed,
    startIndex,
    endIndex,
  };
}
