/**
 * Lightweight reactive i18n — no external deps.
 *
 * Locale priority: localStorage > VITE_LOCALE > navigator.language > 'en'
 * Changing locale at runtime triggers subscribed React components to re-render.
 */

const STORAGE_KEY = 'pinchchat-locale';

const en = {
  // Login screen
  'login.title': 'PinchChat',
  'login.subtitle': 'Connect to your OpenClaw gateway',
  'login.gatewayUrl': 'Gateway URL',
  'login.token': 'Token',
  'login.tokenPlaceholder': 'Enter your gateway token',
  'login.connect': 'Connect',
  'login.connecting': 'Connecting…',
  'login.showToken': 'Show token',
  'login.hideToken': 'Hide token',
  'login.storedLocally': 'Credentials are stored locally in your browser',
  'login.wsHint': 'URL must start with ws:// or wss://',

  // Header
  'header.title': 'PinchChat',
  'header.connected': 'Connected',
  'header.disconnected': 'Disconnected',
  'header.logout': 'Logout',
  'header.toggleSidebar': 'Toggle sidebar',
  'header.changeLanguage': 'Change language',
  'header.soundOn': 'Enable notification sound',
  'header.soundOff': 'Disable notification sound',

  // Chat
  'chat.welcome': 'PinchChat',
  'chat.welcomeSub': 'Send a message to get started',
  'chat.suggestions': 'Try asking...',
  'chat.suggestion1': 'Summarize my recent emails',
  'chat.suggestion2': "What's on my calendar today?",
  'chat.suggestion3': 'Search the web for latest news',
  'chat.suggestion4': 'Help me write a script',
  'chat.loadingHistory': 'Loading messages…',
  'chat.inputPlaceholder': 'Type a message…',
  'chat.inputLabel': 'Message',
  'chat.attachFile': 'Attach file',
  'chat.send': 'Send',
  'chat.stop': 'Stop',
  'chat.showPreview': 'Preview markdown',
  'chat.hidePreview': 'Hide preview',
  'chat.scrollToBottom': 'New messages',
  'chat.scrollDown': 'Scroll to bottom',
  'chat.collapseTools': 'Collapse all tools',
  'chat.expandTools': 'Expand all tools',
  'chat.messages': 'Chat messages',
  'chat.thinking': 'Thinking…',

  // Sidebar
  'sidebar.title': 'Sessions',
  'sidebar.empty': 'No sessions',
  'sidebar.search': 'Search sessions…',
  'sidebar.noResults': 'No matching sessions',
  'sidebar.pin': 'Pin session',
  'sidebar.unpin': 'Unpin session',
  'sidebar.pinned': 'Pinned',
  'sidebar.delete': 'Delete session',
  'sidebar.deleteConfirm': 'Delete this session? This cannot be undone.',
  'sidebar.deleteCancel': 'Cancel',
  'sidebar.openSplit': 'Open in split view',
  'sidebar.close': 'Close sidebar',
  'sidebar.clearSearch': 'Clear search',
  'sidebar.filterAll': 'All',
  'sidebar.filterActive': 'Active',
  'split.close': 'Close split view',
  'app.mainChat': 'Main chat',
  'app.splitPane': 'Split pane',
  'app.skipToChat': 'Skip to chat input',

  // Thinking
  'thinking.label': 'Thinking',
  'thinking.reasoning': 'Reasoning…',

  // Tool call
  'tool.parameters': 'Parameters',
  'tool.result': 'Result',

  // Connection banner
  'connection.reconnecting': 'Connection lost — reconnecting…',
  'connection.reconnected': 'Reconnected!',

  // Message actions
  'message.copy': 'Copy message',
  'message.copied': 'Copied!',
  'message.retry': 'Resend message',
  'message.metadata': 'Message details',
  'message.rawJson': 'Raw JSON',
  'message.hideRawJson': 'Hide raw JSON',

  // Timestamps
  'time.yesterday': 'Yesterday',
  'time.today': 'Today',

  // Keyboard shortcuts
  'shortcuts.title': 'Keyboard Shortcuts',
  'shortcuts.send': 'Send message',
  'shortcuts.newline': 'New line',
  'shortcuts.search': 'Search sessions',
  'shortcuts.switchSession': 'Previous / next session',
  'shortcuts.closeSidebar': 'Close sidebar / search',
  'shortcuts.stop': 'Stop generation',
  'shortcuts.help': 'Show shortcuts',
  'shortcuts.close': 'Close',
  'shortcuts.chatSection': 'Chat',

  // Error boundary
  'error.title': 'Something went wrong',
  'error.description': 'An unexpected error occurred while rendering the interface. You can try again or reload the page.',
  'error.retry': 'Try again',
  'error.reload': 'Reload page',
  'shortcuts.navigationSection': 'Navigation',
  'shortcuts.generalSection': 'General',

  // Export
  'header.export': 'Export conversation as Markdown',
  'header.compact': 'Compact',
  'header.compacting': 'Compacting…',
  'header.sessionInfo': 'Session Info',
  'sessionInfo.sessionKey': 'Session Key',
  'sessionInfo.channel': 'Channel',
  'sessionInfo.kind': 'Kind',
  'sessionInfo.model': 'Model',
  'sessionInfo.agent': 'Agent',
  'sessionInfo.messages': 'Messages',
  'sessionInfo.totalTokens': 'Total Tokens',
  'sessionInfo.inputTokens': 'Input',
  'sessionInfo.outputTokens': 'Output',
  'sessionInfo.contextWindow': 'Context',
  'sessionInfo.lastActive': 'Last Active',

  // Theme
  'theme.title': 'Theme',
  'theme.mode': 'Mode',
  'theme.accent': 'Accent',
  'theme.system': 'System',
  'theme.dark': 'Dark',
  'theme.light': 'Light',
  'theme.oled': 'OLED',

  // Message search
  'search.placeholder': 'Search messages…',
  'search.noResults': '0 results',
  'search.prev': 'Previous match',
  'search.next': 'Next match',
  'shortcuts.searchMessages': 'Search messages',

  // Send shortcut setting
  'settings.sendShortcut': 'Send with',
  'settings.sendEnter': 'Enter',
  'settings.sendCtrlEnter': 'Ctrl+Enter',

  // Bookmarks
  'message.bookmark': 'Bookmark message',
  'message.removeBookmark': 'Remove bookmark',
  'chat.bookmarks': 'Bookmarks',
  'chat.export': 'Export conversation',
  'chat.contextCompacted': 'Context compacted — older messages cached locally',
  'slash.commands': 'Commands',
  'slash.status': 'Show session status & usage',
  'slash.reasoning': 'Toggle reasoning mode',
  'slash.verbose': 'Toggle verbose output',
  'slash.model': 'Switch model for this session',
  'slash.compact': 'Compact conversation context',
  'slash.reset': 'Reset the session',
  'slash.help': 'Show available commands',
} as const;

