import { useCallback, useMemo } from "react";

type Locale = "en" | "fr";

const translations = {
  en: {
    "app.name": "Negopoly Bank",
    "common.loading": "Loading...",
    "common.notice": "Notice:",
    "common.reset": "Reset",
    "common.guest": "Guest",
    "common.dummy": "Dummy",
    "common.player": "Player",
    "common.banker": "Banker",
    "common.bank": "Bank",
    "common.online": "online",
    "common.offline": "Offline",
    "common.name": "Name",
    "common.startingBalance": "Starting balance",
    "common.selectPlayer": "Select player",
    "common.reason": "Reason",
    "common.amount": "Amount",
    "common.note": "Note",
    "common.noReason": "No reason provided",
    "common.from": "From",
    "common.to": "To",
    "common.apply": "Apply",
    "common.force": "Force",
    "common.trigger": "Trigger",
    "common.send": "Send",
    "common.download": "Download",
    "common.load": "Load",
    "common.save": "Save",
    "common.transactions": "Transactions",
    "common.noActivity": "No activity yet.",
    "common.connecting": "Connecting to session {id}...",
    "common.sessionLive": "Session {code} · live",
    "common.continue": "Continue",
    "tabs.dashboard": "Dashboard",
    "tabs.tools": "Tools",
    "tabs.home": "Home",
    "tabs.transfers": "Transfers",
    "tabs.chat": "Chat",
    "entry.tagline": "Open a lobby or join the city.",
    "entry.liveSessions": "Live sessions",
    "entry.bankerControlled": "Banker controlled",
    "entry.createTitle": "Create a session",
    "entry.createSubtitle": "Become the banker and control the flow of money.",
    "entry.bankerName": "Banker name",
    "entry.openVault": "Open the vault",
    "entry.joinTitle": "Join a session",
    "entry.joinSubtitle": "Enter a session code to continue.",
    "entry.sessionCode": "Session code",
    "entry.codePlaceholder": "Enter code",
    "entry.newPlayerLabel": "Create a new player",
    "entry.playerName": "Player name",
    "entry.joinAsNew": "Join as new player",
    "entry.takeoverTitle": "Take over a dummy",
    "entry.alreadyConnected": "You are already connected to this session.",
    "entry.selectDummy": "Select dummy",
    "entry.yourNameOptional": "Your name (optional)",
    "entry.requestTakeover": "Request takeover",
    "entry.noDummies": "No dummies available to take over yet.",
    "entry.changeCode": "Change code",
    "entry.alert.enterCode": "Enter a session code",
    "entry.alert.sessionNotFound": "Session not found",
    "entry.alert.selectDummy": "Select a dummy player",
    "lobby.title": "Negopoly Lobby",
    "lobby.sessionLabel": "Session {id}",
    "lobby.joinTitle": "Join this lobby",
    "lobby.loadingInfo": "Loading session info...",
    "lobby.waitingState": "Waiting for the lobby state.",
    "lobby.header": "Lobby · Session {code}",
    "lobby.statusLine": "Status: {status} · {count} players",
    "lobby.roster": "Lobby roster",
    "lobby.startGame": "Start the game",
    "lobby.waitingBanker": "Waiting for the banker to start the game.",
    "lobby.sessionClosed": "Session closed.",
    "lobby.inviteQr": "Invite QR",
    "lobby.scanToJoin": "Scan to join this lobby instantly.",
    "lobby.addDummyTitle": "Add dummy player",
    "lobby.addDummySubtitle":
      "Create a player for someone without the app. Dummies can be taken over later.",
    "lobby.enterDummyName": "Enter a dummy name",
    "lobby.addDummyButton": "Add dummy",
    "lobby.errorLoadInfo": "Unable to load session info",
    "banker.consoleTitle": "Banker Console",
    "banker.controlsTitle": "Banker controls",
    "banker.tools.playersTab": "Players",
    "banker.tools.adminTab": "Admin",
    "banker.playersTitle": "Players",
    "banker.playerOverview": "Player overview",
    "banker.noPlayers": "No players yet.",
    "banker.adminControls": "Session controls",
    "banker.adjustBalance": "Adjust balance",
    "banker.adjustAmountPlaceholder": "+/- amount",
    "banker.forceTransfer": "Force transfer",
    "banker.createDummy": "Create dummy",
    "banker.dummyName": "Dummy name",
    "banker.addDummy": "Add dummy",
    "banker.blackout": "EMP",
    "banker.blackoutToggle": "Toggle EMP",
    "banker.blackoutEnable": "Enable EMP",
    "banker.blackoutDisable": "Disable EMP",
    "banker.blackoutReason": "EMP reason",
    "banker.endSession": "End session",
    "banker.takeoverApprovals": "Takeover approvals",
    "banker.wants": "Wants {name}",
    "banker.approve": "Approve",
    "banker.stateTitle": "GameState",
    "banker.stateSubtitle": "Export, import, or resume a session from a saved snapshot.",
    "banker.downloadState": "Download current GameState",
    "banker.loadFromFile": "Load GameState from file",
    "banker.loadFromStorage": "Load from browser storage",
    "banker.stateDownloaded": "GameState downloaded.",
    "banker.stateDownloadError": "Unable to download GameState.",
    "banker.stateLoaded": "GameState loaded.",
    "banker.stateLoadError": "Unable to load GameState.",
    "banker.stateLoadInvalid": "Invalid GameState file.",
    "banker.autosaveTitle": "AutoSave",
    "banker.autosaveSubtitle": "Keep rolling backups in this browser.",
    "banker.autosaveToggle": "Enable AutoSave",
    "banker.autosaveEnabled": "AutoSave is enabled",
    "banker.autosaveInterval": "Minutes between saves",
    "banker.autosaveMinutes": "e.g. 3",
    "banker.autosaveKeep": "Snapshots to keep",
    "banker.autosaveCount": "e.g. 5",
    "banker.autosaveNow": "Save now",
    "banker.autosaveSaved": "AutoSave captured.",
    "banker.autosaveFailed": "AutoSave failed.",
    "banker.noAutosaves": "No autosaves yet.",
    "banker.savedAt": "Saved {time}",
    "player.deskTitle": "Player Desk",
    "player.quickTransfer": "Quick transfer",
    "player.sendTo": "Send to",
    "player.noteOptional": "Note (optional)",
    "player.notePlaceholder": "For what?",
    "player.sendFunds": "Send funds",
    "transfers.error": "Choose a player and a valid amount.",
    "player.lastUpdated": "Last updated {time}",
    "home.balance": "Balance",
    "blackout.title": "EMP",
    "blackout.defaultReason": "EMP in effect",
    "blackout.active": "EMP active",
    "chat.title": "Chats",
    "chat.global": "Global chat",
    "chat.conversationCount": "{count} conversations",
    "chat.conversationCountOne": "1 conversation",
    "chat.searchPlaceholder": "Search chats",
    "chat.newTitle": "New chat",
    "chat.newSubtitle": "Start a direct or group conversation",
    "chat.direct": "Direct",
    "chat.group": "Group",
    "chat.groupName": "Group name",
    "chat.groupPlaceholder": "e.g. Negotiators",
    "chat.choosePlayers": "Choose players",
    "chat.noPlayers": "No other players available yet.",
    "chat.back": "Back",
    "chat.backChats": "Chats",
    "chat.noMessages": "No messages yet.",
    "chat.startConversation": "Start the conversation.",
    "chat.messagePlaceholder": "Message",
    "chat.startChat": "Start chat",
    "chat.everyone": "Everyone in the session",
    "chat.directMessage": "Direct message",
    "chat.memberCount": "{count} members",
    "chat.memberCountOne": "1 member",
    "chat.error.direct": "Choose one person to start a direct chat.",
    "chat.error.groupName": "Give the group a name.",
    "chat.error.member": "Select at least one member.",
    "transaction.transfer": "Transfer",
    "transaction.banker_adjust": "Banker adjustment",
    "transaction.banker_force_transfer": "Forced transfer",
    "status.lobby": "Lobby",
    "status.active": "Active",
    "status.ended": "Ended",
    "connection.idle": "idle",
    "connection.connecting": "connecting",
    "connection.open": "connected",
    "connection.error": "error",
    "error.parseResponse": "Unable to parse server response",
    "error.createSession": "Unable to create session",
    "error.joinSession": "Unable to join session",
    "error.connectionNotReady": "Connection not ready",
  },
  fr: {
    "app.name": "Banque Negopoly",
    "common.loading": "Chargement...",
    "common.notice": "Info :",
    "common.reset": "Réinitialiser",
    "common.guest": "Invité",
    "common.dummy": "Dummy",
    "common.player": "Joueur",
    "common.banker": "Banquier",
    "common.bank": "Banque",
    "common.online": "en ligne",
    "common.offline": "Hors ligne",
    "common.name": "Nom",
    "common.startingBalance": "Solde de départ",
    "common.selectPlayer": "Choisir un joueur",
    "common.reason": "Raison",
    "common.amount": "Montant",
    "common.note": "Note",
    "common.noReason": "Aucune raison fournie",
    "common.from": "De",
    "common.to": "À",
    "common.apply": "Appliquer",
    "common.force": "Forcer",
    "common.trigger": "Déclencher",
    "common.send": "Envoyer",
    "common.download": "Télécharger",
    "common.load": "Charger",
    "common.save": "Enregistrer",
    "common.transactions": "Transactions",
    "common.noActivity": "Aucune activité.",
    "common.connecting": "Connexion à la session {id}...",
    "common.sessionLive": "Session {code} · en direct",
    "common.continue": "Continuer",
    "tabs.dashboard": "Tableau",
    "tabs.tools": "Outils",
    "tabs.home": "Accueil",
    "tabs.transfers": "Transferts",
    "tabs.chat": "Chat",
    "entry.tagline": "Ouvrez un lobby ou rejoignez la ville.",
    "entry.liveSessions": "Sessions en direct",
    "entry.bankerControlled": "Contrôlé par le banquier",
    "entry.createTitle": "Créer une session",
    "entry.createSubtitle": "Devenez banquier et contrôlez le flux d'argent.",
    "entry.bankerName": "Nom du banquier",
    "entry.openVault": "Ouvrir le coffre",
    "entry.joinTitle": "Rejoindre une session",
    "entry.joinSubtitle": "Entrez un code pour continuer.",
    "entry.sessionCode": "Code de session",
    "entry.codePlaceholder": "Entrez le code",
    "entry.newPlayerLabel": "Créer un nouveau joueur",
    "entry.playerName": "Nom du joueur",
    "entry.joinAsNew": "Rejoindre comme nouveau joueur",
    "entry.takeoverTitle": "Reprendre un dummy",
    "entry.alreadyConnected": "Vous êtes déjà connecté à cette session.",
    "entry.selectDummy": "Choisir un dummy",
    "entry.yourNameOptional": "Votre nom (optionnel)",
    "entry.requestTakeover": "Demander la reprise",
    "entry.noDummies": "Aucun dummy disponible pour le moment.",
    "entry.changeCode": "Changer de code",
    "entry.alert.enterCode": "Entrez un code de session",
    "entry.alert.sessionNotFound": "Session introuvable",
    "entry.alert.selectDummy": "Sélectionnez un dummy",
    "lobby.title": "Lobby Negopoly",
    "lobby.sessionLabel": "Session {id}",
    "lobby.joinTitle": "Rejoindre ce lobby",
    "lobby.loadingInfo": "Chargement des infos de session...",
    "lobby.waitingState": "En attente de l'état du lobby.",
    "lobby.header": "Lobby · Session {code}",
    "lobby.statusLine": "Statut : {status} · {count} joueurs",
    "lobby.roster": "Liste des joueurs",
    "lobby.startGame": "Démarrer la partie",
    "lobby.waitingBanker": "En attente du banquier pour démarrer.",
    "lobby.sessionClosed": "Session terminée.",
    "lobby.inviteQr": "QR d'invitation",
    "lobby.scanToJoin": "Scannez pour rejoindre instantanément.",
    "lobby.addDummyTitle": "Ajouter un dummy",
    "lobby.addDummySubtitle":
      "Créez un joueur pour quelqu'un sans l'application. Les dummies peuvent être repris.",
    "lobby.enterDummyName": "Entrez un nom de dummy",
    "lobby.addDummyButton": "Ajouter un dummy",
    "lobby.errorLoadInfo": "Impossible de charger les infos de session",
    "banker.consoleTitle": "Console banquier",
    "banker.controlsTitle": "Contrôles banquier",
    "banker.tools.playersTab": "Joueurs",
    "banker.tools.adminTab": "Admin",
    "banker.playersTitle": "Joueurs",
    "banker.playerOverview": "Vue joueur",
    "banker.noPlayers": "Pas encore de joueurs.",
    "banker.adminControls": "Contrôles de session",
    "banker.adjustBalance": "Ajuster le solde",
    "banker.adjustAmountPlaceholder": "Montant +/-",
    "banker.forceTransfer": "Forcer un transfert",
    "banker.createDummy": "Créer un dummy",
    "banker.dummyName": "Nom du dummy",
    "banker.addDummy": "Ajouter un dummy",
    "banker.blackout": "EMP",
    "banker.blackoutToggle": "Basculer l'EMP",
    "banker.blackoutEnable": "Activer l'EMP",
    "banker.blackoutDisable": "Désactiver l'EMP",
    "banker.blackoutReason": "Raison de l'EMP",
    "banker.endSession": "Terminer la session",
    "banker.takeoverApprovals": "Approbations de reprise",
    "banker.wants": "Veut {name}",
    "banker.approve": "Approuver",
    "banker.stateTitle": "État de partie",
    "banker.stateSubtitle": "Exportez, importez ou reprenez une partie depuis une sauvegarde.",
    "banker.downloadState": "Télécharger l'état actuel",
    "banker.loadFromFile": "Charger un état depuis un fichier",
    "banker.loadFromStorage": "Charger depuis le navigateur",
    "banker.stateDownloaded": "État téléchargé.",
    "banker.stateDownloadError": "Impossible de télécharger l'état.",
    "banker.stateLoaded": "État chargé.",
    "banker.stateLoadError": "Impossible de charger l'état.",
    "banker.stateLoadInvalid": "Fichier d'état invalide.",
    "banker.autosaveTitle": "AutoSave",
    "banker.autosaveSubtitle": "Conservez des sauvegardes dans ce navigateur.",
    "banker.autosaveToggle": "Activer AutoSave",
    "banker.autosaveEnabled": "AutoSave activé",
    "banker.autosaveInterval": "Minutes entre sauvegardes",
    "banker.autosaveMinutes": "ex. 3",
    "banker.autosaveKeep": "Sauvegardes à conserver",
    "banker.autosaveCount": "ex. 5",
    "banker.autosaveNow": "Sauvegarder maintenant",
    "banker.autosaveSaved": "Sauvegarde effectuée.",
    "banker.autosaveFailed": "Échec de la sauvegarde.",
    "banker.noAutosaves": "Aucune sauvegarde.",
    "banker.savedAt": "Sauvé {time}",
    "player.deskTitle": "Bureau joueur",
    "player.quickTransfer": "Transfert rapide",
    "player.sendTo": "Envoyer à",
    "player.noteOptional": "Note (optionnel)",
    "player.notePlaceholder": "Pour quoi ?",
    "player.sendFunds": "Envoyer les fonds",
    "transfers.error": "Choisissez un joueur et un montant valide.",
    "player.lastUpdated": "Mis à jour {time}",
    "home.balance": "Solde",
    "blackout.title": "EMP",
    "blackout.defaultReason": "EMP en cours",
    "blackout.active": "EMP actif",
    "chat.title": "Chats",
    "chat.global": "Chat global",
    "chat.conversationCount": "{count} conversations",
    "chat.conversationCountOne": "1 conversation",
    "chat.searchPlaceholder": "Rechercher un chat",
    "chat.newTitle": "Nouveau chat",
    "chat.newSubtitle": "Démarrer une conversation directe ou de groupe",
    "chat.direct": "Direct",
    "chat.group": "Groupe",
    "chat.groupName": "Nom du groupe",
    "chat.groupPlaceholder": "ex. Négociateurs",
    "chat.choosePlayers": "Choisir des joueurs",
    "chat.noPlayers": "Aucun autre joueur disponible.",
    "chat.back": "Retour",
    "chat.backChats": "Chats",
    "chat.noMessages": "Aucun message.",
    "chat.startConversation": "Démarrez la conversation.",
    "chat.messagePlaceholder": "Message",
    "chat.startChat": "Démarrer le chat",
    "chat.everyone": "Tout le monde dans la session",
    "chat.directMessage": "Message direct",
    "chat.memberCount": "{count} membres",
    "chat.memberCountOne": "1 membre",
    "chat.error.direct": "Choisissez une personne pour un chat direct.",
    "chat.error.groupName": "Donnez un nom au groupe.",
    "chat.error.member": "Sélectionnez au moins un membre.",
    "transaction.transfer": "Transfert",
    "transaction.banker_adjust": "Ajustement banquier",
    "transaction.banker_force_transfer": "Transfert forcé",
    "status.lobby": "Lobby",
    "status.active": "Active",
    "status.ended": "Terminée",
    "connection.idle": "inactif",
    "connection.connecting": "connexion",
    "connection.open": "connecté",
    "connection.error": "erreur",
    "error.parseResponse": "Impossible de lire la réponse du serveur",
    "error.createSession": "Impossible de créer la session",
    "error.joinSession": "Impossible de rejoindre la session",
    "error.connectionNotReady": "Connexion non prête",
  },
} as const;

