//! Internacionalización — diccionarios embebidos es/en/pt.
//!
//! Se inicializa una sola vez en `main()` antes de construir la UI. Cambiar el
//! idioma en vivo requeriría reconstruir todos los widgets; en su lugar se le
//! pide al usuario reiniciar la aplicación tras cambiar el idioma.
//!
//! Fase 1 (radio-player v0.4.3): cubre títulos de ventanas, diálogos comunes,
//! botones de toolbar y labels más visibles. Strings de logs, errores internos
//! y sub-paneles más profundos quedan en español hasta una segunda iteración.

use std::sync::OnceLock;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Locale { Es, En, Pt }

impl Locale {
    pub fn code(self) -> &'static str {
        match self { Locale::Es=>"es", Locale::En=>"en", Locale::Pt=>"pt" }
    }
    pub fn from_code(c: &str) -> Option<Self> {
        match c { "es"=>Some(Locale::Es), "en"=>Some(Locale::En), "pt"=>Some(Locale::Pt), _=>None }
    }
}

static LOCALE: OnceLock<Locale> = OnceLock::new();

/// Inicializa el locale activo. Prioridad: `forced` > env > `en`.
pub fn init(forced: Option<&str>) -> Locale {
    let lc = forced
        .and_then(Locale::from_code)
        .or_else(detect_from_env)
        .unwrap_or(Locale::En);
    let _ = LOCALE.set(lc);
    lc
}

fn detect_from_env() -> Option<Locale> {
    let raw = std::env::var("LC_ALL").ok().filter(|s| !s.is_empty())
        .or_else(|| std::env::var("LC_MESSAGES").ok().filter(|s| !s.is_empty()))
        .or_else(|| std::env::var("LANG").ok().filter(|s| !s.is_empty()))?;
    let code = raw.split(['.', '_', '@']).next()?.to_lowercase();
    Locale::from_code(&code)
}

#[inline]
pub fn current() -> Locale {
    *LOCALE.get().unwrap_or(&Locale::En)
}

/// Devuelve la traducción para `key` en el idioma activo.
/// Si no hay traducción cae a inglés, y si tampoco existe devuelve la key.
pub fn tr(key: &str) -> &'static str {
    let dict: Dict = match current() {
        Locale::Es => ES,
        Locale::En => EN,
        Locale::Pt => PT,
    };
    for (k, v) in dict { if *k == key { return v; } }
    for (k, v) in EN   { if *k == key { return v; } }
    Box::leak(key.to_string().into_boxed_str())
}

type Dict = &'static [(&'static str, &'static str)];

