<?php
/**
 * modules/turnero/views/voces.php
 * Prueba de voces del televisor — /erp.php?m=turnero&v=voces
 *
 * Las voces disponibles no las decide el ERP sino el equipo: dependen del
 * sistema operativo y del navegador del televisor. Por eso esta página hay que
 * abrirla EN EL TELEVISOR, no en el computador de la oficina: cada equipo
 * ofrece una lista distinta.
 *
 * Sirve para oír cada voz con el texto real de un llamado y elegir la que
 * quede. Distingue las locales de las que se bajan de internet, que son las
 * que se entrecortan cuando el wifi flaquea.
 */
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Prueba de voces · Turnero</title>
<style>
    * { box-sizing: border-box; }
    body {
        margin: 0; padding: 24px;
        font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
        background: #0f172a; color: #e2e8f0;
    }
    h1 { font-size: 1.5rem; margin: 0 0 4px; }
    .sub { color: #94a3b8; font-size: .95rem; margin-bottom: 20px; }
    .aviso {
        background: #1e293b; border-left: 4px solid #38bdf8;
        padding: 12px 16px; border-radius: 6px; margin-bottom: 22px;
        font-size: .92rem; line-height: 1.5;
    }
    .fila {
        display: flex; align-items: center; gap: 14px;
        background: #1e293b; border-radius: 8px;
        padding: 14px 16px; margin-bottom: 10px;
        border: 1px solid #334155;
    }
    .fila.elegida { border-color: #38bdf8; background: #1e3a52; }
    .nom { font-weight: 600; flex: 1; min-width: 0; }
    .nom small { display: block; font-weight: 400; color: #94a3b8; font-size: .8rem; }
    .tag {
        font-size: .72rem; padding: 3px 9px; border-radius: 99px;
        white-space: nowrap; font-weight: 600;
    }
    .local  { background: #14532d; color: #86efac; }
    .remota { background: #7c2d12; color: #fdba74; }
    .actual { background: #0c4a6e; color: #7dd3fc; }
    button {
        background: #0284c7; color: #fff; border: 0;
        padding: 10px 20px; border-radius: 6px; cursor: pointer;
        font-size: .95rem; font-weight: 600; white-space: nowrap;
    }
    button:hover { background: #0369a1; }
    #vacio { color: #94a3b8; padding: 20px 0; }
</style>
</head>
<body>

<h1>Prueba de voces</h1>
<div class="sub">Ábrala <strong>en el televisor</strong>: cada equipo ofrece voces distintas.</div>

<div class="aviso">
    Las <span class="tag local">local</span> salen del propio equipo: nunca se cortan, aunque suenen
    algo más robóticas.<br>
    Las <span class="tag remota">de internet</span> suenan más naturales, pero se bajan de los
    servidores de Google en cada llamado. Con wifi débil se entrecortan o no suenan.
    <br><br>
    Oiga las que aparezcan y dígame cuál prefiere.
</div>

<div id="lista"><div id="vacio">Cargando voces…</div></div>

<script>
// El mismo texto que dice la pantalla de turnos, para juzgarlas en condiciones
const TEXTO = 'Turno A 0 1, María Fernanda Gómez, pase a Consultorio 2';

// Réplica de la preferencia de display_global.php, para señalar cuál está
// sonando. Si allá se cambia el orden, hay que cambiarlo aquí también.
const VOCES_PREFERIDAS = ['sabina', 'paulina'];

function vozActual(voces) {
    if (!voces.length) return null;
    const locales = voces.filter(v => v.localService);
    for (const nombre of VOCES_PREFERIDAS) {
        const v = locales.find(v => v.name.toLowerCase().includes(nombre));
        if (v) return v;
    }
    for (const lang of ['es-MX','es-419','es-US','es-CO']) {
        const v = locales.find(v => v.lang === lang);
        if (v) return v;
    }
    if (locales.length) return locales[0];
    for (const lang of ['es-CO','es-419','es-MX','es-US','es-ES']) {
        const v = voces.find(v => v.lang === lang);
        if (v) return v;
    }
    return voces[0];
}

function probar(voz) {
    window.speechSynthesis.cancel();
    const u = new SpeechSynthesisUtterance(TEXTO);
    u.voice = voz;
    u.lang  = voz.lang;
    u.rate  = 0.95;
    u.pitch = 1.05;
    window.speechSynthesis.speak(u);
}

function pintar() {
    const todas  = window.speechSynthesis.getVoices();
    const es     = todas.filter(v => v.lang && v.lang.toLowerCase().startsWith('es'));
    const lista  = document.getElementById('lista');
    const actual = vozActual(es);

    if (!es.length) {
        lista.innerHTML = '<div id="vacio">Este equipo no tiene ninguna voz en español instalada. '
            + 'Habría que instalarle una desde la configuración del sistema, '
            + 'o dejar el llamado solo con el pito y el cartel.</div>';
        return;
    }

    // Las locales primero: son las que interesan
    es.sort((a, b) => (b.localService - a.localService) || a.name.localeCompare(b.name));

    lista.innerHTML = '';
    es.forEach((v, i) => {
        const fila = document.createElement('div');
        fila.className = 'fila' + (v === actual ? ' elegida' : '');
        fila.innerHTML =
            '<div class="nom">' + v.name + '<small>' + v.lang + '</small></div>'
            + (v.localService ? '<span class="tag local">local</span>'
                              : '<span class="tag remota">de internet</span>')
            + (v === actual ? '<span class="tag actual">la de ahora</span>' : '');
        const b = document.createElement('button');
        b.textContent = 'Oír';
        b.onclick = () => probar(v);
        fila.appendChild(b);
        lista.appendChild(fila);
    });
}

// getVoices() suele venir vacío en la primera llamada: el navegador las carga aparte
window.speechSynthesis.onvoiceschanged = pintar;
pintar();
setTimeout(pintar, 600);
</script>

</body>
</html>