const fr: Record<keyof typeof en, string> = {
  'login.title': 'PinchChat',
  'login.subtitle': 'Connectez-vous à votre gateway OpenClaw',
  'login.gatewayUrl': 'URL de la gateway',
  'login.token': 'Token',
  'login.tokenPlaceholder': 'Entrez votre token gateway',
  'login.connect': 'Connexion',
  'login.connecting': 'Connexion…',
  'login.showToken': 'Afficher le token',
  'login.hideToken': 'Masquer le token',
  'login.storedLocally': 'Les identifiants sont stockés localement dans votre navigateur',
  'login.wsHint': 'L\'URL doit commencer par ws:// ou wss://',

  'header.title': 'PinchChat',
  'header.connected': 'Connecté',
  'header.disconnected': 'Déconnecté',
  'header.logout': 'Déconnexion',
  'header.toggleSidebar': 'Afficher/masquer la barre latérale',
  'header.changeLanguage': 'Changer de langue',
  'header.soundOn': 'Activer le son de notification',
  'header.soundOff': 'Désactiver le son de notification',

  'chat.welcome': 'PinchChat',
  'chat.welcomeSub': 'Envoyez un message pour commencer',
  'chat.suggestions': 'Essayez par exemple...',
  'chat.suggestion1': 'Résume mes derniers emails',
  'chat.suggestion2': "Qu'est-ce que j'ai au calendrier aujourd'hui ?",
  'chat.suggestion3': 'Cherche sur le web les dernières actus',
  'chat.suggestion4': "Aide-moi à écrire un script",
  'chat.loadingHistory': 'Chargement des messages…',
  'chat.inputPlaceholder': 'Tapez un message…',
  'chat.inputLabel': 'Message',
  'chat.attachFile': 'Joindre un fichier',
  'chat.send': 'Envoyer',
  'chat.stop': 'Arrêter',
  'chat.showPreview': 'Aperçu markdown',
  'chat.hidePreview': 'Masquer l\'aperçu',
  'chat.scrollToBottom': 'Nouveaux messages',
  'chat.scrollDown': 'Défiler en bas',
  'chat.collapseTools': 'Replier tous les outils',
  'chat.expandTools': 'Déplier tous les outils',
  'chat.messages': 'Messages du chat',
  'chat.thinking': 'Réflexion…',

  'sidebar.title': 'Sessions',
  'sidebar.empty': 'Aucune session',
  'sidebar.search': 'Rechercher…',
  'sidebar.noResults': 'Aucun résultat',
  'sidebar.pin': 'Épingler la session',
  'sidebar.unpin': 'Désépingler la session',
  'sidebar.pinned': 'Épinglées',
  'sidebar.delete': 'Supprimer la session',
  'sidebar.deleteConfirm': 'Supprimer cette session ? Cette action est irréversible.',
  'sidebar.deleteCancel': 'Annuler',
  'sidebar.openSplit': 'Ouvrir en vue scindée',
  'sidebar.close': 'Fermer la barre latérale',
  'sidebar.clearSearch': 'Effacer la recherche',
  'sidebar.filterAll': 'Tout',
  'sidebar.filterActive': 'Actives',
  'split.close': 'Fermer la vue scindée',
  'app.mainChat': 'Chat principal',
  'app.splitPane': 'Volet scindé',
  'app.skipToChat': 'Aller au champ de saisie',

  'thinking.label': 'Réflexion',
  'thinking.reasoning': 'Réflexion…',

  'tool.parameters': 'Paramètres',
  'tool.result': 'Résultat',

  'connection.reconnecting': 'Connexion perdue — reconnexion…',
  'connection.reconnected': 'Reconnecté !',

  'message.copy': 'Copier le message',
  'message.copied': 'Copié !',
  'message.retry': 'Renvoyer le message',
  'message.metadata': 'Détails du message',
  'message.rawJson': 'JSON brut',
  'message.hideRawJson': 'Masquer le JSON brut',

  'time.yesterday': 'Hier',
  'time.today': "Aujourd'hui",

  'shortcuts.title': 'Raccourcis clavier',
  'shortcuts.send': 'Envoyer le message',
  'shortcuts.newline': 'Nouvelle ligne',
  'shortcuts.search': 'Rechercher des sessions',
  'shortcuts.switchSession': 'Session précédente / suivante',
  'shortcuts.closeSidebar': 'Fermer la barre / recherche',
  'shortcuts.stop': 'Arrêter la génération',
  'shortcuts.help': 'Afficher les raccourcis',
  'shortcuts.close': 'Fermer',
  'shortcuts.chatSection': 'Chat',

  'error.title': 'Quelque chose s\'est mal passé',
  'error.description': 'Une erreur inattendue est survenue lors de l\'affichage. Vous pouvez réessayer ou recharger la page.',
  'error.retry': 'Réessayer',
  'error.reload': 'Recharger',
  'shortcuts.navigationSection': 'Navigation',
  'shortcuts.generalSection': 'Général',

  'header.export': 'Exporter la conversation en Markdown',
  'header.compact': 'Compacter',
  'header.compacting': 'Compaction…',
  'header.sessionInfo': 'Infos session',
  'sessionInfo.sessionKey': 'Clé session',
  'sessionInfo.channel': 'Canal',
  'sessionInfo.kind': 'Type',
  'sessionInfo.model': 'Modèle',
  'sessionInfo.agent': 'Agent',
  'sessionInfo.messages': 'Messages',
  'sessionInfo.totalTokens': 'Tokens total',
  'sessionInfo.inputTokens': 'Entrée',
  'sessionInfo.outputTokens': 'Sortie',
  'sessionInfo.contextWindow': 'Contexte',
  'sessionInfo.lastActive': 'Dernière activité',

  'theme.title': 'Thème',
  'theme.mode': 'Mode',
  'theme.accent': 'Accent',
  'theme.system': 'Système',
  'theme.dark': 'Sombre',
  'theme.light': 'Clair',
  'theme.oled': 'OLED',

  'search.placeholder': 'Rechercher dans les messages…',
  'search.noResults': '0 résultat',
  'search.prev': 'Résultat précédent',
  'search.next': 'Résultat suivant',
  'shortcuts.searchMessages': 'Rechercher dans les messages',

  'settings.sendShortcut': 'Envoyer avec',
  'settings.sendEnter': 'Entrée',
  'settings.sendCtrlEnter': 'Ctrl+Entrée',

  'message.bookmark': 'Marquer le message',
  'message.removeBookmark': 'Retirer le marque-page',
  'chat.bookmarks': 'Marque-pages',
  'chat.export': 'Exporter la conversation',
  'chat.contextCompacted': 'Contexte compacté — anciens messages en cache local',
  'slash.commands': 'Commandes',
  'slash.status': 'Afficher le statut et l\'utilisation',
  'slash.reasoning': 'Activer/désactiver le raisonnement',
  'slash.verbose': 'Activer/désactiver le mode verbeux',
  'slash.model': 'Changer de modèle pour cette session',
  'slash.compact': 'Compacter le contexte',
  'slash.reset': 'Réinitialiser la session',
  'slash.help': 'Afficher les commandes disponibles',
};