const ES: Dict = &[
    // Títulos de ventana
    ("win.player",          "G Radio Player"),
    ("win.pautaje",         "GR Pautaje"),
    ("win.processor",       "GR Procesador DSP"),
    ("win.config",          "Configuración GR"),
    // Botones comunes
    ("btn.ok",              "OK"),
    ("btn.cancel",          "Cancelar"),
    ("btn.save",            "Guardar"),
    ("btn.close",           "Cerrar"),
    ("btn.interrupt",       "Interrumpir"),
    ("btn.generate",        "Generar"),
    ("btn.all",             "Todos"),
    ("btn.choose_folder",   "Elegir carpeta"),
    ("btn.edit_list",       "✏ Editar lista…"),
    ("btn.select",          "Seleccionar"),
    ("btn.operador",        "🎛 Operador"),
    // Display "now playing"
    ("now.stopped_end",     "⏹ Detenido al final del tema"),
    ("now.app_name",        "G Radio Player"),
    ("now.no_track",        "Sin tema"),
    ("now.stopped_after",   "Se detuvo: Detener después"),
    ("now.no_ad",           "Sin comercial"),
    // Decks
    ("deck.a",              "🎵 Deck A (temas impares)"),
    ("deck.b",              "🎵 Deck B (temas pares)"),
    // Tooltips de toolbar
    ("tool.start",          "Iniciar reproducción"),
    ("tool.stop_general",   "Stop General — detiene parrilla, comerciales y eventos"),
    ("tool.next",           "Siguiente tema"),
    ("tool.hora",           "Reproducir hora"),
    ("tool.pisador",        "Pisador"),
    ("tool.duck",           "Bajar música (duck)"),
    ("tool.buscador",       "Buscador de audio"),
    ("tool.pautaje",        "Pautaje"),
    ("tool.parrilla",       "Parrilla"),
    ("tool.playlist",       "Editor de playlists .gradio"),
    ("tool.botonera",       "Botonera"),
    ("tool.config",         "Configuración"),
    ("tool.visor",          "Visor"),
    ("tool.record",         "Grabar"),
    ("tool.reportes",       "Reportería de audios emitidos"),
    // Cola activa / tandas de comerciales
    ("cola.titulo",         "⬛ Cola activa"),
    ("cola.vaciar",         "🗑 Vaciar"),
    ("cola.no_tandas",      "Sin tandas programadas en las próximas horas"),
    // Volumen (status bar)
    ("vol.fmt",             "Vol: {up}%  |  Duck: {dn}%  |  Fundido: {mix}s"),
    // Tooltips de configuración
    ("tip.empty_queue",     "Eliminar todos los comerciales en cola"),
    ("tip.vu_meter",        "VU Meter"),
    ("tip.dsp_on",          "Procesador DSP activo — clic para desactivar"),
    ("tip.dsp_off",         "Procesador DSP inactivo — clic para activar"),
    ("tip.upvol",           "Nivel de volumen del audio principal (0–100)."),
    ("tip.downvol",         "Nivel de volumen durante la atenuación (duck) por comerciales (0–100)."),
    ("tip.client_port",     "Puerto TCP en que gr-client se conectará a este servidor (default: 7777)."),
    ("tip.client_token",    "Token que deben enviar los clientes remotos al conectarse. Vacío = sin auth."),
    ("tip.gen_id",          "Genera un ID aleatorio de 8 dígitos."),
    ("tip.silence",         "Segundos de silencio sostenido antes de avanzar al siguiente tema. 0 = desactivado."),
    ("tip.relay",           "Activa la conexión al servidor de relay para acceso remoto desde internet."),
    ("tip.relay_id",        "ID de 8 dígitos que identifica este servidor en el relay. Compártelo con gr-client para conectarse por internet."),
    // Labels del diálogo de Configuración
    ("cfg.audio_main",      "Tarjeta de audio principal:"),
    ("cfg.audio_cue",       "Tarjeta de audio CUE:"),
    ("cfg.medio_name",      "Nombre del medio:"),
    ("cfg.crossfade",       "Tiempo de fundido (seg):"),
    ("cfg.pisador_on",      "Pisador sobre temas:"),
    ("cfg.pisador_dir",     "Carpeta de pisadores:"),
    ("cfg.pisador_every",   "Tocar pisador cada N temas:"),
    ("cfg.pisador_excl",    "Carpetas que no se pisan:"),
    ("cfg.nacionales",      "Carpetas Nacionales:"),
    ("cfg.intercultural",   "Carpetas Intercultural:"),
    ("cfg.silence",         "Silencio máximo (seg, 0=desact.):"),
    ("cfg.upvol",           "Volumen principal (0–100):"),
    ("cfg.downvol",         "Volumen duck (0–100):"),
    ("cfg.client_port",     "Puerto servidor remoto (gr-client):"),
    ("cfg.client_token",    "Token de acceso (gr-client):"),
    ("cfg.client_token_ph", "(vacío = sin autenticación)"),
    ("cfg.relay",           "Relay internet:"),
    ("cfg.relay_id",        "ID de relay (8 dígitos):"),
    ("cfg.no_repeat",       "No repetir temas de los últimos (días):"),
    ("cfg.folders_n",       "{n} carpeta(s)"),
    ("cfg.pick_pisador",    "Elegir carpeta de pisadores"),
    // Preset
    ("preset.label",            "PRESET"),
    ("preset.save_dialog",      "Guardar preset"),
    ("preset.name_label",       "Nombre del preset:"),
    // Idioma
    ("lang.label",          "Idioma:"),
    ("lang.auto",           "Automático"),
    ("lang.restart_title",  "Reiniciar para aplicar"),
    ("lang.restart_body",   "El idioma se aplicará la próxima vez que se inicie G Radio Player."),
    ("skin.label",          "Skin (apariencia):"),
    ("skin.default",        "Predeterminado"),
    ("skin.restart_title",  "Reiniciar para aplicar"),
    ("skin.restart_body",   "El skin se aplicará la próxima vez que se abra cada ventana."),
    ("players.label",         "Players (paneles visibles):"),
    ("players.3",             "3 — Deck A + Deck B + comercial"),
    ("players.2",             "2 — un deck fusionado + comercial"),
    ("players.1",             "1 — un solo panel (deck o comercial)"),
    ("players.restart_title", "Reiniciar para aplicar"),
    ("players.restart_body",  "Los paneles de reproducción se reorganizarán la próxima vez que se inicie G Radio Player."),
    // Diálogo URL de streaming
    ("dialogo.url.title",            "Agregar URL de Streaming"),
    ("dialogo.url.label",            "URL del streaming:"),
    ("dialogo.url.history",          "Historial:"),
    ("dialogo.url.use",              "Usar"),
    ("dialogo.url.delete_tip",       "Eliminar del historial"),
    ("dialogo.url.duration",         "Duración (segundos):"),
    ("dialogo.url.duration_tip",     "0 = continuo / sin límite de tiempo"),
    ("dialogo.url.continuous_hint",  "(0 = continuo)"),
    ("dialogo.url.add",              "Agregar"),
    // Días de la semana
    ("dia.lunes",     "Lunes"),
    ("dia.martes",    "Martes"),
    ("dia.miercoles", "Miércoles"),
    ("dia.jueves",    "Jueves"),
    ("dia.viernes",   "Viernes"),
    ("dia.sabado",    "Sábado"),
    ("dia.domingo",   "Domingo"),
    // Árbol de archivos
    ("tree.home",     "Inicio"),
    ("tree.system",   "Sistema"),
    // Ventana de Parrilla Musical
    ("parr.win_title",         "Parrilla Específica - G Radio"),
    ("parr.titulo",            "ELABORACIÓN DE LA PARRILLA MUSICAL ESPECÍFICA POR DÍA Y HORAS"),
    ("parr.pisadores_hora",    "Pisadores esta hora:"),
    ("parr.pisadores_ph",      "(usa carpeta general)"),
    ("parr.pis_browse_tip",    "Elegir carpeta de pisadores para esta hora"),
    ("parr.fuentes_audio",     "FUENTES DE AUDIO"),
    ("parr.col_nombre",        "Nombre"),
    ("parr.btn_marca_hora",    "Insertar marca de Hora"),
    ("parr.subir_item",        "Subir ítem"),
    ("parr.bajar_item",        "Bajar ítem"),
    ("parr.eliminar_item",     "Eliminar ítem"),
    ("parr.parrilla_musical",  "PARRILLA MUSICAL"),
    ("parr.btn_leer",          "🔍  Leer"),
    ("parr.btn_leer_tip",      "Cargar parrilla del día y hora seleccionados"),
    ("parr.btn_grabar",        "⏺  Grabar"),
    ("parr.btn_grabar_tip",    "Guardar parrilla en el día y hora seleccionados"),
    ("parr.frame_horas",       "Horas"),
    ("parr.frame_dia",         "Día"),
    ("parr.tip_hora",          "Clic: ver hora {h} | Arrastrar: copiar parrilla"),
    ("parr.tip_dia",           "Clic: seleccionar {d} | Arrastrar: copiar parrilla"),
    // Botón "Abrir" en file chooser
    ("btn.open",               "Abrir"),
    // Botonera
    ("boto.menu_asignar",      "🎵  Asignar audio..."),
    ("boto.menu_quitar",       "🗑  Quitar audio"),
    ("boto.sel_audio",         "Seleccionar audio"),
    ("boto.filtro_audio",      "Archivos de audio"),
    ("boto.filtro_todos",      "Todos los archivos"),
    // Visor de Pautaje
    ("visor.win_title",         "GR Visor de Pautaje"),
    ("visor.header",            "Actualizar Pautaje"),
    ("visor.btn_refresh",       "↻ Actualizar"),
    ("visor.pautaje_dia",       "Pautaje del día"),
    ("visor.col_nombre",        "Comercial/Evento"),
    ("visor.col_tiempo",        "Tiempo"),
    ("visor.col_dias",          "Días"),
    ("visor.col_inicio",        "Inicio"),
    ("visor.col_fin",           "Fin"),
    ("visor.parrilla_header",   "Parrilla musical — Hora actual: {h}:00  |  Siguiente: {hs}:00"),
    ("visor.hora_actual",       "HORA ACTUAL"),
    ("visor.hora_siguiente",    "HORA SIGUIENTE"),
    ("visor.sin_programacion",  "(sin programación)"),
    ("visor.aleatorio",         "aleatorio"),
    ("visor.lista",             "lista"),
    // Buscador de audio
    ("buscador.win_title",          "G Radio — Buscador"),
    ("buscador.btn_search_tip",     "Buscar"),
    ("buscador.entry_ph",           "Buscar tema…"),
    ("buscador.btn_clear",          "Limpiar"),
    ("buscador.btn_index",          "⟳ Índice"),
    ("buscador.btn_index_tip",      "Actualizar índice de locate (updatedb)"),
    ("buscador.col_tema",           "Tema Encontrado"),
    ("buscador.col_tiempo",         "Tiempo"),
    ("buscador.col_ruta",           "Ruta"),
    ("buscador.status_ready",       "Listo. Ingresa un término y presiona Enter o 🔍"),
    ("buscador.status_listo",       "Listo."),
    ("buscador.status_buscando",    "Buscando \"{q}\"…"),
    ("buscador.status_resultados",  "{n} resultado(s) para \"{q}\"  —  doble clic para agregar a la lista, arrastra para posicionar"),
    ("buscador.status_indexando",   "Actualizando índice locate…"),
    ("buscador.status_index_ok",    "Índice actualizado correctamente."),
    ("buscador.status_index_err",   "Error al actualizar índice."),
    ("buscador.btn_pause",          "⏸ Pausa"),
    ("buscador.btn_resume",         "▶ Reanudar"),
    ("buscador.btn_stop",           "■ Stop"),
    ("buscador.btn_play_now_tip",   "▶ Reproducir ahora (crossfade al deck libre)"),
    ("buscador.btn_first",          "⤒ Insertar al inicio de la lista"),
    ("buscador.btn_last",           "⤓ Agregar al final de la lista"),
    ("buscador.menu_cue",           "🎧  Preescuchar (CUE)"),
    ("buscador.menu_add",           "➕  Agregar a la lista"),
    // Reportes
    ("rep.win_title",      "G Radio — Reportería de Audios Emitidos"),
    ("rep.title",          "G Radio — Reporting Tool"),
    ("rep.subtitle",       "Audios Emitidos — Reporte de Transmisión"),
    ("rep.categoria",      "CATEGORÍA"),
    ("rep.cat_com",        "Comerciales"),
    ("rep.cat_par",        "Parrilla"),
    ("rep.cat_ev",         "Eventos"),
    ("rep.rango_fechas",   "RANGO DE FECHAS"),
    ("rep.desde",          "Desde:"),
    ("rep.hasta",          "Hasta:"),
    ("rep.btn_cargar",     "🔍  Cargar datos"),
    ("rep.buscar_audio",   "BUSCAR AUDIO"),
    ("rep.buscar_ph",      "Ej: casa baca  (insensible a mayúsculas)"),
    ("rep.buscar_hint",    "Vacío = mostrar todo"),
    ("rep.col_fecha",      "FECHA"),
    ("rep.col_total",      "TOTAL"),
    ("rep.col_nacional",   "NACIONAL"),
    ("rep.col_intercult",  "INTERCULTURAL"),
    ("rep.col_archivo",    "ARCHIVO"),
    ("rep.col_emisiones",  "EMISIONES"),
    ("rep.col_dur_total",  "DUR. TOTAL"),
    ("rep.btn_pdf",        "📄  Generar PDF"),
    ("rep.btn_csv",        "📊  Exportar CSV"),
    ("rep.status_inicio",  "Selecciona categoría y rango de fechas, luego haz clic en 'Cargar datos'."),
    ("rep.status_vacio",   "No se encontraron registros para el período seleccionado."),
    ("rep.status_resumen", "✓  {titulos} títulos únicos · {emisiones} emisiones totales · {desde} al {hasta}"),
    ("rep.status_pdf_ok",  "✓ PDF generado: {path}"),
    ("rep.status_pdf_err", "✗ Error al generar PDF: {err}"),
    ("rep.status_csv_ok",  "✓ CSV exportado: {path}"),
    ("rep.status_csv_err", "✗ Error al exportar CSV: {err}"),
    // Editor de playlists (.gradio)
    ("pl.win_title",     "Creación de Playlist G Radio"),
    ("pl.tip_del",       "Eliminar seleccionado"),
    ("pl.tip_up",        "Subir"),
    ("pl.tip_down",      "Bajar"),
    ("pl.tip_play_cue",  "Pre-escuchar"),
    ("pl.tip_stop_cue",  "Detener pre-escucha"),
    ("pl.tip_clock",     "Calcular tiempos"),
    ("pl.col_tema",      "Tema Musical"),
    ("pl.col_tiempo",    "Tiempo"),
    ("pl.col_ruta",      "Ruta"),
    ("pl.btn_clear",     "🔴 Borrar Lista"),
    ("pl.btn_load",      "Cargar Lista"),
    ("pl.btn_save",      "Guardar Lista"),
    ("pl.load_title",    "Cargar lista .gradio"),
    ("pl.save_title",    "Guardar lista .gradio"),
    ("pl.filter",        "Listas G Radio (*.gradio)"),
    ("pl.default_name",  "nueva_lista.gradio"),
    // Árbol de archivos (panel_arbol.rs)
    ("arbol.pautar_carpeta", "Pautar carpeta completa (aleatoria)"),
    // GR Pautaje — ventana principal
    ("paut.tip_acumulado",     "Tiempo total acumulado en la hora"),
    ("paut.tip_corte",         "Tiempo de este corte"),
    ("paut.col_comercial",     "Comercial"),
    ("paut.col_dias",          "LMXJVSD"),
    ("paut.col_inicio",        "Inicio"),
    ("paut.col_fin",           "Fin"),
    ("paut.col_ruta",          "Ruta"),
    ("paut.fecha_inicio",      "Inicio"),
    ("paut.fecha_fin",         "Fin"),
    ("paut.tip_limpiar",       "Eliminar comerciales caducados"),
    ("paut.confirm_caducados", "¿Desea eliminar todos los comerciales caducados?"),
    ("paut.info_caducados",    "Se eliminaron {n} entradas caducadas."),
    ("paut.tipo_comerciales",  "Comerciales"),
    ("paut.tipo_eventos",      "Eventos"),
    ("paut.tipo_eventos_espera","Eventos en Espera"),
    ("paut.tip_subir",         "Mover hacia arriba"),
    ("paut.tip_bajar",         "Mover hacia abajo"),
    ("paut.tip_eliminar",      "Eliminar seleccionado del pautaje"),
    ("paut.tip_play_cue",      "Reproducir en segunda tarjeta de audio"),
    ("paut.tip_url",           "Agregar URL de streaming"),
    ("paut.tip_hora",          "Insertar señal de hora en el pautaje"),
    ("paut.tip_linea",         "Entrada de línea"),
    // Diálogos del player principal
    ("dlg.ruta_archivo",       "Ruta del archivo"),
    ("dlg.copiar_ruta",        "📋 Copiar ruta"),
    ("dlg.ins_stream_title",   "📡 Insertar Streaming"),
    ("dlg.url_lbl",            "URL:"),
    ("dlg.duracion_s",         "Duración (s):"),
    ("dlg.btn_insertar",       "📡 Insertar"),
    ("dlg.confirm_interrumpir","Hay comerciales o eventos reproduciéndose.\n¿Interrumpirlos y reproducir el audio en el deck?"),
    ("dlg.filter_zip",         "Archivos ZIP"),
    ("dlg.recovery_title",     "Recuperación completada"),
    ("dlg.recovery_body",      "✅ Configuración restaurada.\n{n} archivos recuperados.\n\nReinicia el reproductor para aplicar los cambios."),
    // Herramientas y paneles del player
    ("tool.auto_refill",       "Automático — pausa el relleno automático de la parrilla\nVerde=automático · Rojo=pausado"),
    ("tool.vaciar_playlist",   "Vaciar cola de reproducción"),
    ("playlist.titulo",        "🎵 Cola de reproducción  [doble-click=reproducir · arrastrar=reordenar · soltar archivo=insertar]"),
    ("playlist.total",         "Total"),
    ("panel.comerciales_tandas","📢 Comerciales — próximas tandas"),
    ("panel.eventos_espera",   "⏳ Eventos en espera"),
    // Menú contextual de la cola
    ("ctx.cue",                "🎧  Preescuchar (CUE)"),
    ("ctx.ins_hora",           "🕐  Insertar Hora aquí"),
    ("ctx.ins_stream",         "📡  Insertar Streaming aquí"),
    ("ctx.load_list",          "📋  Cargar lista .gradio aquí"),
    ("ctx.regen",              "🔄  Regenerar lista"),
    ("ctx.del_cola",           "🗑  Eliminar de la cola"),
    // Ventana flotante de CUE
    ("cue.win_title",          "🎧 CUE: {title}"),
    ("cue.btn_pause",          "⏸ Pausa"),
    ("cue.btn_resume",         "▶ Reanudar"),
    ("cue.btn_stop",           "■ Stop"),
    ("tip.no_repeat",          "Días hacia atrás que se consultan para evitar repetir un tema. 1 = solo hoy, 3 = tres días (recomendado)."),
    ("panel.eventos",          "📅 Eventos"),
    ("dlg.error",              "Error"),
    ("dlg.backup_title",       "Respaldo completado"),
    ("dlg.backup_body",        "✅ Respaldo creado exitosamente.\n{n} archivos guardados en:\n{path}"),
    ("dlg.backup_err",         "❌ Error al crear respaldo:\n{err}"),
    ("dlg.sel_backup",         "Seleccionar respaldo GR"),
    ("dlg.btn_restore",        "Restaurar"),
    ("dlg.recovery_err",       "❌ Error al recuperar:\n{err}"),
    ("dlg.token_title",        "Token obligatorio"),
    ("dlg.token_body",         "⚠ El relay de internet requiere un token de acceso.\nSin token, cualquiera que adivine el ID puede controlar el reproductor.\n\nIngresa un token en el campo 'Token de acceso (gr-client)' antes de activar el relay."),
    // Fundido
    ("cfg.fundido_excl",       "Carpetas que no se funden:"),
    ("tip.fundido_excl",       "Los archivos en estas carpetas se reproducen con arranque directo (sin crossfade), para no cortar el inicio ni el final — útil para locuciones/IDs."),
    // IA
    ("cfg.ia",                 "Inteligencia Artificial:"),
    ("tip.ia",                 "Habilita el asistente de IA integrado (OpenCode con modelos abiertos gratuitos)."),
    ("tip.ia_btn",             "Abrir asistente IA para G-Radio"),
    // Locutor Automático
    ("cfg.locutor",            "Locutor Automático:"),
    ("tip.locutor",            "Habilita la generación de locuciones por IA a cargo de agentes externos (experimental). El estado se guarda en tmp/locutor_auto para que esos agentes lo lean."),
    ("btn.ia",                 "IA"),
    ("dlg.ia_warn_title",      "Habilitar Inteligencia Artificial"),
    ("dlg.ia_warn_body",       "Esta función usa OpenCode con modelos de IA abiertos y gratuitos.\n\nEl asistente puede leer y modificar archivos de programación de la radio.\n\n⚠ El uso de IA puede generar resultados inesperados. Se recomienda\nrevisar los cambios antes de aplicarlos en transmisión.\n\n¿Aceptas estas condiciones y deseas habilitar la IA?"),
    ("dlg.ia_no_bin",          "⚠ No se encontró opencode instalado.\n\nInstálalo desde: https://opencode.ai\n\nO coloca el binario en:\n  ~/.local/bin/opencode"),
    ("dlg.ia_accept",          "✅ Aceptar y habilitar"),
    ("dlg.locutor_warn_title", "Habilitar Locutor Automático"),
    ("dlg.locutor_warn_body",  "El Locutor Automático genera locuciones de radio (voz IA) a cargo de un agente de IA externo (Claude/OpenCode), no de este programa.\n\nEsta función solo activa la bandera que ese agente lee para decidir si debe generar audio; sin un agente configurado y corriendo, no ocurre nada.\n\n⚠ El agente puede leer y escribir archivos de programación de la radio\n(parrilla, comerciales, eventos) para insertar las locuciones generadas.\n\n¿Aceptas estas condiciones y deseas habilitar el Locutor Automático?"),
    ("dlg.locutor_accept",     "✅ Aceptar y habilitar"),
    ("preset.default_name",    "Mi preset"),
];

