// ============ i18n ============
const I18N = {
  es: {
    nav_overview: "Resumen",
    nav_analytics: "Analítica",
    nav_trends: "Tendencias",
    nav_workflow: "Workflow",
    nav_admin: "Administración",
    nav_main: "Principal",
    nav_ops: "Operaciones",
    role_admin: "Admin",
    search_placeholder: "Buscar consultas, usuarios, ejecuciones…",
    overview_title: "Resumen",
    overview_crumbs: "Dashboard · Vista general",
    kpi_searches: "Búsquedas",
    kpi_unique_terms: "Términos únicos",
    kpi_avg_daily: "Promedio diario",
    kpi_ctr: "CTR global",
    kpi_zero: "Zero-results",
    kpi_latency: "Latencia p95",
    latency_title: "Latencia del buscador",
    latency_current: "Ahora",
    latency_avg: "Promedio",
    last_24h: "últimas 24 h",
    tip_latency: "Latencia p95 del tráfico hacia el buscador, medida en el balanceador de carga. Menos es mejor.",
    traffic_title: "Tráfico del buscador",
    traffic_now: "Ahora",
    traffic_peak: "Pico",
    traffic_total: "solicitudes",
    rps_unit: "req/s",
    tip_traffic: "Solicitudes por segundo recibidas por el buscador, medidas en el balanceador de carga.",
    trend_searches: "Volumen de búsquedas",
    top_terms: "Términos más consultados",
    zero_results: "Búsquedas sin resultados",
    latest_run: "Última ingesta",
    recent_users: "Usuarios recientes",
    vs_prev: "vs semana previa",
    analytics_title: "Analítica de búsquedas",
    analytics_crumbs: "Dashboard · Analítica",
    period_24h: "24h",
    period_7d: "7d",
    period_30d: "30d",
    period_90d: "90d",
    period_365d: "1a",
    terms_full: "Top 50 términos",
    rank: "#",
    term: "Término",
    searches: "Búsquedas",
    ctr: "CTR",
    clicks: "Clicks",
    zero_rate: "% sin resultados",
    trend: "Tendencia",
    zero_list: "Términos sin resultados",
    suggest_fix: "Agregar sinónimo",
    pct_of_total: "% del total",
    loading: "Cargando…",
    api_error: "Error al cargar datos",
    no_data: "Sin datos en este período",
    data_range: "Datos hasta",
    trends_title: "Tendencias",
    trends_crumbs: "Dashboard · Tendencias",
    rising_terms: "Términos al alza",
    falling_terms: "Términos a la baja",
    new_terms: "Términos nuevos",
    zero_rising: "Zero-results al alza",
    zero_new: "Zero-results nuevos",
    trends_compare: "Comparado con período anterior",
    current_period: "Período actual",
    previous_period: "Período anterior",
    vs_previous: "vs anterior",
    new_label: "NUEVO",
    term_details: "Estadísticas del término",
    first_seen: "Primera búsqueda",
    last_seen: "Última búsqueda",
    daily_volume: "Volumen diario",
    daily_zero: "Zero-results diarios",
    term_not_found: "Sin registros para este término en el período",
    search_hint: "Presiona Enter para ver estadísticas",
    elapsed: "Tiempo",
    records_per_sec: "Registros/s",
    stage_metrics: "Métricas",
    load_error: "Error al consultar el workflow",
    refresh: "Refrescar",
    live: "Vivo",
    sign_in: "Iniciar sesión",
    sign_out: "Salir",
    signed_in_as: "Sesión",
    read_only: "Solo lectura",
    password: "Contraseña",
    admin_restricted: "Acceso restringido",
    admin_restricted_sub: "Ingresa con tu cuenta autorizada para acceder al dashboard.",
    login_tagline: "AI · SEARCH · ANALYTICS",
    powered_by: "Powered by",
    amarello: "Amarello",
    anteater: "Anteater",
    anteater_slogan: "Intelligent Search",
    anteater_tagline: "Anteater · Intelligent Search",
    tip_searches: "Total de búsquedas realizadas por usuarios en el período seleccionado.",
    tip_unique_terms: "Cantidad de términos distintos buscados (sin contar duplicados).",
    tip_avg_daily: "Promedio de búsquedas por día durante el período.",
    tip_zero_kpi: "Porcentaje de búsquedas que no devolvieron ningún producto. Indicador de demanda no cubierta por el catálogo.",
    tip_volume: "Volumen diario de búsquedas a lo largo del período seleccionado.",
    tip_top_terms: "Los términos más buscados, ordenados por número de consultas.",
    tip_latest_run: "Última ejecución del workflow de ingesta del catálogo.",
    tip_zero_list: "Términos que los usuarios buscaron pero no obtuvieron resultados. Útil para detectar productos faltantes o errores de sinonimia.",
    tip_terms_full: "Top 50 términos más consultados con su participación en el total.",
    tip_trends_compare: "Comparación del período actual contra el período inmediato anterior de igual duración.",
    tip_rising: "Términos cuyas búsquedas aumentaron respecto al período anterior.",
    tip_falling: "Términos cuyas búsquedas disminuyeron respecto al período anterior.",
    tip_new_terms: "Términos que aparecieron por primera vez en este período (cero búsquedas antes).",
    tip_zero_rising: "Términos sin resultados cuya demanda está creciendo. Oportunidades de catálogo.",
    tip_zero_new: "Términos sin resultados totalmente nuevos. Potenciales productos a considerar.",
    tip_tornado: "Comparación visual lado a lado: izquierda los que más bajaron, derecha los que más subieron.",
    tip_workflow_graph: "Flujo de ingesta: valida acceso, carga catálogo, enriquece con IA, genera embeddings y publica al índice.",
    tip_exec_history: "Historial de las últimas ejecuciones del workflow con estado y métricas.",
    tip_admin_users: "Usuarios con acceso al dashboard (autenticados con Firebase y con el claim correspondiente).",
    tip_term_details: "Estadísticas detalladas para un término específico: volumen, zero-rate y cambio en el tiempo.",
    tip_analyzed: "Suma de términos al alza + a la baja + nuevos que cumplen el umbral mínimo de actividad.",
    per_category: "Por categoría",
    tip_per_category: "Cantidad de términos a mostrar en cada categoría (al alza, a la baja, nuevos). Mínimo {min}, máximo {max}.",
    forbidden_title: "Sin permisos",
    forbidden_sub: "Tu cuenta no tiene el claim cliente = {cliente} requerido para administrar.",
    temp_password: "Contraseña temporal",
    temp_password_hint: "Dejar vacío para invitación sin contraseña",
    invite_link: "Liga de activación",
    copy_link: "Copiar liga",
    copied: "Copiado",
    user_created: "Usuario creado",
    user_invited: "Invitación enviada a",
    user_deleted: "Usuario eliminado",
    delete_user: "Eliminar usuario",
    confirm_delete: "¿Seguro que quieres eliminar a {name}?",
    no_users: "Sin usuarios con acceso para este cliente",
    workflow_title: "Workflow de ingesta",
    workflow_crumbs: "Dashboard · Workflow",
    run_now: "Ejecutar ahora",
    push: "Push",
    push_terminado: "Terminado",
    push_iniciado: "En cola",
    push_procesando: "Procesando",
    push_confirm_title: "Ejecutar push",
    push_confirm_body: "Se iniciará un push completo del catálogo. No se puede lanzar otro hasta que termine. ¿Continuar?",
    push_started: "Push iniciado",
    push_running_hint: "Hay un push en curso; espera a que termine.",
    workflow_graph: "Diagrama de ejecución",
    exec_history: "Historial de ejecuciones",
    run_id: "Run ID",
    started: "Inicio",
    duration: "Duración",
    records: "Registros",
    status: "Estado",
    s_setup: "Setup",
    s_ingest: "Ingesta a DB",
    s_enhance: "Enhanced de productos",
    s_vector: "Vectorización",
    s_confirm: "Confirmación",
    s_setup_sub: "Valida conexión y permisos",
    s_ingest_sub: "Carga cruda al staging",
    s_enhance_sub: "Enriquecimiento con IA",
    s_vector_sub: "Genera embeddings",
    s_confirm_sub: "Publica al índice",
    admin_title: "Administración",
    admin_crumbs: "Dashboard · Usuarios",
    add_user: "Agregar usuario",
    invite_user: "Invitar por email",
    users: "Usuarios",
    filter_role: "Rol",
    filter_status: "Estado",
    name: "Nombre",
    email: "Email",
    role: "Rol",
    last_active: "Última actividad",
    actions: "Acciones",
    all: "Todos",
    active: "Activo",
    invited: "Invitado",
    suspended: "Suspendido",
    new_user: "Nuevo usuario",
    full_name: "Nombre completo",
    send_invite: "Enviar invitación",
    cancel: "Cancelar",
    save: "Guardar",
    density: "Densidad",
    comfortable: "Cómoda",
    compact: "Compacta",
    theme: "Tema",
    dark: "Oscuro",
    light: "Claro",
    language: "Idioma",
    spanish: "Español",
    english: "English",
    tweaks: "Tweaks",
    success: "Completado",
    running: "En ejecución",
    failed: "Fallido",
    queued: "En cola",
    pending: "Pendiente",
    of: "de",
    records_count: "registros",
    last_run_ago: "hace",
    seconds: "s",
    minutes: "min",
    hours: "h",
    days: "d",
    signal_strong: "señal fuerte",
    rising: "al alza",
    falling: "a la baja",
    view_all: "Ver todos",
    filter: "Filtrar",
    export: "Exportar",
    never: "Nunca",
    next_run_in: "Próxima en",
  },
  en: {
    nav_overview: "Overview",
    nav_analytics: "Analytics",
    nav_trends: "Trends",
    nav_workflow: "Workflow",
    nav_admin: "Admin",
    nav_main: "Main",
    nav_ops: "Operations",
    role_admin: "Admin",
    search_placeholder: "Search queries, users, runs…",
    overview_title: "Overview",
    overview_crumbs: "Dashboard · Overview",
    kpi_searches: "Searches",
    kpi_unique_terms: "Unique terms",
    kpi_avg_daily: "Daily average",
    kpi_ctr: "Global CTR",
    kpi_zero: "Zero-results",
    kpi_latency: "p95 Latency",
    latency_title: "Search latency",
    latency_current: "Now",
    latency_avg: "Average",
    last_24h: "last 24 h",
    tip_latency: "p95 latency of traffic to the search service, measured at the load balancer. Lower is better.",
    traffic_title: "Search traffic",
    traffic_now: "Now",
    traffic_peak: "Peak",
    traffic_total: "requests",
    rps_unit: "req/s",
    tip_traffic: "Requests per second received by the search service, measured at the load balancer.",
    trend_searches: "Search volume",
    top_terms: "Top queried terms",
    zero_results: "Zero-result searches",
    latest_run: "Latest ingest",
    recent_users: "Recent users",
    vs_prev: "vs prev. week",
    analytics_title: "Search analytics",
    analytics_crumbs: "Dashboard · Analytics",
    period_24h: "24h",
    period_7d: "7d",
    period_30d: "30d",
    period_90d: "90d",
    period_365d: "1y",
    terms_full: "Top 50 terms",
    rank: "#",
    term: "Term",
    searches: "Searches",
    ctr: "CTR",
    clicks: "Clicks",
    zero_rate: "% zero-results",
    trend: "Trend",
    zero_list: "Zero-result terms",
    suggest_fix: "Add synonym",
    pct_of_total: "% of total",
    loading: "Loading…",
    api_error: "Failed to load data",
    no_data: "No data in this period",
    data_range: "Data through",
    trends_title: "Trends",
    trends_crumbs: "Dashboard · Trends",
    rising_terms: "Rising terms",
    falling_terms: "Falling terms",
    new_terms: "New terms",
    zero_rising: "Rising zero-results",
    zero_new: "New zero-results",
    trends_compare: "Compared to previous period",
    current_period: "Current period",
    previous_period: "Previous period",
    vs_previous: "vs previous",
    new_label: "NEW",
    term_details: "Term statistics",
    first_seen: "First seen",
    last_seen: "Last seen",
    daily_volume: "Daily volume",
    daily_zero: "Daily zero-results",
    term_not_found: "No records for this term in period",
    search_hint: "Press Enter to view stats",
    elapsed: "Time",
    records_per_sec: "Records/s",
    stage_metrics: "Metrics",
    load_error: "Failed to query workflow",
    refresh: "Refresh",
    live: "Live",
    sign_in: "Sign in",
    sign_out: "Sign out",
    signed_in_as: "Session",
    read_only: "Read-only",
    password: "Password",
    admin_restricted: "Restricted access",
    admin_restricted_sub: "Sign in with your authorized account to access the dashboard.",
    login_tagline: "AI · SEARCH · ANALYTICS",
    powered_by: "Powered by",
    amarello: "Amarello",
    anteater: "Anteater",
    anteater_slogan: "Intelligent Search",
    anteater_tagline: "Anteater · Intelligent Search",
    tip_searches: "Total searches performed by users in the selected period.",
    tip_unique_terms: "Distinct terms searched (duplicates not counted).",
    tip_avg_daily: "Average searches per day during the period.",
    tip_zero_kpi: "Share of searches that returned no products. Signals unmet demand in the catalog.",
    tip_volume: "Daily search volume across the selected period.",
    tip_top_terms: "Most searched terms, ranked by query count.",
    tip_latest_run: "Latest run of the catalog-ingest workflow.",
    tip_zero_list: "Terms users searched that returned no results. Useful to spot missing products or synonym gaps.",
    tip_terms_full: "Top 50 most queried terms and their share of total searches.",
    tip_trends_compare: "Current period compared against the immediately prior period of equal length.",
    tip_rising: "Terms whose search volume grew vs. the previous period.",
    tip_falling: "Terms whose search volume dropped vs. the previous period.",
    tip_new_terms: "Terms that appear for the first time in this period (zero searches before).",
    tip_zero_rising: "Zero-result terms with growing demand. Clear catalog opportunities.",
    tip_zero_new: "Brand-new zero-result terms. Potential products to consider.",
    tip_tornado: "Side-by-side comparison: biggest drops on the left, biggest rises on the right.",
    tip_workflow_graph: "Ingest flow: validate access, load the catalog, enrich descriptions with AI, generate embeddings, publish to the search index.",
    tip_exec_history: "Recent workflow executions with their state and metrics.",
    tip_admin_users: "Users with dashboard access (Firebase-authenticated and holding the required claim).",
    tip_term_details: "Per-term statistics: volume, zero-rate, and change over time.",
    tip_analyzed: "Sum of rising + falling + new terms that meet the minimum activity threshold.",
    per_category: "Per category",
    tip_per_category: "How many terms to show per category (rising, falling, new). Min {min}, max {max}.",
    forbidden_title: "Forbidden",
    forbidden_sub: "Your account lacks the cliente = {cliente} claim required to administer.",
    temp_password: "Temp password",
    temp_password_hint: "Leave blank for passwordless invite",
    invite_link: "Activation link",
    copy_link: "Copy link",
    copied: "Copied",
    user_created: "User created",
    user_invited: "Invitation sent to",
    user_deleted: "User deleted",
    delete_user: "Delete user",
    confirm_delete: "Delete {name}?",
    no_users: "No users with access for this cliente",
    workflow_title: "Ingest workflow",
    workflow_crumbs: "Dashboard · Workflow",
    run_now: "Run now",
    push: "Push",
    push_terminado: "Finished",
    push_iniciado: "Queued",
    push_procesando: "Processing",
    push_confirm_title: "Run push",
    push_confirm_body: "A full catalog push will start. Another one can't be launched until it finishes. Continue?",
    push_started: "Push started",
    push_running_hint: "A push is in progress; wait for it to finish.",
    workflow_graph: "Execution graph",
    exec_history: "Execution history",
    run_id: "Run ID",
    started: "Started",
    duration: "Duration",
    records: "Records",
    status: "Status",
    s_setup: "Setup",
    s_ingest: "DB ingest",
    s_enhance: "Product enhancement",
    s_vector: "Vectorization",
    s_confirm: "Confirmation",
    s_setup_sub: "Validate connection & perms",
    s_ingest_sub: "Load raw into staging",
    s_enhance_sub: "AI enrichment",
    s_vector_sub: "Generate embeddings",
    s_confirm_sub: "Publish to index",
    admin_title: "Administration",
    admin_crumbs: "Dashboard · Users",
    add_user: "Add user",
    invite_user: "Invite by email",
    users: "Users",
    filter_role: "Role",
    filter_status: "Status",
    name: "Name",
    email: "Email",
    role: "Role",
    last_active: "Last active",
    actions: "Actions",
    all: "All",
    active: "Active",
    invited: "Invited",
    suspended: "Suspended",
    new_user: "New user",
    full_name: "Full name",
    send_invite: "Send invite",
    cancel: "Cancel",
    save: "Save",
    density: "Density",
    comfortable: "Comfortable",
    compact: "Compact",
    theme: "Theme",
    dark: "Dark",
    light: "Light",
    language: "Language",
    spanish: "Español",
    english: "English",
    tweaks: "Tweaks",
    success: "Success",
    running: "Running",
    failed: "Failed",
    queued: "Queued",
    pending: "Pending",
    of: "of",
    records_count: "records",
    last_run_ago: "",
    seconds: "s ago",
    minutes: "m ago",
    hours: "h ago",
    days: "d ago",
    signal_strong: "strong signal",
    rising: "rising",
    falling: "falling",
    view_all: "View all",
    filter: "Filter",
    export: "Export",
    never: "Never",
    next_run_in: "Next in",
  },
};

function useT(lang) {
  return React.useCallback((k) => (I18N[lang] && I18N[lang][k]) || k, [lang]);
}

Object.assign(window, { I18N, useT });