const es: Record<keyof typeof en, string> = {
  'login.title': 'PinchChat',
  'login.subtitle': 'Conéctate a tu gateway OpenClaw',
  'login.gatewayUrl': 'URL del gateway',
  'login.token': 'Token',
  'login.tokenPlaceholder': 'Introduce tu token de gateway',
  'login.connect': 'Conectar',
  'login.connecting': 'Conectando…',
  'login.showToken': 'Mostrar token',
  'login.hideToken': 'Ocultar token',
  'login.storedLocally': 'Las credenciales se guardan localmente en tu navegador',
  'login.wsHint': 'La URL debe empezar con ws:// o wss://',

  'header.title': 'PinchChat',
  'header.connected': 'Conectado',
  'header.disconnected': 'Desconectado',
  'header.logout': 'Cerrar sesión',
  'header.toggleSidebar': 'Mostrar/ocultar barra lateral',
  'header.changeLanguage': 'Cambiar idioma',
  'header.soundOn': 'Activar sonido de notificación',
  'header.soundOff': 'Desactivar sonido de notificación',

  'chat.welcome': 'PinchChat',
  'chat.welcomeSub': 'Envía un mensaje para comenzar',
  'chat.suggestions': 'Prueba a preguntar...',
  'chat.suggestion1': 'Resume mis últimos correos',
  'chat.suggestion2': '¿Qué tengo en el calendario hoy?',
  'chat.suggestion3': 'Busca en la web las últimas noticias',
  'chat.suggestion4': 'Ayúdame a escribir un script',
  'chat.loadingHistory': 'Cargando mensajes…',
  'chat.inputPlaceholder': 'Escribe un mensaje…',
  'chat.inputLabel': 'Mensaje',
  'chat.attachFile': 'Adjuntar archivo',
  'chat.send': 'Enviar',
  'chat.stop': 'Detener',
  'chat.showPreview': 'Vista previa markdown',
  'chat.hidePreview': 'Ocultar vista previa',
  'chat.scrollToBottom': 'Nuevos mensajes',
  'chat.scrollDown': 'Ir al final',
  'chat.collapseTools': 'Contraer todas las herramientas',
  'chat.expandTools': 'Expandir todas las herramientas',
  'chat.messages': 'Mensajes del chat',
  'chat.thinking': 'Pensando…',

  'sidebar.title': 'Sesiones',
  'sidebar.empty': 'Sin sesiones',
  'sidebar.search': 'Buscar sesiones…',
  'sidebar.noResults': 'Sin resultados',
  'sidebar.pin': 'Fijar sesión',
  'sidebar.unpin': 'Desfijar sesión',
  'sidebar.pinned': 'Fijadas',
  'sidebar.delete': 'Eliminar sesión',
  'sidebar.deleteConfirm': '¿Eliminar esta sesión? Esta acción no se puede deshacer.',
  'sidebar.deleteCancel': 'Cancelar',
  'sidebar.openSplit': 'Abrir en vista dividida',
  'sidebar.close': 'Cerrar barra lateral',
  'sidebar.clearSearch': 'Limpiar búsqueda',
  'sidebar.filterAll': 'Todas',
  'sidebar.filterActive': 'Activas',
  'split.close': 'Cerrar vista dividida',
  'app.mainChat': 'Chat principal',
  'app.splitPane': 'Panel dividido',
  'app.skipToChat': 'Ir al campo de entrada',

  'thinking.label': 'Pensamiento',
  'thinking.reasoning': 'Razonando…',

  'tool.parameters': 'Parámetros',
  'tool.result': 'Resultado',

  'connection.reconnecting': 'Conexión perdida — reconectando…',
  'connection.reconnected': '¡Reconectado!',

  'message.copy': 'Copiar mensaje',
  'message.copied': '¡Copiado!',
  'message.retry': 'Reenviar mensaje',
  'message.metadata': 'Detalles del mensaje',
  'message.rawJson': 'JSON sin formato',
  'message.hideRawJson': 'Ocultar JSON sin formato',

  'time.yesterday': 'Ayer',
  'time.today': 'Hoy',

  'shortcuts.title': 'Atajos de teclado',
  'shortcuts.send': 'Enviar mensaje',
  'shortcuts.newline': 'Nueva línea',
  'shortcuts.search': 'Buscar sesiones',
  'shortcuts.switchSession': 'Sesión anterior / siguiente',
  'shortcuts.closeSidebar': 'Cerrar barra / búsqueda',
  'shortcuts.stop': 'Detener generación',
  'shortcuts.help': 'Mostrar atajos',
  'shortcuts.close': 'Cerrar',
  'shortcuts.chatSection': 'Chat',

  'error.title': 'Algo salió mal',
  'error.description': 'Ocurrió un error inesperado al mostrar la interfaz. Puedes intentar de nuevo o recargar la página.',
  'error.retry': 'Reintentar',
  'error.reload': 'Recargar página',
  'shortcuts.navigationSection': 'Navegación',
  'shortcuts.generalSection': 'General',

  'header.export': 'Exportar conversación como Markdown',
  'header.compact': 'Compactar',
  'header.compacting': 'Compactando…',
  'header.sessionInfo': 'Info de sesión',
  'sessionInfo.sessionKey': 'Clave de sesión',
  'sessionInfo.channel': 'Canal',
  'sessionInfo.kind': 'Tipo',
  'sessionInfo.model': 'Modelo',
  'sessionInfo.agent': 'Agente',
  'sessionInfo.messages': 'Mensajes',
  'sessionInfo.totalTokens': 'Tokens totales',
  'sessionInfo.inputTokens': 'Entrada',
  'sessionInfo.outputTokens': 'Salida',
  'sessionInfo.contextWindow': 'Contexto',
  'sessionInfo.lastActive': 'Última actividad',

  'theme.title': 'Tema',
  'theme.mode': 'Modo',
  'theme.accent': 'Acento',
  'theme.system': 'Sistema',
  'theme.dark': 'Oscuro',
  'theme.light': 'Claro',
  'theme.oled': 'OLED',

  'search.placeholder': 'Buscar en mensajes…',
  'search.noResults': '0 resultados',
  'search.prev': 'Resultado anterior',
  'search.next': 'Resultado siguiente',
  'shortcuts.searchMessages': 'Buscar en mensajes',

  'settings.sendShortcut': 'Enviar con',
  'settings.sendEnter': 'Enter',
  'settings.sendCtrlEnter': 'Ctrl+Enter',

  'message.bookmark': 'Marcar mensaje',
  'message.removeBookmark': 'Quitar marcador',
  'chat.bookmarks': 'Marcadores',
  'chat.export': 'Exportar conversación',
  'chat.contextCompacted': 'Contexto compactado — mensajes anteriores en caché local',
  'slash.commands': 'Comandos',
  'slash.status': 'Mostrar estado y uso de la sesión',
  'slash.reasoning': 'Activar/desactivar razonamiento',
  'slash.verbose': 'Activar/desactivar modo detallado',
  'slash.model': 'Cambiar modelo para esta sesión',
  'slash.compact': 'Compactar contexto de conversación',
  'slash.reset': 'Reiniciar la sesión',
  'slash.help': 'Mostrar comandos disponibles',
};

