import { APP_LOCALES, type AppLocale } from '../../core/i18n/locale'; import { type RouteId } from '../../core/routing/route-ids'; export type CommandId = | 'help' | 'projects' | 'servicesAi' | 'cv' | 'contact' | 'brew' | 'ignite' | 'rev' | 'clear' | 'close'; export const COMMAND_IDS: readonly CommandId[] = [ 'help', 'projects', 'servicesAi', 'cv', 'contact', 'brew', 'ignite', 'rev', 'clear', 'close', ]; export type CommandAction = | { readonly kind: 'navigate'; readonly routeId: RouteId } | { readonly kind: 'openCv' } | { readonly kind: 'message'; readonly messageKey: 'help' | 'brew' | 'ignite' | 'rev' } | { readonly kind: 'clear' } | { readonly kind: 'close' }; export interface CommandDefinition { readonly id: CommandId; readonly input: string; readonly aliases: Record; readonly action: CommandAction; } export type CommandMatch = | { readonly kind: 'command'; readonly definition: CommandDefinition } | { readonly kind: 'empty' } | { readonly kind: 'unknown'; readonly input: string }; export const COMMANDS: readonly CommandDefinition[] = [ { id: 'help', input: 'help', aliases: { de: ['hilfe'], en: [] }, action: { kind: 'message', messageKey: 'help' }, }, { id: 'projects', input: 'projects', aliases: { de: ['projekte'], en: [] }, action: { kind: 'navigate', routeId: 'projects' }, }, { id: 'servicesAi', input: 'services ai', aliases: { de: ['leistungen ai'], en: [] }, action: { kind: 'navigate', routeId: 'servicesAi' }, }, { id: 'cv', input: 'cv', aliases: { de: ['lebenslauf'], en: ['resume'] }, action: { kind: 'openCv' }, }, { id: 'contact', input: 'contact', aliases: { de: ['kontakt'], en: [] }, action: { kind: 'navigate', routeId: 'contact' }, }, { id: 'brew', input: 'brew', aliases: { de: ['brauen'], en: [] }, action: { kind: 'message', messageKey: 'brew' }, }, { id: 'ignite', input: 'ignite', aliases: { de: ['zuenden', 'zünden'], en: [] }, action: { kind: 'message', messageKey: 'ignite' }, }, { id: 'rev', input: 'rev', aliases: { de: ['drehzahl'], en: [] }, action: { kind: 'message', messageKey: 'rev' }, }, { id: 'clear', input: 'clear', aliases: { de: ['leeren'], en: [] }, action: { kind: 'clear' }, }, { id: 'close', input: 'close', aliases: { de: ['schliessen', 'schließen'], en: [] }, action: { kind: 'close' }, }, ]; const COMMAND_LOOKUP = buildCommandLookup(COMMANDS); function buildCommandLookup( commands: readonly CommandDefinition[], ): ReadonlyMap { const lookup = new Map(); for (const command of commands) { lookup.set(normalizeCommandInput(command.input), command); for (const locale of APP_LOCALES) { for (const alias of command.aliases[locale]) { lookup.set(normalizeCommandInput(alias), command); } } } return lookup; } export function normalizeCommandInput(raw: string): string { return raw.trim().replace(/\s+/g, ' ').toLowerCase(); } export function parseCommand(raw: string): CommandMatch { const normalized = normalizeCommandInput(raw); if (normalized.length === 0) { return { kind: 'empty' }; } const definition = COMMAND_LOOKUP.get(normalized); if (!definition) { return { kind: 'unknown', input: raw }; } return { kind: 'command', definition }; } export function suggestCommands(raw: string, locale: AppLocale): readonly CommandDefinition[] { const normalized = normalizeCommandInput(raw); return COMMANDS.filter((command) => { if (normalized.length === 0) { return true; } if (command.input.startsWith(normalized)) { return true; } return command.aliases[locale].some((alias) => normalizeCommandInput(alias).startsWith(normalized), ); }); }