type I18nKey = keyof typeof translations.en;

export function getLocale(): Locale {
  if (typeof navigator !== "undefined") {
    const raw = (navigator.languages?.[0] ?? navigator.language ?? "en").toLowerCase();
    return raw.startsWith("fr") ? "fr" : "en";
  }
  return "en";
}

function translate(locale: Locale, key: I18nKey, vars?: Record<string, string | number>) {
  const table = translations[locale] ?? translations.en;
  let template = table[key] ?? translations.en[key] ?? key;
  if (vars) {
    Object.entries(vars).forEach(([name, value]) => {
      template = template.replace(new RegExp(`\\{${name}\\}`, "g"), String(value));
    });
  }
  return template;
}

export function useI18n() {
  const locale = useMemo(getLocale, []);
  const t = useCallback(
    (key: I18nKey, vars?: Record<string, string | number>) => translate(locale, key, vars),
    [locale],
  );
  return { t, locale };
}

export function tStatic(key: I18nKey, vars?: Record<string, string | number>) {
  return translate(getLocale(), key, vars);
}

export function formatTransactionKind(
  kind: "transfer" | "banker_adjust" | "banker_force_transfer",
  t: (key: I18nKey) => string,
) {
  return t(`transaction.${kind}` as I18nKey);
}

export function formatStatus(
  status: "lobby" | "active" | "ended",
  t: (key: I18nKey) => string,
) {
  return t(`status.${status}` as I18nKey);
}

export function formatConnectionState(
  state: "idle" | "connecting" | "open" | "error",
  t: (key: I18nKey) => string,
) {
  return t(`connection.${state}` as I18nKey);
}