export type TranslationKey = keyof typeof en;

const de: Record<keyof typeof en, string> = {
  'login.title': 'PinchChat',
  'login.subtitle': 'Mit deinem OpenClaw-Gateway verbinden',
  'login.gatewayUrl': 'Gateway-URL',
  'login.token': 'Token',
  'login.tokenPlaceholder': 'Gateway-Token eingeben',
  'login.connect': 'Verbinden',
  'login.connecting': 'Verbinde…',
  'login.showToken': 'Token anzeigen',
  'login.hideToken': 'Token verbergen',
  'login.storedLocally': 'Zugangsdaten werden lokal in deinem Browser gespeichert',
  'login.wsHint': 'URL muss mit ws:// oder wss:// beginnen',

  'header.title': 'PinchChat',
  'header.connected': 'Verbunden',
  'header.disconnected': 'Getrennt',
  'header.logout': 'Abmelden',
  'header.toggleSidebar': 'Seitenleiste ein-/ausblenden',
  'header.changeLanguage': 'Sprache ändern',
  'header.soundOn': 'Benachrichtigungston aktivieren',
  'header.soundOff': 'Benachrichtigungston deaktivieren',

  'chat.welcome': 'PinchChat',
  'chat.welcomeSub': 'Sende eine Nachricht, um zu beginnen',
  'chat.suggestions': 'Probiere z.\u00a0B. …',
  'chat.suggestion1': 'Fasse meine letzten E-Mails zusammen',
  'chat.suggestion2': 'Was steht heute in meinem Kalender?',
  'chat.suggestion3': 'Suche im Web nach aktuellen Nachrichten',
  'chat.suggestion4': 'Hilf mir, ein Skript zu schreiben',
  'chat.loadingHistory': 'Nachrichten werden geladen…',
  'chat.inputPlaceholder': 'Nachricht eingeben…',
  'chat.inputLabel': 'Nachricht',
  'chat.attachFile': 'Datei anhängen',
  'chat.send': 'Senden',
  'chat.stop': 'Stoppen',
  'chat.showPreview': 'Markdown-Vorschau',
  'chat.hidePreview': 'Vorschau ausblenden',
  'chat.scrollToBottom': 'Neue Nachrichten',
  'chat.scrollDown': 'Nach unten scrollen',
  'chat.collapseTools': 'Alle Tools einklappen',
  'chat.expandTools': 'Alle Tools ausklappen',
  'chat.messages': 'Chat-Nachrichten',
  'chat.thinking': 'Denkt nach…',

  'sidebar.title': 'Sitzungen',
  'sidebar.empty': 'Keine Sitzungen',
  'sidebar.search': 'Sitzungen suchen…',
  'sidebar.noResults': 'Keine Treffer',
  'sidebar.pin': 'Sitzung anheften',
  'sidebar.unpin': 'Sitzung lösen',
  'sidebar.pinned': 'Angeheftet',
  'sidebar.delete': 'Sitzung löschen',
  'sidebar.deleteConfirm': 'Diese Sitzung löschen? Dies kann nicht rückgängig gemacht werden.',
  'sidebar.deleteCancel': 'Abbrechen',
  'sidebar.openSplit': 'In geteilter Ansicht öffnen',
  'sidebar.close': 'Seitenleiste schließen',
  'sidebar.clearSearch': 'Suche leeren',
  'sidebar.filterAll': 'Alle',
  'sidebar.filterActive': 'Aktive',
  'split.close': 'Geteilte Ansicht schließen',
  'app.mainChat': 'Haupt-Chat',
  'app.splitPane': 'Geteiltes Fenster',
  'app.skipToChat': 'Zum Eingabefeld springen',

  'thinking.label': 'Nachdenken',
  'thinking.reasoning': 'Denkt nach…',

  'tool.parameters': 'Parameter',
  'tool.result': 'Ergebnis',

  'connection.reconnecting': 'Verbindung verloren — wird wiederhergestellt…',
  'connection.reconnected': 'Wieder verbunden!',

  'message.copy': 'Nachricht kopieren',
  'message.copied': 'Kopiert!',
  'message.retry': 'Nachricht erneut senden',
  'message.metadata': 'Nachrichtendetails',
  'message.rawJson': 'Roh-JSON',
  'message.hideRawJson': 'Roh-JSON ausblenden',

  'time.yesterday': 'Gestern',
  'time.today': 'Heute',

  'shortcuts.title': 'Tastenkürzel',
  'shortcuts.send': 'Nachricht senden',
  'shortcuts.newline': 'Neue Zeile',
  'shortcuts.search': 'Sitzungen suchen',
  'shortcuts.switchSession': 'Vorherige / nächste Sitzung',
  'shortcuts.closeSidebar': 'Seitenleiste / Suche schließen',
  'shortcuts.stop': 'Generierung stoppen',
  'shortcuts.help': 'Tastenkürzel anzeigen',
  'shortcuts.close': 'Schließen',
  'shortcuts.chatSection': 'Chat',

  'error.title': 'Etwas ist schiefgelaufen',
  'error.description': 'Beim Rendern der Oberfläche ist ein unerwarteter Fehler aufgetreten. Du kannst es erneut versuchen oder die Seite neu laden.',
  'error.retry': 'Erneut versuchen',
  'error.reload': 'Seite neu laden',
  'shortcuts.navigationSection': 'Navigation',
  'shortcuts.generalSection': 'Allgemein',

  'header.export': 'Unterhaltung als Markdown exportieren',
  'header.compact': 'Kompaktieren',
  'header.compacting': 'Kompaktiere…',
  'header.sessionInfo': 'Sitzungsinfo',
  'sessionInfo.sessionKey': 'Sitzungsschlüssel',
  'sessionInfo.channel': 'Kanal',
  'sessionInfo.kind': 'Typ',
  'sessionInfo.model': 'Modell',
  'sessionInfo.agent': 'Agent',
  'sessionInfo.messages': 'Nachrichten',
  'sessionInfo.totalTokens': 'Tokens gesamt',
  'sessionInfo.inputTokens': 'Eingabe',
  'sessionInfo.outputTokens': 'Ausgabe',
  'sessionInfo.contextWindow': 'Kontext',
  'sessionInfo.lastActive': 'Letzte Aktivität',

  'theme.title': 'Design',
  'theme.mode': 'Modus',
  'theme.accent': 'Akzent',
  'theme.system': 'System',
  'theme.dark': 'Dunkel',
  'theme.light': 'Hell',
  'theme.oled': 'OLED',

  'search.placeholder': 'In Nachrichten suchen…',
  'search.noResults': '0 Ergebnisse',
  'search.prev': 'Vorheriger Treffer',
  'search.next': 'Nächster Treffer',
  'shortcuts.searchMessages': 'In Nachrichten suchen',

  'settings.sendShortcut': 'Senden mit',
  'settings.sendEnter': 'Enter',
  'settings.sendCtrlEnter': 'Strg+Enter',

  'message.bookmark': 'Nachricht markieren',
  'message.removeBookmark': 'Lesezeichen entfernen',
  'chat.bookmarks': 'Lesezeichen',
  'chat.export': 'Unterhaltung exportieren',
  'chat.contextCompacted': 'Kontext kompaktiert — ältere Nachrichten lokal zwischengespeichert',
  'slash.commands': 'Befehle',
  'slash.status': 'Sitzungsstatus und Nutzung anzeigen',
  'slash.reasoning': 'Reasoning-Modus umschalten',
  'slash.verbose': 'Ausführliche Ausgabe umschalten',
  'slash.model': 'Modell für diese Sitzung wechseln',
  'slash.compact': 'Gesprächskontext kompaktieren',
  'slash.reset': 'Sitzung zurücksetzen',
  'slash.help': 'Verfügbare Befehle anzeigen',
};