const EN: Dict = &[
    ("win.player",          "G Radio Player"),
    ("win.pautaje",         "GR Schedule"),
    ("win.processor",       "GR DSP Processor"),
    ("win.config",          "GR Settings"),
    ("btn.ok",              "OK"),
    ("btn.cancel",          "Cancel"),
    ("btn.save",            "Save"),
    ("btn.close",           "Close"),
    ("btn.interrupt",       "Interrupt"),
    ("btn.generate",        "Generate"),
    ("btn.all",             "All"),
    ("btn.choose_folder",   "Choose folder"),
    ("btn.edit_list",       "✏ Edit list…"),
    ("btn.select",          "Select"),
    ("btn.operador",        "🎛 Operator"),
    ("now.stopped_end",     "⏹ Stopped at end of track"),
    ("now.app_name",        "G Radio Player"),
    ("now.no_track",        "No track"),
    ("now.stopped_after",   "Stopped: Stop after"),
    ("now.no_ad",           "No ad"),
    ("deck.a",              "🎵 Deck A (odd tracks)"),
    ("deck.b",              "🎵 Deck B (even tracks)"),
    ("tool.start",          "Start playback"),
    ("tool.stop_general",   "Stop All — stops schedule, commercials and events"),
    ("tool.next",           "Next track"),
    ("tool.hora",           "Play hour"),
    ("tool.pisador",        "Sweeper"),
    ("tool.duck",           "Duck music"),
    ("tool.buscador",       "Audio search"),
    ("tool.pautaje",        "Schedule"),
    ("tool.parrilla",       "Grid"),
    ("tool.playlist",       ".gradio playlist editor"),
    ("tool.botonera",       "Hot keys"),
    ("tool.config",         "Settings"),
    ("tool.visor",          "Viewer"),
    ("tool.record",         "Record"),
    ("tool.reportes",       "Aired audio reports"),
    ("cola.titulo",         "⬛ Active queue"),
    ("cola.vaciar",         "🗑 Clear"),
    ("cola.no_tandas",      "No commercial breaks scheduled in the coming hours"),
    ("vol.fmt",             "Vol: {up}%  |  Duck: {dn}%  |  Fade: {mix}s"),
    ("tip.empty_queue",     "Clear all queued commercials"),
    ("tip.vu_meter",        "VU Meter"),
    ("tip.dsp_on",          "DSP processor active — click to disable"),
    ("tip.dsp_off",         "DSP processor inactive — click to enable"),
    ("tip.upvol",           "Main audio volume level (0–100)."),
    ("tip.downvol",         "Audio level during ducking (commercials playing) (0–100)."),
    ("tip.client_port",     "TCP port gr-client will connect to (default: 7777)."),
    ("tip.client_token",    "Token remote clients must send to connect. Empty = no auth."),
    ("tip.gen_id",          "Generate a random 8-digit ID."),
    ("tip.silence",         "Seconds of sustained silence before skipping to the next track. 0 = disabled."),
    ("tip.relay",           "Enable the connection to the relay server for remote access over the internet."),
    ("tip.relay_id",        "8-digit ID that identifies this server on the relay. Share it with gr-client to connect over the internet."),
    ("cfg.audio_main",      "Main audio device:"),
    ("cfg.audio_cue",       "CUE audio device:"),
    ("cfg.medio_name",      "Station name:"),
    ("cfg.crossfade",       "Crossfade (sec):"),
    ("cfg.pisador_on",      "Sweeper over tracks:"),
    ("cfg.pisador_dir",     "Sweepers folder:"),
    ("cfg.pisador_every",   "Play sweeper every N tracks:"),
    ("cfg.pisador_excl",    "Folders without sweepers:"),
    ("cfg.nacionales",      "National folders:"),
    ("cfg.intercultural",   "Intercultural folders:"),
    ("cfg.silence",         "Max silence (sec, 0=off):"),
    ("cfg.upvol",           "Main volume (0–100):"),
    ("cfg.downvol",         "Duck volume (0–100):"),
    ("cfg.client_port",     "Remote server port (gr-client):"),
    ("cfg.client_token",    "Access token (gr-client):"),
    ("cfg.client_token_ph", "(empty = no authentication)"),
    ("cfg.relay",           "Internet relay:"),
    ("cfg.relay_id",        "Relay ID (8 digits):"),
    ("cfg.no_repeat",       "Do not repeat tracks from the last (days):"),
    ("cfg.folders_n",       "{n} folder(s)"),
    ("cfg.pick_pisador",    "Choose sweepers folder"),
    ("preset.label",            "PRESET"),
    ("preset.save_dialog",      "Save preset"),
    ("preset.name_label",       "Preset name:"),
    ("lang.label",          "Language:"),
    ("lang.auto",           "Automatic"),
    ("lang.restart_title",  "Restart to apply"),
    ("lang.restart_body",   "The language change will take effect next time G Radio Player starts."),
    ("skin.label",          "Skin (appearance):"),
    ("skin.default",        "Default"),
    ("skin.restart_title",  "Restart to apply"),
    ("skin.restart_body",   "The skin will take effect next time each window is opened."),
    ("players.label",         "Players (visible panels):"),
    ("players.3",             "3 — Deck A + Deck B + commercial"),
    ("players.2",             "2 — one merged deck + commercial"),
    ("players.1",             "1 — single panel (deck or commercial)"),
    ("players.restart_title", "Restart to apply"),
    ("players.restart_body",  "The playback panels will rearrange next time G Radio Player starts."),
    ("dialogo.url.title",            "Add streaming URL"),
    ("dialogo.url.label",            "Streaming URL:"),
    ("dialogo.url.history",          "History:"),
    ("dialogo.url.use",              "Use"),
    ("dialogo.url.delete_tip",       "Remove from history"),
    ("dialogo.url.duration",         "Duration (seconds):"),
    ("dialogo.url.duration_tip",     "0 = continuous / no time limit"),
    ("dialogo.url.continuous_hint",  "(0 = continuous)"),
    ("dialogo.url.add",              "Add"),
    ("dia.lunes",     "Monday"),
    ("dia.martes",    "Tuesday"),
    ("dia.miercoles", "Wednesday"),
    ("dia.jueves",    "Thursday"),
    ("dia.viernes",   "Friday"),
    ("dia.sabado",    "Saturday"),
    ("dia.domingo",   "Sunday"),
    ("tree.home",     "Home"),
    ("tree.system",   "System"),
    ("parr.win_title",         "Specific Schedule - G Radio"),
    ("parr.titulo",            "BUILD THE SPECIFIC MUSIC SCHEDULE BY DAY AND HOUR"),
    ("parr.pisadores_hora",    "Sweepers this hour:"),
    ("parr.pisadores_ph",      "(use general folder)"),
    ("parr.pis_browse_tip",    "Choose sweepers folder for this hour"),
    ("parr.fuentes_audio",     "AUDIO SOURCES"),
    ("parr.col_nombre",        "Name"),
    ("parr.btn_marca_hora",    "Insert hour marker"),
    ("parr.subir_item",        "Move item up"),
    ("parr.bajar_item",        "Move item down"),
    ("parr.eliminar_item",     "Delete item"),
    ("parr.parrilla_musical",  "MUSIC SCHEDULE"),
    ("parr.btn_leer",          "🔍  Load"),
    ("parr.btn_leer_tip",      "Load schedule for the selected day and hour"),
    ("parr.btn_grabar",        "⏺  Save"),
    ("parr.btn_grabar_tip",    "Save schedule to the selected day and hour"),
    ("parr.frame_horas",       "Hours"),
    ("parr.frame_dia",         "Day"),
    ("parr.tip_hora",          "Click: view hour {h} | Drag: copy schedule"),
    ("parr.tip_dia",           "Click: select {d} | Drag: copy schedule"),
    ("btn.open",               "Open"),
    ("boto.menu_asignar",      "🎵  Assign audio..."),
    ("boto.menu_quitar",       "🗑  Remove audio"),
    ("boto.sel_audio",         "Select audio"),
    ("boto.filtro_audio",      "Audio files"),
    ("boto.filtro_todos",      "All files"),
    ("visor.win_title",         "GR Schedule Viewer"),
    ("visor.header",            "Refresh schedule"),
    ("visor.btn_refresh",       "↻ Refresh"),
    ("visor.pautaje_dia",       "Today's schedule"),
    ("visor.col_nombre",        "Commercial/Event"),
    ("visor.col_tiempo",        "Length"),
    ("visor.col_dias",          "Days"),
    ("visor.col_inicio",        "Start"),
    ("visor.col_fin",           "End"),
    ("visor.parrilla_header",   "Music schedule — Current hour: {h}:00  |  Next: {hs}:00"),
    ("visor.hora_actual",       "CURRENT HOUR"),
    ("visor.hora_siguiente",    "NEXT HOUR"),
    ("visor.sin_programacion",  "(nothing scheduled)"),
    ("visor.aleatorio",         "random"),
    ("visor.lista",             "list"),
    ("buscador.win_title",          "G Radio — Search"),
    ("buscador.btn_search_tip",     "Search"),
    ("buscador.entry_ph",           "Search track…"),
    ("buscador.btn_clear",          "Clear"),
    ("buscador.btn_index",          "⟳ Index"),
    ("buscador.btn_index_tip",      "Update locate index (updatedb)"),
    ("buscador.col_tema",           "Track found"),
    ("buscador.col_tiempo",         "Length"),
    ("buscador.col_ruta",           "Path"),
    ("buscador.status_ready",       "Ready. Type a term and press Enter or 🔍"),
    ("buscador.status_listo",       "Ready."),
    ("buscador.status_buscando",    "Searching \"{q}\"…"),
    ("buscador.status_resultados",  "{n} result(s) for \"{q}\"  —  double-click to append, drag to position"),
    ("buscador.status_indexando",   "Updating locate index…"),
    ("buscador.status_index_ok",    "Index updated successfully."),
    ("buscador.status_index_err",   "Error updating index."),
    ("buscador.btn_pause",          "⏸ Pause"),
    ("buscador.btn_resume",         "▶ Resume"),
    ("buscador.btn_stop",           "■ Stop"),
    ("buscador.btn_play_now_tip",   "▶ Play now (crossfade to the free deck)"),
    ("buscador.btn_first",          "⤒ Insert at top of the list"),
    ("buscador.btn_last",           "⤓ Append to the end of the list"),
    ("buscador.menu_cue",           "🎧  Pre-listen (CUE)"),
    ("buscador.menu_add",           "➕  Add to the list"),
    ("rep.win_title",      "G Radio — Aired Audio Reports"),
    ("rep.title",          "G Radio — Reporting Tool"),
    ("rep.subtitle",       "Aired audio — Broadcast report"),
    ("rep.categoria",      "CATEGORY"),
    ("rep.cat_com",        "Commercials"),
    ("rep.cat_par",        "Schedule"),
    ("rep.cat_ev",         "Events"),
    ("rep.rango_fechas",   "DATE RANGE"),
    ("rep.desde",          "From:"),
    ("rep.hasta",          "To:"),
    ("rep.btn_cargar",     "🔍  Load data"),
    ("rep.buscar_audio",   "SEARCH AUDIO"),
    ("rep.buscar_ph",      "E.g.: casa baca  (case-insensitive)"),
    ("rep.buscar_hint",    "Empty = show all"),
    ("rep.col_fecha",      "DATE"),
    ("rep.col_total",      "TOTAL"),
    ("rep.col_nacional",   "NATIONAL"),
    ("rep.col_intercult",  "INTERCULTURAL"),
    ("rep.col_archivo",    "FILE"),
    ("rep.col_emisiones",  "AIRINGS"),
    ("rep.col_dur_total",  "TOTAL DUR."),
    ("rep.btn_pdf",        "📄  Generate PDF"),
    ("rep.btn_csv",        "📊  Export CSV"),
    ("rep.status_inicio",  "Select category and date range, then click 'Load data'."),
    ("rep.status_vacio",   "No records were found for the selected period."),
    ("rep.status_resumen", "✓  {titulos} unique titles · {emisiones} total airings · {desde} to {hasta}"),
    ("rep.status_pdf_ok",  "✓ PDF generated: {path}"),
    ("rep.status_pdf_err", "✗ Error generating PDF: {err}"),
    ("rep.status_csv_ok",  "✓ CSV exported: {path}"),
    ("rep.status_csv_err", "✗ Error exporting CSV: {err}"),
    ("pl.win_title",     "G Radio playlist editor"),
    ("pl.tip_del",       "Delete selected"),
    ("pl.tip_up",        "Move up"),
    ("pl.tip_down",      "Move down"),
    ("pl.tip_play_cue",  "Pre-listen"),
    ("pl.tip_stop_cue",  "Stop pre-listen"),
    ("pl.tip_clock",     "Compute lengths"),
    ("pl.col_tema",      "Track"),
    ("pl.col_tiempo",    "Length"),
    ("pl.col_ruta",      "Path"),
    ("pl.btn_clear",     "🔴 Clear list"),
    ("pl.btn_load",      "Load list"),
    ("pl.btn_save",      "Save list"),
    ("pl.load_title",    "Load .gradio list"),
    ("pl.save_title",    "Save .gradio list"),
    ("pl.filter",        "G Radio lists (*.gradio)"),
    ("pl.default_name",  "new_list.gradio"),
    ("arbol.pautar_carpeta", "Schedule the whole folder (random)"),
    ("paut.tip_acumulado",     "Total time accumulated in this hour"),
    ("paut.tip_corte",         "Time of this slot"),
    ("paut.col_comercial",     "Commercial"),
    ("paut.col_dias",          "MTWTFSS"),
    ("paut.col_inicio",        "Start"),
    ("paut.col_fin",           "End"),
    ("paut.col_ruta",          "Path"),
    ("paut.fecha_inicio",      "Start"),
    ("paut.fecha_fin",         "End"),
    ("paut.tip_limpiar",       "Delete expired commercials"),
    ("paut.confirm_caducados", "Do you want to delete all expired commercials?"),
    ("paut.info_caducados",    "{n} expired entries were removed."),
    ("paut.tipo_comerciales",  "Commercials"),
    ("paut.tipo_eventos",      "Events"),
    ("paut.tipo_eventos_espera","Events on hold"),
    ("paut.tip_subir",         "Move up"),
    ("paut.tip_bajar",         "Move down"),
    ("paut.tip_eliminar",      "Delete selected entry"),
    ("paut.tip_play_cue",      "Play on the second audio card"),
    ("paut.tip_url",           "Add streaming URL"),
    ("paut.tip_hora",          "Insert hour cue into the schedule"),
    ("paut.tip_linea",         "Line input"),
    ("dlg.ruta_archivo",       "File path"),
    ("dlg.copiar_ruta",        "📋 Copy path"),
    ("dlg.ins_stream_title",   "📡 Insert streaming"),
    ("dlg.url_lbl",            "URL:"),
    ("dlg.duracion_s",         "Duration (s):"),
    ("dlg.btn_insertar",       "📡 Insert"),
    ("dlg.confirm_interrumpir","Commercials or events are playing.\nInterrupt them and play the audio on the deck?"),
    ("dlg.filter_zip",         "ZIP files"),
    ("dlg.recovery_title",     "Recovery completed"),
    ("dlg.recovery_body",      "✅ Settings restored.\n{n} files recovered.\n\nRestart the player to apply the changes."),
    ("tool.auto_refill",       "Auto — pauses the schedule's automatic refill\nGreen=auto · Red=paused"),
    ("tool.vaciar_playlist",   "Clear playback queue"),
    ("playlist.titulo",        "🎵 Playback queue  [double-click=play · drag=reorder · drop file=insert]"),
    ("playlist.total",         "Total"),
    ("panel.comerciales_tandas","📢 Commercials — upcoming breaks"),
    ("panel.eventos_espera",   "⏳ Events on hold"),
    ("ctx.cue",                "🎧  Pre-listen (CUE)"),
    ("ctx.ins_hora",           "🕐  Insert hour here"),
    ("ctx.ins_stream",         "📡  Insert streaming here"),
    ("ctx.load_list",          "📋  Load .gradio list here"),
    ("ctx.regen",              "🔄  Regenerate list"),
    ("ctx.del_cola",           "🗑  Remove from queue"),
    ("cue.win_title",          "🎧 CUE: {title}"),
    ("cue.btn_pause",          "⏸ Pause"),
    ("cue.btn_resume",         "▶ Resume"),
    ("cue.btn_stop",           "■ Stop"),
    ("tip.no_repeat",          "Days back to look up to avoid repeating a track. 1 = today only, 3 = three days (recommended)."),
    ("panel.eventos",          "📅 Events"),
    ("dlg.error",              "Error"),
    ("dlg.backup_title",       "Backup completed"),
    ("dlg.backup_body",        "✅ Backup created successfully.\n{n} files saved to:\n{path}"),
    ("dlg.backup_err",         "❌ Backup failed:\n{err}"),
    ("dlg.sel_backup",         "Select GR backup"),
    ("dlg.btn_restore",        "Restore"),
    ("dlg.recovery_err",       "❌ Restore failed:\n{err}"),
    ("dlg.token_title",        "Token required"),
    ("dlg.token_body",         "⚠ The internet relay requires an access token.\nWithout one, anyone who guesses the ID can control the player.\n\nEnter a token in the 'Access token (gr-client)' field before enabling the relay."),
    // Fade
    ("cfg.fundido_excl",       "Folders without crossfade:"),
    ("tip.fundido_excl",       "Files in these folders play with a direct start (no crossfade), so the start/end isn't cut off — useful for voice IDs/announcements."),
    // AI
    ("cfg.ia",                 "Artificial Intelligence:"),
    ("tip.ia",                 "Enable the built-in AI assistant (OpenCode with free open models)."),
    ("tip.ia_btn",             "Open AI assistant for G-Radio"),
    // Automatic Announcer
    ("cfg.locutor",            "Automatic Announcer:"),
    ("tip.locutor",            "Enables AI-generated announcements handled by external agents (experimental). The state is saved to tmp/locutor_auto for those agents to read."),
    ("btn.ia",                 "AI"),
    ("dlg.ia_warn_title",      "Enable Artificial Intelligence"),
    ("dlg.ia_warn_body",       "This feature uses OpenCode with free open-source AI models.\n\nThe assistant can read and modify radio scheduling files.\n\n⚠ AI may produce unexpected results. Review changes before\napplying them during broadcast.\n\nDo you accept these conditions and want to enable AI?"),
    ("dlg.ia_no_bin",          "⚠ opencode not found.\n\nInstall it from: https://opencode.ai\n\nOr place the binary at:\n  ~/.local/bin/opencode"),
    ("dlg.ia_accept",          "✅ Accept and enable"),
    ("dlg.locutor_warn_title", "Enable Automatic Announcer"),
    ("dlg.locutor_warn_body",  "The Automatic Announcer generates radio announcements (AI voice) through an external AI agent (Claude/OpenCode), not this program.\n\nThis feature only turns on the flag that agent reads to decide whether to generate audio; without a configured agent running, nothing happens.\n\n⚠ The agent may read and write radio scheduling files\n(playlist, ads, events) to insert the generated announcements.\n\nDo you accept these conditions and want to enable the Automatic Announcer?"),
    ("dlg.locutor_accept",     "✅ Accept and enable"),
    ("preset.default_name",    "My preset"),
];