const ja: Record<keyof typeof en, string> = {
  'login.title': 'PinchChat',
  'login.subtitle': 'OpenClawゲートウェイに接続',
  'login.gatewayUrl': 'ゲートウェイURL',
  'login.token': 'トークン',
  'login.tokenPlaceholder': 'ゲートウェイトークンを入力',
  'login.connect': '接続',
  'login.connecting': '接続中…',
  'login.showToken': 'トークンを表示',
  'login.hideToken': 'トークンを非表示',
  'login.storedLocally': '認証情報はブラウザにローカル保存されます',
  'login.wsHint': 'URLはws://またはwss://で始まる必要があります',

  'header.title': 'PinchChat',
  'header.connected': '接続済み',
  'header.disconnected': '切断',
  'header.logout': 'ログアウト',
  'header.toggleSidebar': 'サイドバーの表示切替',
  'header.changeLanguage': '言語を変更',
  'header.soundOn': '通知音を有効にする',
  'header.soundOff': '通知音を無効にする',

  'chat.welcome': 'PinchChat',
  'chat.welcomeSub': 'メッセージを送信して始めましょう',
  'chat.suggestions': '例えば…',
  'chat.suggestion1': '最近のメールをまとめて',
  'chat.suggestion2': '今日のカレンダーは？',
  'chat.suggestion3': '最新ニュースをウェブで検索して',
  'chat.suggestion4': 'スクリプトを書くのを手伝って',
  'chat.loadingHistory': 'メッセージを読み込み中…',
  'chat.inputPlaceholder': 'メッセージを入力…',
  'chat.inputLabel': 'メッセージ',
  'chat.attachFile': 'ファイルを添付',
  'chat.send': '送信',
  'chat.stop': '停止',
  'chat.showPreview': 'Markdownプレビュー',
  'chat.hidePreview': 'プレビューを非表示',
  'chat.scrollToBottom': '新しいメッセージ',
  'chat.scrollDown': '一番下へスクロール',
  'chat.collapseTools': 'すべてのツールを折りたたむ',
  'chat.expandTools': 'すべてのツールを展開',
  'chat.messages': 'チャットメッセージ',
  'chat.thinking': '思考中…',

  'sidebar.title': 'セッション',
  'sidebar.empty': 'セッションなし',
  'sidebar.search': 'セッションを検索…',
  'sidebar.noResults': '結果なし',
  'sidebar.pin': 'セッションをピン留め',
  'sidebar.unpin': 'ピン留めを解除',
  'sidebar.pinned': 'ピン留め',
  'sidebar.delete': 'セッションを削除',
  'sidebar.deleteConfirm': 'このセッションを削除しますか？元に戻せません。',
  'sidebar.deleteCancel': 'キャンセル',
  'sidebar.openSplit': '分割ビューで開く',
  'sidebar.close': 'サイドバーを閉じる',
  'sidebar.clearSearch': '検索をクリア',
  'sidebar.filterAll': 'すべて',
  'sidebar.filterActive': 'アクティブ',
  'split.close': '分割ビューを閉じる',
  'app.mainChat': 'メインチャット',
  'app.splitPane': '分割ペイン',
  'app.skipToChat': '入力欄へ移動',

  'thinking.label': '思考',
  'thinking.reasoning': '推論中…',

  'tool.parameters': 'パラメータ',
  'tool.result': '結果',

  'connection.reconnecting': '接続が切断されました — 再接続中…',
  'connection.reconnected': '再接続しました！',

  'message.copy': 'メッセージをコピー',
  'message.copied': 'コピーしました！',
  'message.retry': 'メッセージを再送信',
  'message.metadata': 'メッセージの詳細',
  'message.rawJson': '生JSON',
  'message.hideRawJson': '生JSONを非表示',

  'time.yesterday': '昨日',
  'time.today': '今日',

  'shortcuts.title': 'キーボードショートカット',
  'shortcuts.send': 'メッセージを送信',
  'shortcuts.newline': '改行',
  'shortcuts.search': 'セッションを検索',
  'shortcuts.switchSession': '前 / 次のセッション',
  'shortcuts.closeSidebar': 'サイドバー / 検索を閉じる',
  'shortcuts.stop': '生成を停止',
  'shortcuts.help': 'ショートカットを表示',
  'shortcuts.close': '閉じる',
  'shortcuts.chatSection': 'チャット',

  'error.title': 'エラーが発生しました',
  'error.description': 'インターフェースの表示中に予期しないエラーが発生しました。再試行するかページをリロードしてください。',
  'error.retry': '再試行',
  'error.reload': 'ページをリロード',
  'shortcuts.navigationSection': 'ナビゲーション',
  'shortcuts.generalSection': '全般',

  'header.export': '会話をMarkdownでエクスポート',
  'header.compact': 'コンパクト化',
  'header.compacting': 'コンパクト化中…',
  'header.sessionInfo': 'セッション情報',
  'sessionInfo.sessionKey': 'セッションキー',
  'sessionInfo.channel': 'チャンネル',
  'sessionInfo.kind': '種類',
  'sessionInfo.model': 'モデル',
  'sessionInfo.agent': 'エージェント',
  'sessionInfo.messages': 'メッセージ',
  'sessionInfo.totalTokens': '合計トークン',
  'sessionInfo.inputTokens': '入力',
  'sessionInfo.outputTokens': '出力',
  'sessionInfo.contextWindow': 'コンテキスト',
  'sessionInfo.lastActive': '最終アクティブ',

  'theme.title': 'テーマ',
  'theme.mode': 'モード',
  'theme.accent': 'アクセント',
  'theme.system': 'システム',
  'theme.dark': 'ダーク',
  'theme.light': 'ライト',
  'theme.oled': 'OLED',

  'search.placeholder': 'メッセージを検索…',
  'search.noResults': '0件',
  'search.prev': '前の結果',
  'search.next': '次の結果',
  'shortcuts.searchMessages': 'メッセージを検索',

  'settings.sendShortcut': '送信キー',
  'settings.sendEnter': 'Enter',
  'settings.sendCtrlEnter': 'Ctrl+Enter',

  'message.bookmark': 'メッセージをブックマーク',
  'message.removeBookmark': 'ブックマークを削除',
  'chat.bookmarks': 'ブックマーク',
  'chat.export': '会話をエクスポート',
  'chat.contextCompacted': 'コンテキストがコンパクト化されました — 古いメッセージはローカルキャッシュに保存',
  'slash.commands': 'コマンド',
  'slash.status': 'セッションのステータスと使用量を表示',
  'slash.reasoning': '推論モードの切替',
  'slash.verbose': '詳細出力の切替',
  'slash.model': 'このセッションのモデルを変更',
  'slash.compact': '会話コンテキストをコンパクト化',
  'slash.reset': 'セッションをリセット',
  'slash.help': '利用可能なコマンドを表示',
};

const pt: Record<keyof typeof en, string> = {
  'login.title': 'PinchChat',
  'login.subtitle': 'Conectar ao seu gateway OpenClaw',
  'login.gatewayUrl': 'URL do Gateway',
  'login.token': 'Token',
  'login.tokenPlaceholder': 'Insira o token do gateway',
  'login.connect': 'Conectar',
  'login.connecting': 'Conectando…',
  'login.showToken': 'Mostrar token',
  'login.hideToken': 'Ocultar token',
  'login.storedLocally': 'As credenciais são armazenadas localmente no navegador',
  'login.wsHint': 'A URL deve começar com ws:// ou wss://',

  'header.title': 'PinchChat',
  'header.connected': 'Conectado',
  'header.disconnected': 'Desconectado',
  'header.logout': 'Sair',
  'header.toggleSidebar': 'Alternar barra lateral',
  'header.changeLanguage': 'Alterar idioma',
  'header.soundOn': 'Ativar som de notificação',
  'header.soundOff': 'Desativar som de notificação',

  'chat.welcome': 'PinchChat',
  'chat.welcomeSub': 'Envie uma mensagem para começar',
  'chat.suggestions': 'Tente perguntar…',
  'chat.suggestion1': 'Resuma meus e-mails recentes',
  'chat.suggestion2': 'O que há na minha agenda hoje?',
  'chat.suggestion3': 'Pesquise na web as últimas notícias',
  'chat.suggestion4': 'Ajude-me a escrever um script',
  'chat.loadingHistory': 'Carregando mensagens…',
  'chat.inputPlaceholder': 'Digite uma mensagem…',
  'chat.inputLabel': 'Mensagem',
  'chat.attachFile': 'Anexar arquivo',
  'chat.send': 'Enviar',
  'chat.stop': 'Parar',
  'chat.showPreview': 'Pré-visualizar markdown',
  'chat.hidePreview': 'Ocultar pré-visualização',
  'chat.scrollToBottom': 'Novas mensagens',
  'chat.scrollDown': 'Rolar para baixo',
  'chat.collapseTools': 'Recolher todas as ferramentas',
  'chat.expandTools': 'Expandir todas as ferramentas',
  'chat.messages': 'Mensagens do chat',
  'chat.thinking': 'Pensando…',

  'sidebar.title': 'Sessões',
  'sidebar.empty': 'Nenhuma sessão',
  'sidebar.search': 'Pesquisar sessões…',
  'sidebar.noResults': 'Nenhuma sessão encontrada',
  'sidebar.pin': 'Fixar sessão',
  'sidebar.unpin': 'Desafixar sessão',
  'sidebar.pinned': 'Fixada',
  'sidebar.delete': 'Excluir sessão',
  'sidebar.deleteConfirm': 'Excluir esta sessão? Esta ação não pode ser desfeita.',
  'sidebar.deleteCancel': 'Cancelar',
  'sidebar.openSplit': 'Abrir em visualização dividida',
  'sidebar.close': 'Fechar barra lateral',
  'sidebar.clearSearch': 'Limpar pesquisa',
  'sidebar.filterAll': 'Todas',
  'sidebar.filterActive': 'Ativas',
  'split.close': 'Fechar visualização dividida',
  'app.mainChat': 'Chat principal',
  'app.splitPane': 'Painel dividido',
  'app.skipToChat': 'Ir para o campo de entrada',

  'thinking.label': 'Pensamento',
  'thinking.reasoning': 'Raciocinando…',

  'tool.parameters': 'Parâmetros',
  'tool.result': 'Resultado',

  'connection.reconnecting': 'Conexão perdida — reconectando…',
  'connection.reconnected': 'Reconectado!',

  'message.copy': 'Copiar mensagem',
  'message.copied': 'Copiado!',
  'message.retry': 'Reenviar mensagem',
  'message.metadata': 'Detalhes da mensagem',
  'message.rawJson': 'JSON bruto',
  'message.hideRawJson': 'Ocultar JSON bruto',

  'time.yesterday': 'Ontem',
  'time.today': 'Hoje',

  'shortcuts.title': 'Atalhos de teclado',
  'shortcuts.send': 'Enviar mensagem',
  'shortcuts.newline': 'Nova linha',
  'shortcuts.search': 'Pesquisar sessões',
  'shortcuts.switchSession': 'Sessão anterior / próxima',
  'shortcuts.closeSidebar': 'Fechar barra lateral / pesquisa',
  'shortcuts.stop': 'Parar geração',
  'shortcuts.help': 'Mostrar atalhos',
  'shortcuts.close': 'Fechar',
  'shortcuts.chatSection': 'Chat',

  'error.title': 'Algo deu errado',
  'error.description': 'Ocorreu um erro inesperado ao renderizar a interface. Tente novamente ou recarregue a página.',
  'error.retry': 'Tentar novamente',
  'error.reload': 'Recarregar página',
  'shortcuts.navigationSection': 'Navegação',
  'shortcuts.generalSection': 'Geral',

  'header.export': 'Exportar conversa em Markdown',
  'header.compact': 'Compactar',
  'header.compacting': 'Compactando…',
  'header.sessionInfo': 'Informações da sessão',
  'sessionInfo.sessionKey': 'Chave da sessão',
  'sessionInfo.channel': 'Canal',
  'sessionInfo.kind': 'Tipo',
  'sessionInfo.model': 'Modelo',
  'sessionInfo.agent': 'Agente',
  'sessionInfo.messages': 'Mensagens',
  'sessionInfo.totalTokens': 'Total de tokens',
  'sessionInfo.inputTokens': 'Entrada',
  'sessionInfo.outputTokens': 'Saída',
  'sessionInfo.contextWindow': 'Contexto',
  'sessionInfo.lastActive': 'Última atividade',

  'theme.title': 'Tema',
  'theme.mode': 'Modo',
  'theme.accent': 'Cor de destaque',
  'theme.system': 'Sistema',
  'theme.dark': 'Escuro',
  'theme.light': 'Claro',
  'theme.oled': 'OLED',

  'search.placeholder': 'Pesquisar mensagens…',
  'search.noResults': '0 resultados',
  'search.prev': 'Resultado anterior',
  'search.next': 'Próximo resultado',
  'shortcuts.searchMessages': 'Pesquisar mensagens',

  'settings.sendShortcut': 'Tecla de envio',
  'settings.sendEnter': 'Enter',
  'settings.sendCtrlEnter': 'Ctrl+Enter',

  'message.bookmark': 'Marcar mensagem',
  'message.removeBookmark': 'Remover marcador',
  'chat.bookmarks': 'Marcadores',
  'chat.export': 'Exportar conversa',
  'chat.contextCompacted': 'Contexto compactado — mensagens antigas salvas no cache local',
  'slash.commands': 'Comandos',
  'slash.status': 'Mostrar status e uso da sessão',
  'slash.reasoning': 'Alternar modo de raciocínio',
  'slash.verbose': 'Alternar saída detalhada',
  'slash.model': 'Alterar modelo desta sessão',
  'slash.compact': 'Compactar contexto da conversa',
  'slash.reset': 'Redefinir sessão',
  'slash.help': 'Mostrar comandos disponíveis',
};