const PT: Dict = &[
    ("win.player",          "G Radio Player"),
    ("win.pautaje",         "GR Grade"),
    ("win.processor",       "GR Processador DSP"),
    ("win.config",          "Configurações GR"),
    ("btn.ok",              "OK"),
    ("btn.cancel",          "Cancelar"),
    ("btn.save",            "Salvar"),
    ("btn.close",           "Fechar"),
    ("btn.interrupt",       "Interromper"),
    ("btn.generate",        "Gerar"),
    ("btn.all",             "Todos"),
    ("btn.choose_folder",   "Escolher pasta"),
    ("btn.edit_list",       "✏ Editar lista…"),
    ("btn.select",          "Selecionar"),
    ("btn.operador",        "🎛 Operador"),
    ("now.stopped_end",     "⏹ Parado no fim da faixa"),
    ("now.app_name",        "G Radio Player"),
    ("now.no_track",        "Sem faixa"),
    ("now.stopped_after",   "Parado: Parar depois"),
    ("now.no_ad",           "Sem comercial"),
    ("deck.a",              "🎵 Deck A (faixas ímpares)"),
    ("deck.b",              "🎵 Deck B (faixas pares)"),
    ("tool.start",          "Iniciar reprodução"),
    ("tool.stop_general",   "Parar Tudo — para grade, comerciais e eventos"),
    ("tool.next",           "Próxima faixa"),
    ("tool.hora",           "Tocar hora"),
    ("tool.pisador",        "Vinheta"),
    ("tool.duck",           "Abaixar música (duck)"),
    ("tool.buscador",       "Busca de áudio"),
    ("tool.pautaje",        "Programação"),
    ("tool.parrilla",       "Grade"),
    ("tool.playlist",       "Editor de playlists .gradio"),
    ("tool.botonera",       "Botoeira"),
    ("tool.config",         "Configurações"),
    ("tool.visor",          "Visor"),
    ("tool.record",         "Gravar"),
    ("tool.reportes",       "Relatórios de áudios reproduzidos"),
    ("cola.titulo",         "⬛ Fila ativa"),
    ("cola.vaciar",         "🗑 Limpar"),
    ("cola.no_tandas",      "Sem blocos comerciais nas próximas horas"),
    ("vol.fmt",             "Vol: {up}%  |  Duck: {dn}%  |  Fade: {mix}s"),
    ("tip.empty_queue",     "Limpar todos os comerciais na fila"),
    ("tip.vu_meter",        "VU Meter"),
    ("tip.dsp_on",          "Processador DSP ativo — clique para desativar"),
    ("tip.dsp_off",         "Processador DSP inativo — clique para ativar"),
    ("tip.upvol",           "Nível de volume do áudio principal (0–100)."),
    ("tip.downvol",         "Nível de volume durante a atenuação (duck) por comerciais (0–100)."),
    ("tip.client_port",     "Porta TCP em que gr-client conectará a este servidor (padrão: 7777)."),
    ("tip.client_token",    "Token que clientes remotos devem enviar ao conectar. Vazio = sem auth."),
    ("tip.gen_id",          "Gera um ID aleatório de 8 dígitos."),
    ("tip.silence",         "Segundos de silêncio sustentado antes de avançar para a próxima faixa. 0 = desativado."),
    ("tip.relay",           "Ativa a conexão com o servidor de relay para acesso remoto via internet."),
    ("tip.relay_id",        "ID de 8 dígitos que identifica este servidor no relay. Compartilhe-o com gr-client para conectar pela internet."),
    ("cfg.audio_main",      "Placa de áudio principal:"),
    ("cfg.audio_cue",       "Placa de áudio CUE:"),
    ("cfg.medio_name",      "Nome da rádio:"),
    ("cfg.crossfade",       "Tempo de fade (seg):"),
    ("cfg.pisador_on",      "Vinheta sobre faixas:"),
    ("cfg.pisador_dir",     "Pasta de vinhetas:"),
    ("cfg.pisador_every",   "Tocar vinheta a cada N faixas:"),
    ("cfg.pisador_excl",    "Pastas sem vinhetas:"),
    ("cfg.nacionales",      "Pastas nacionais:"),
    ("cfg.intercultural",   "Pastas interculturais:"),
    ("cfg.silence",         "Silêncio máximo (seg, 0=desat.):"),
    ("cfg.upvol",           "Volume principal (0–100):"),
    ("cfg.downvol",         "Volume duck (0–100):"),
    ("cfg.client_port",     "Porta servidor remoto (gr-client):"),
    ("cfg.client_token",    "Token de acesso (gr-client):"),
    ("cfg.client_token_ph", "(vazio = sem autenticação)"),
    ("cfg.relay",           "Relay internet:"),
    ("cfg.relay_id",        "ID de relay (8 dígitos):"),
    ("cfg.no_repeat",       "Não repetir faixas dos últimos (dias):"),
    ("cfg.folders_n",       "{n} pasta(s)"),
    ("cfg.pick_pisador",    "Escolher pasta de vinhetas"),
    ("preset.label",            "PRESET"),
    ("preset.save_dialog",      "Salvar preset"),
    ("preset.name_label",       "Nome do preset:"),
    ("lang.label",          "Idioma:"),
    ("lang.auto",           "Automático"),
    ("lang.restart_title",  "Reinicie para aplicar"),
    ("lang.restart_body",   "O idioma será aplicado na próxima vez que iniciar o G Radio Player."),
    ("skin.label",          "Skin (aparência):"),
    ("skin.default",        "Padrão"),
    ("skin.restart_title",  "Reinicie para aplicar"),
    ("skin.restart_body",   "O skin será aplicado na próxima vez que cada janela for aberta."),
    ("players.label",         "Players (painéis visíveis):"),
    ("players.3",             "3 — Deck A + Deck B + comercial"),
    ("players.2",             "2 — um deck fundido + comercial"),
    ("players.1",             "1 — um único painel (deck ou comercial)"),
    ("players.restart_title", "Reinicie para aplicar"),
    ("players.restart_body",  "Os painéis de reprodução serão reorganizados na próxima vez que o G Radio Player for iniciado."),
    ("dialogo.url.title",            "Adicionar URL de streaming"),
    ("dialogo.url.label",            "URL do streaming:"),
    ("dialogo.url.history",          "Histórico:"),
    ("dialogo.url.use",              "Usar"),
    ("dialogo.url.delete_tip",       "Remover do histórico"),
    ("dialogo.url.duration",         "Duração (segundos):"),
    ("dialogo.url.duration_tip",     "0 = contínuo / sem limite de tempo"),
    ("dialogo.url.continuous_hint",  "(0 = contínuo)"),
    ("dialogo.url.add",              "Adicionar"),
    ("dia.lunes",     "Segunda"),
    ("dia.martes",    "Terça"),
    ("dia.miercoles", "Quarta"),
    ("dia.jueves",    "Quinta"),
    ("dia.viernes",   "Sexta"),
    ("dia.sabado",    "Sábado"),
    ("dia.domingo",   "Domingo"),
    ("tree.home",     "Início"),
    ("tree.system",   "Sistema"),
    ("parr.win_title",         "Grade Específica - G Radio"),
    ("parr.titulo",            "ELABORAÇÃO DA GRADE MUSICAL ESPECÍFICA POR DIA E HORAS"),
    ("parr.pisadores_hora",    "Vinhetas esta hora:"),
    ("parr.pisadores_ph",      "(usa pasta geral)"),
    ("parr.pis_browse_tip",    "Escolher pasta de vinhetas para esta hora"),
    ("parr.fuentes_audio",     "FONTES DE ÁUDIO"),
    ("parr.col_nombre",        "Nome"),
    ("parr.btn_marca_hora",    "Inserir marca de Hora"),
    ("parr.subir_item",        "Subir item"),
    ("parr.bajar_item",        "Descer item"),
    ("parr.eliminar_item",     "Excluir item"),
    ("parr.parrilla_musical",  "GRADE MUSICAL"),
    ("parr.btn_leer",          "🔍  Ler"),
    ("parr.btn_leer_tip",      "Carregar grade do dia e hora selecionados"),
    ("parr.btn_grabar",        "⏺  Gravar"),
    ("parr.btn_grabar_tip",    "Salvar grade no dia e hora selecionados"),
    ("parr.frame_horas",       "Horas"),
    ("parr.frame_dia",         "Dia"),
    ("parr.tip_hora",          "Clique: ver hora {h} | Arrastar: copiar grade"),
    ("parr.tip_dia",           "Clique: selecionar {d} | Arrastar: copiar grade"),
    ("btn.open",               "Abrir"),
    ("boto.menu_asignar",      "🎵  Atribuir áudio..."),
    ("boto.menu_quitar",       "🗑  Remover áudio"),
    ("boto.sel_audio",         "Selecionar áudio"),
    ("boto.filtro_audio",      "Arquivos de áudio"),
    ("boto.filtro_todos",      "Todos os arquivos"),
    ("visor.win_title",         "GR Visualizador de Programação"),
    ("visor.header",            "Atualizar programação"),
    ("visor.btn_refresh",       "↻ Atualizar"),
    ("visor.pautaje_dia",       "Programação do dia"),
    ("visor.col_nombre",        "Comercial/Evento"),
    ("visor.col_tiempo",        "Tempo"),
    ("visor.col_dias",          "Dias"),
    ("visor.col_inicio",        "Início"),
    ("visor.col_fin",           "Fim"),
    ("visor.parrilla_header",   "Grade musical — Hora atual: {h}:00  |  Próxima: {hs}:00"),
    ("visor.hora_actual",       "HORA ATUAL"),
    ("visor.hora_siguiente",    "PRÓXIMA HORA"),
    ("visor.sin_programacion",  "(sem programação)"),
    ("visor.aleatorio",         "aleatório"),
    ("visor.lista",             "lista"),
    ("buscador.win_title",          "G Radio — Busca"),
    ("buscador.btn_search_tip",     "Buscar"),
    ("buscador.entry_ph",           "Buscar faixa…"),
    ("buscador.btn_clear",          "Limpar"),
    ("buscador.btn_index",          "⟳ Índice"),
    ("buscador.btn_index_tip",      "Atualizar índice do locate (updatedb)"),
    ("buscador.col_tema",           "Faixa encontrada"),
    ("buscador.col_tiempo",         "Tempo"),
    ("buscador.col_ruta",           "Caminho"),
    ("buscador.status_ready",       "Pronto. Digite um termo e pressione Enter ou 🔍"),
    ("buscador.status_listo",       "Pronto."),
    ("buscador.status_buscando",    "Buscando \"{q}\"…"),
    ("buscador.status_resultados",  "{n} resultado(s) para \"{q}\"  —  duplo clique para adicionar, arraste para posicionar"),
    ("buscador.status_indexando",   "Atualizando índice locate…"),
    ("buscador.status_index_ok",    "Índice atualizado com sucesso."),
    ("buscador.status_index_err",   "Erro ao atualizar índice."),
    ("buscador.btn_pause",          "⏸ Pausa"),
    ("buscador.btn_resume",         "▶ Retomar"),
    ("buscador.btn_stop",           "■ Stop"),
    ("buscador.btn_play_now_tip",   "▶ Reproduzir agora (crossfade no deck livre)"),
    ("buscador.btn_first",          "⤒ Inserir no início da lista"),
    ("buscador.btn_last",           "⤓ Adicionar ao final da lista"),
    ("buscador.menu_cue",           "🎧  Pré-escuta (CUE)"),
    ("buscador.menu_add",           "➕  Adicionar à lista"),
    ("rep.win_title",      "G Radio — Relatórios de Áudios Reproduzidos"),
    ("rep.title",          "G Radio — Reporting Tool"),
    ("rep.subtitle",       "Áudios reproduzidos — Relatório de transmissão"),
    ("rep.categoria",      "CATEGORIA"),
    ("rep.cat_com",        "Comerciais"),
    ("rep.cat_par",        "Grade"),
    ("rep.cat_ev",         "Eventos"),
    ("rep.rango_fechas",   "PERÍODO"),
    ("rep.desde",          "De:"),
    ("rep.hasta",          "Até:"),
    ("rep.btn_cargar",     "🔍  Carregar dados"),
    ("rep.buscar_audio",   "BUSCAR ÁUDIO"),
    ("rep.buscar_ph",      "Ex.: casa baca  (sem distinguir maiúsculas)"),
    ("rep.buscar_hint",    "Vazio = mostrar tudo"),
    ("rep.col_fecha",      "DATA"),
    ("rep.col_total",      "TOTAL"),
    ("rep.col_nacional",   "NACIONAL"),
    ("rep.col_intercult",  "INTERCULTURAL"),
    ("rep.col_archivo",    "ARQUIVO"),
    ("rep.col_emisiones",  "EXIBIÇÕES"),
    ("rep.col_dur_total",  "DUR. TOTAL"),
    ("rep.btn_pdf",        "📄  Gerar PDF"),
    ("rep.btn_csv",        "📊  Exportar CSV"),
    ("rep.status_inicio",  "Selecione categoria e período, depois clique em 'Carregar dados'."),
    ("rep.status_vacio",   "Nenhum registro encontrado no período selecionado."),
    ("rep.status_resumen", "✓  {titulos} títulos únicos · {emisiones} exibições totais · {desde} a {hasta}"),
    ("rep.status_pdf_ok",  "✓ PDF gerado: {path}"),
    ("rep.status_pdf_err", "✗ Erro ao gerar PDF: {err}"),
    ("rep.status_csv_ok",  "✓ CSV exportado: {path}"),
    ("rep.status_csv_err", "✗ Erro ao exportar CSV: {err}"),
    ("pl.win_title",     "Criação de Playlist G Radio"),
    ("pl.tip_del",       "Excluir selecionado"),
    ("pl.tip_up",        "Subir"),
    ("pl.tip_down",      "Descer"),
    ("pl.tip_play_cue",  "Pré-escutar"),
    ("pl.tip_stop_cue",  "Parar pré-escuta"),
    ("pl.tip_clock",     "Calcular tempos"),
    ("pl.col_tema",      "Faixa"),
    ("pl.col_tiempo",    "Tempo"),
    ("pl.col_ruta",      "Caminho"),
    ("pl.btn_clear",     "🔴 Apagar lista"),
    ("pl.btn_load",      "Carregar lista"),
    ("pl.btn_save",      "Salvar lista"),
    ("pl.load_title",    "Carregar lista .gradio"),
    ("pl.save_title",    "Salvar lista .gradio"),
    ("pl.filter",        "Listas G Radio (*.gradio)"),
    ("pl.default_name",  "nova_lista.gradio"),
    ("arbol.pautar_carpeta", "Programar pasta inteira (aleatória)"),
    ("paut.tip_acumulado",     "Tempo total acumulado na hora"),
    ("paut.tip_corte",         "Tempo deste bloco"),
    ("paut.col_comercial",     "Comercial"),
    ("paut.col_dias",          "STQQSSD"),
    ("paut.col_inicio",        "Início"),
    ("paut.col_fin",           "Fim"),
    ("paut.col_ruta",          "Caminho"),
    ("paut.fecha_inicio",      "Início"),
    ("paut.fecha_fin",         "Fim"),
    ("paut.tip_limpiar",       "Excluir comerciais vencidos"),
    ("paut.confirm_caducados", "Deseja excluir todos os comerciais vencidos?"),
    ("paut.info_caducados",    "Foram excluídos {n} registros vencidos."),
    ("paut.tipo_comerciales",  "Comerciais"),
    ("paut.tipo_eventos",      "Eventos"),
    ("paut.tipo_eventos_espera","Eventos em espera"),
    ("paut.tip_subir",         "Mover para cima"),
    ("paut.tip_bajar",         "Mover para baixo"),
    ("paut.tip_eliminar",      "Excluir selecionado da programação"),
    ("paut.tip_play_cue",      "Reproduzir na segunda placa de áudio"),
    ("paut.tip_url",           "Adicionar URL de streaming"),
    ("paut.tip_hora",          "Inserir marca de hora na programação"),
    ("paut.tip_linea",         "Entrada de linha"),
    ("dlg.ruta_archivo",       "Caminho do arquivo"),
    ("dlg.copiar_ruta",        "📋 Copiar caminho"),
    ("dlg.ins_stream_title",   "📡 Inserir streaming"),
    ("dlg.url_lbl",            "URL:"),
    ("dlg.duracion_s",         "Duração (s):"),
    ("dlg.btn_insertar",       "📡 Inserir"),
    ("dlg.confirm_interrumpir","Há comerciais ou eventos reproduzindo.\nInterromper e reproduzir o áudio no deck?"),
    ("dlg.filter_zip",         "Arquivos ZIP"),
    ("dlg.recovery_title",     "Recuperação concluída"),
    ("dlg.recovery_body",      "✅ Configuração restaurada.\n{n} arquivos recuperados.\n\nReinicie o reprodutor para aplicar as mudanças."),
    ("tool.auto_refill",       "Automático — pausa o preenchimento automático da grade\nVerde=automático · Vermelho=pausado"),
    ("tool.vaciar_playlist",   "Limpar fila de reprodução"),
    ("playlist.titulo",        "🎵 Fila de reprodução  [duplo clique=tocar · arrastar=reordenar · soltar arquivo=inserir]"),
    ("playlist.total",         "Total"),
    ("panel.comerciales_tandas","📢 Comerciais — próximos blocos"),
    ("panel.eventos_espera",   "⏳ Eventos em espera"),
    ("ctx.cue",                "🎧  Pré-escuta (CUE)"),
    ("ctx.ins_hora",           "🕐  Inserir hora aqui"),
    ("ctx.ins_stream",         "📡  Inserir streaming aqui"),
    ("ctx.load_list",          "📋  Carregar lista .gradio aqui"),
    ("ctx.regen",              "🔄  Regenerar lista"),
    ("ctx.del_cola",           "🗑  Remover da fila"),
    ("cue.win_title",          "🎧 CUE: {title}"),
    ("cue.btn_pause",          "⏸ Pausa"),
    ("cue.btn_resume",         "▶ Retomar"),
    ("cue.btn_stop",           "■ Stop"),
    ("tip.no_repeat",          "Dias para trás consultados para evitar repetir uma faixa. 1 = só hoje, 3 = três dias (recomendado)."),
    ("panel.eventos",          "📅 Eventos"),
    ("dlg.error",              "Erro"),
    ("dlg.backup_title",       "Backup concluído"),
    ("dlg.backup_body",        "✅ Backup criado com sucesso.\n{n} arquivos salvos em:\n{path}"),
    ("dlg.backup_err",         "❌ Erro ao criar backup:\n{err}"),
    ("dlg.sel_backup",         "Selecionar backup GR"),
    ("dlg.btn_restore",        "Restaurar"),
    ("dlg.recovery_err",       "❌ Erro ao restaurar:\n{err}"),
    ("dlg.token_title",        "Token obrigatório"),
    ("dlg.token_body",         "⚠ O relay de internet requer um token de acesso.\nSem token, qualquer um que adivinhe o ID pode controlar o reprodutor.\n\nDigite um token no campo 'Token de acesso (gr-client)' antes de ativar o relay."),
    // Fade
    ("cfg.fundido_excl",       "Pastas sem fade:"),
    ("tip.fundido_excl",       "Os arquivos nessas pastas tocam com início direto (sem crossfade), para não cortar o começo nem o final — útil para locuções/vinhetas."),
    // IA
    ("cfg.ia",                 "Inteligência Artificial:"),
    ("tip.ia",                 "Habilita o assistente de IA integrado (OpenCode com modelos abertos gratuitos)."),
    ("tip.ia_btn",             "Abrir assistente IA para G-Radio"),
    ("btn.ia",                 "IA"),
    // Locutor Automático
    ("cfg.locutor",            "Locutor Automático:"),
    ("tip.locutor",            "Habilita a geração de locuções por IA feita por agentes externos (experimental). O estado é salvo em tmp/locutor_auto para que esses agentes o leiam."),
    ("dlg.ia_warn_title",      "Habilitar Inteligência Artificial"),
    ("dlg.ia_warn_body",       "Esta função usa OpenCode com modelos de IA abertos e gratuitos.\n\nO assistente pode ler e modificar arquivos de programação da rádio.\n\n⚠ O uso de IA pode gerar resultados inesperados. Revise as alterações\nantes de aplicá-las no ar.\n\nVocê aceita estas condições e deseja habilitar a IA?"),
    ("dlg.ia_no_bin",          "⚠ opencode não encontrado.\n\nInstale em: https://opencode.ai\n\nOu coloque o binário em:\n  ~/.local/bin/opencode"),
    ("dlg.ia_accept",          "✅ Aceitar e habilitar"),
    ("dlg.locutor_warn_title", "Habilitar Locutor Automático"),
    ("dlg.locutor_warn_body",  "O Locutor Automático gera locuções de rádio (voz IA) através de um agente de IA externo (Claude/OpenCode), não deste programa.\n\nEsta função só ativa a bandeira que esse agente lê para decidir se deve gerar áudio; sem um agente configurado e em execução, nada acontece.\n\n⚠ O agente pode ler e escrever arquivos de programação da rádio\n(grade, comerciais, eventos) para inserir as locuções geradas.\n\nVocê aceita estas condições e deseja habilitar o Locutor Automático?"),
    ("dlg.locutor_accept",     "✅ Aceitar e habilitar"),
    ("preset.default_name",    "Meu preset"),
];