const zh: Record<keyof typeof en, string> = {
  'login.title': 'PinchChat',
  'login.subtitle': '连接到您的 OpenClaw 网关',
  'login.gatewayUrl': '网关地址',
  'login.token': '令牌',
  'login.tokenPlaceholder': '输入网关令牌',
  'login.connect': '连接',
  'login.connecting': '连接中…',
  'login.showToken': '显示令牌',
  'login.hideToken': '隐藏令牌',
  'login.storedLocally': '凭据仅存储在浏览器本地',
  'login.wsHint': '地址必须以 ws:// 或 wss:// 开头',

  'header.title': 'PinchChat',
  'header.connected': '已连接',
  'header.disconnected': '未连接',
  'header.logout': '退出',
  'header.toggleSidebar': '切换侧边栏',
  'header.changeLanguage': '切换语言',
  'header.soundOn': '开启通知音',
  'header.soundOff': '关闭通知音',

  'chat.welcome': 'PinchChat',
  'chat.welcomeSub': '发送消息开始对话',
  'chat.suggestions': '试试问…',
  'chat.suggestion1': '总结我最近的邮件',
  'chat.suggestion2': '今天的日程安排是什么？',
  'chat.suggestion3': '搜索最新新闻',
  'chat.suggestion4': '帮我写一个脚本',
  'chat.loadingHistory': '加载消息中…',
  'chat.inputPlaceholder': '输入消息…',
  'chat.inputLabel': '消息',
  'chat.attachFile': '添加附件',
  'chat.send': '发送',
  'chat.stop': '停止',
  'chat.showPreview': '预览 Markdown',
  'chat.hidePreview': '隐藏预览',
  'chat.scrollToBottom': '新消息',
  'chat.scrollDown': '滚动到底部',
  'chat.collapseTools': '折叠所有工具',
  'chat.expandTools': '展开所有工具',
  'chat.messages': '聊天消息',
  'chat.thinking': '思考中…',

  'sidebar.title': '会话',
  'sidebar.empty': '没有会话',
  'sidebar.search': '搜索会话…',
  'sidebar.noResults': '未找到匹配会话',
  'sidebar.pin': '置顶会话',
  'sidebar.unpin': '取消置顶',
  'sidebar.pinned': '已置顶',
  'sidebar.delete': '删除会话',
  'sidebar.deleteConfirm': '删除此会话？此操作无法撤消。',
  'sidebar.deleteCancel': '取消',
  'sidebar.openSplit': '在分屏中打开',
  'sidebar.close': '关闭侧边栏',
  'sidebar.clearSearch': '清除搜索',
  'sidebar.filterAll': '全部',
  'sidebar.filterActive': '活跃',
  'split.close': '关闭分屏',
  'app.mainChat': '主聊天',
  'app.splitPane': '分屏面板',
  'app.skipToChat': '跳转到输入框',

  'thinking.label': '思考',
  'thinking.reasoning': '推理中…',

  'tool.parameters': '参数',
  'tool.result': '结果',

  'connection.reconnecting': '连接中断 — 正在重连…',
  'connection.reconnected': '已重新连接！',

  'message.copy': '复制消息',
  'message.copied': '已复制！',
  'message.retry': '重新发送',
  'message.metadata': '消息详情',
  'message.rawJson': '原始 JSON',
  'message.hideRawJson': '隐藏原始 JSON',

  'time.yesterday': '昨天',
  'time.today': '今天',

  'shortcuts.title': '键盘快捷键',
  'shortcuts.send': '发送消息',
  'shortcuts.newline': '换行',
  'shortcuts.search': '搜索会话',
  'shortcuts.switchSession': '上一个 / 下一个会话',
  'shortcuts.closeSidebar': '关闭侧边栏 / 搜索',
  'shortcuts.stop': '停止生成',
  'shortcuts.help': '显示快捷键',
  'shortcuts.close': '关闭',
  'shortcuts.chatSection': '聊天',

  'error.title': '出错了',
  'error.description': '渲染界面时发生意外错误。您可以重试或刷新页面。',
  'error.retry': '重试',
  'error.reload': '刷新页面',
  'shortcuts.navigationSection': '导航',
  'shortcuts.generalSection': '通用',

  'header.export': '导出会话为 Markdown',
  'header.compact': '压缩',
  'header.compacting': '压缩中…',
  'header.sessionInfo': '会话信息',
  'sessionInfo.sessionKey': '会话密钥',
  'sessionInfo.channel': '频道',
  'sessionInfo.kind': '类型',
  'sessionInfo.model': '模型',
  'sessionInfo.agent': '智能体',
  'sessionInfo.messages': '消息数',
  'sessionInfo.totalTokens': '总令牌数',
  'sessionInfo.inputTokens': '输入',
  'sessionInfo.outputTokens': '输出',
  'sessionInfo.contextWindow': '上下文',
  'sessionInfo.lastActive': '最后活跃',

  'theme.title': '主题',
  'theme.mode': '模式',
  'theme.accent': '强调色',
  'theme.system': '跟随系统',
  'theme.dark': '深色',
  'theme.light': '浅色',
  'theme.oled': 'OLED',

  'search.placeholder': '搜索消息…',
  'search.noResults': '无结果',
  'search.prev': '上一个',
  'search.next': '下一个',
  'shortcuts.searchMessages': '搜索消息',

  'settings.sendShortcut': '发送方式',
  'settings.sendEnter': 'Enter',
  'settings.sendCtrlEnter': 'Ctrl+Enter',

  'message.bookmark': '收藏消息',
  'message.removeBookmark': '取消收藏',
  'chat.bookmarks': '收藏',
  'chat.export': '导出会话',
  'chat.contextCompacted': '上下文已压缩 — 旧消息已缓存到本地',
  'slash.commands': '命令',
  'slash.status': '显示会话状态和用量',
  'slash.reasoning': '切换推理模式',
  'slash.verbose': '切换详细输出',
  'slash.model': '切换当前会话模型',
  'slash.compact': '压缩会话上下文',
  'slash.reset': '重置会话',
  'slash.help': '显示可用命令',
};

const messages: Record<string, Record<string, string>> = { en, fr, es, de, ja, pt, zh };

export const supportedLocales = Object.keys(messages) as string[];

/** Labels shown in the language selector */
export const localeLabels: Record<string, string> = {
  en: 'EN',
  fr: 'FR',
  es: 'ES',
  de: 'DE',
  ja: 'JA',
  pt: 'PT',
  zh: '中文',
};

function resolveInitialLocale(): string {
  // 1. localStorage
  try {
    const stored = localStorage.getItem(STORAGE_KEY);
    if (stored && messages[stored]) return stored;
  } catch { /* SSR or blocked storage */ }

  // 2. VITE_LOCALE env var
  const envLocale = (import.meta.env.VITE_LOCALE as string) || '';
  if (envLocale && messages[envLocale]) return envLocale;

  // 3. navigator.language
  if (typeof navigator !== 'undefined') {
    const navLang = navigator.language?.split('-')[0];
    if (navLang && messages[navLang]) return navLang;
  }

  // 4. fallback
  return 'en';
}

let currentLocale = resolveInitialLocale();
let dict = messages[currentLocale] || messages.en;

// Sync <html lang> on initial load
try { document.documentElement.lang = currentLocale; } catch { /* SSR */ }

type Listener = () => void;
const listeners = new Set<Listener>();

/** Subscribe to locale changes. Returns unsubscribe function. */
export function onLocaleChange(fn: Listener): () => void {
  listeners.add(fn);
  return () => listeners.delete(fn);
}

/** Get the current locale code */
export function getLocale(): string {
  return currentLocale;
}

/** Switch locale at runtime. Persists to localStorage and notifies subscribers. */
export function setLocale(loc: string): void {
  if (!messages[loc] || loc === currentLocale) return;
  currentLocale = loc;
  dict = messages[loc];
  try { localStorage.setItem(STORAGE_KEY, loc); } catch { /* noop */ }
  try { document.documentElement.lang = loc; } catch { /* SSR */ }
  listeners.forEach((fn) => fn());
}

/** Return the translated string for the given key, falling back to English. */
export function t(key: TranslationKey): string {
  return dict[key] ?? (messages.en as Record<string, string>)[key] ?? key;
}

// Keep backward-compat named export
export { currentLocale as locale };
