<?php
require_once "./app/functions.php";
$pag = basename($_SERVER['PHP_SELF']);
if (comprobar_override(str_replace($_SERVER['DOCUMENT_ROOT'], '', __FILE__))) exit;

//Comprobar si tiene clave del sitio para fichar
$clave_fichar = isset($_GET['clave_fichar']) ? md5(filter_input(INPUT_GET, 'clave_fichar', FILTER_SANITIZE_SPECIAL_CHARS)) : '';

if (BLOQUEO_SITIO_CLAVE && (!isset($_GET['clave_fichar']) || (isset($_GET['clave_fichar']) && $clave_fichar != SITIO_CLAVE_SECRETA_FICHAR))) {
    if (!isset($_COOKIE['clave_fichar']) || $_COOKIE['clave_fichar'] != SITIO_CLAVE_SECRETA_FICHAR) {
        header("Location: " . SITIO_CARPETA . "/iniciar_sesion.php?tipo=error&mensaje=No tienes acceso a esta página, debes iniciar sesión&redirect=index.php");
        exit;
    }
}

gen_plantilla(false, $pag, true, true, 'Fichar', true, true);

$fichador_masivo = get_config('fichador_masivo');
$mostrar_ult_hora = get_config('mostrar_ult_registro_fichador');
$mostrar_apellidos_fichador = get_config('mostrar_apellidos_fichador');
//Coger ultimo registro
$ult_hoy = consulta("SELECT id_empleado,
  SEC_TO_TIME(
    GREATEST(
      IFNULL(TIME_TO_SEC(TIME(NULLIF(hora1,''))),0),
      IFNULL(TIME_TO_SEC(TIME(NULLIF(hora2,''))),0),
      IFNULL(TIME_TO_SEC(TIME(NULLIF(hora3,''))),0),
      IFNULL(TIME_TO_SEC(TIME(NULLIF(hora4,''))),0),
      IFNULL(TIME_TO_SEC(TIME(NULLIF(hora5,''))),0),
      IFNULL(TIME_TO_SEC(TIME(NULLIF(hora6,''))),0)
    )
  ) AS ultima_hora
FROM registros
WHERE fecha = ?
ORDER BY ultima_hora DESC
LIMIT 1;", [date('Y-m-d')], true);
?>
<aside id="showdialog"></aside>
<section class="cristal">
    <?php if (get_config('fichador_titulo')) : ?>
        <h1 class="no-seleccionable negro">¿Quién eres?</h1>
    <?php endif; ?>

    <section class="flex column gap1 alineado anchocompleto">
        <?php
        $fecha = date("Y-m-d");
        if (!empty($consult = consulta(
            "SELECT e.id, e.nombre, e.apellidos
        FROM empleados AS e
        WHERE NOT EXISTS (
        SELECT 1
        FROM bajas_empleado AS b
        WHERE b.id_empleado = e.id
            AND (
            b.fecha_incorporacion IS NULL         -- baja abierta (aún de baja)
            OR b.fecha_incorporacion > CURDATE()  -- reincorporación futura
            )
        )
        ORDER BY e.nombre;",
            [],
            true
        ))) {
            echo "<section id='fichaje'>";
            if ($fichador_masivo) {
                echo '<input type="search" name="fichaje" id="buscador_fichaje" list="lista_empleados" required>';
                echo '<input type="hidden" name="id_empleado" id="id_empleado">';
                echo '<datalist id="lista_empleados">';
            }
            for ($i = 0; $i < count($consult); $i++) {
                $ultimah = null;
                if (!$fichador_masivo && $mostrar_ult_hora) {
                    if (!empty($registro = consulta(
                        "SELECT hora1, hora2, hora3, hora4, hora5, hora6 FROM registros WHERE id_empleado=? AND fecha=? AND activo=1 ORDER BY id DESC;",
                        [$consult[$i]["id"], $fecha],
                        true
                    ))) {
                        $a = 0;
                        for ($o = 1; $o <= 6; $o++) {
                            if (empty($registro[0]["hora" . $o]) || ($registro[0]["hora" . $o] == "00:00:00" && $registro[0]["hora" . $o] == "00:00")) break;
                            $a++;
                        }
                        $ultimah = $registro[0]["hora" . $a];
                        $separado = explode(":", $ultimah);
                        $ultimah = $separado[0] . ":" . $separado[1];
                    }
                }

                // Construir nombre con apellidos si está activada la opción
                $nombre_mostrar = $consult[$i]["nombre"];
                if ($mostrar_apellidos_fichador && !empty($consult[$i]["apellidos"])) {
                    $nombre_mostrar .= " " . $consult[$i]["apellidos"];
                }

                if (!$fichador_masivo) {
                    echo "<section><input type='radio' id=" . $consult[$i]["id"] . " class='iempleado' name='fichaje' value=" . $consult[$i]["id"] . " title='" . htmlspecialchars($nombre_mostrar) . "' onclick='enfocar_pin()' " . (!empty($ultimah) && $ultimah != ":" && $ult_hoy[0]['id_empleado'] == $consult[$i]["id"] ? "checked>" : '>');
                    echo "<label for=" . $consult[$i]["id"] . " class='label-empleado empleado no-seleccionable' title='" . htmlspecialchars($nombre_mostrar) . "'>" . htmlspecialchars($nombre_mostrar) . (!empty($ultimah) && $ultimah != ":" ? "<span class='horafichador'>" . $ultimah . "</span>" : '');
                    echo "</label></section>";
                } else
                    echo '<option value="' . htmlspecialchars($nombre_mostrar) . '" data-id="' . $consult[$i]["id"] . '">' . htmlspecialchars($nombre_mostrar) . '</option>';
            }

            if ($fichador_masivo) echo '</datalist>';

            echo "</section>";
            if (LOCALIZACION && isset($_GET["latitud"])) {
                echo "<input type='hidden' id='latitud' value='" . $_GET['latitud'] . "' />";
                echo "<input type='hidden' id='longitud' value='" . $_GET['longitud'] . "' />";
            } elseif (LOCALIZACION) { ?>
                <script>
                    // Obtener ubicación al cargar la página (cache para uso posterior)
                    var _geoLatitud = '';
                    var _geoLongitud = '';
                    if ("geolocation" in navigator) {
                        navigator.geolocation.getCurrentPosition(function(position) {
                            _geoLatitud = String(position.coords.latitude);
                            _geoLongitud = String(position.coords.longitude);
                        }, function(err) {
                            console.warn('Geolocalización no disponible:', err.message);
                        }, { enableHighAccuracy: true, timeout: 10000, maximumAge: 60000 });
                    }

                    function obtenerUbicacion() {
                        return new Promise(function(resolve) {
                            // Si ya tenemos ubicación cacheada, usarla
                            if (_geoLatitud && _geoLongitud) {
                                resolve({ latitud: _geoLatitud, longitud: _geoLongitud });
                                return;
                            }
                            // Si no, intentar obtenerla ahora
                            if ("geolocation" in navigator) {
                                navigator.geolocation.getCurrentPosition(function(position) {
                                    _geoLatitud = String(position.coords.latitude);
                                    _geoLongitud = String(position.coords.longitude);
                                    resolve({ latitud: _geoLatitud, longitud: _geoLongitud });
                                }, function() {
                                    resolve({ latitud: '', longitud: '' });
                                }, { enableHighAccuracy: true, timeout: 5000, maximumAge: 60000 });
                            } else {
                                resolve({ latitud: '', longitud: '' });
                            }
                        });
                    }
                </script>
            <?php } ?>
            <section class="flex row supercentrado" style="align-items: stretch;">
                <input type="password" id="contraseña" title="Introduce el pin" inputmode="numeric" pattern="\d*" style="width: 4rem; border-radius: .4rem 0 0 .4rem; outline: none;" required>
                <button id="mostrarcontra" type="button" onclick="mostrarContrasena()">
                    <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 640 512" title="Mostrar contraseña">
                        <path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2
                        25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7
                        0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8
                        5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408
                        294.5c8.4-19.3 10.6-41.4 4.8-63.3c-11.1-41.5-47.8-69.4-88.6-71.1c-5.8-.2-9.2 6.1-7.4 11.7c2.1 6.4 3.3
                        13.2 3.3 20.3c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zM373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5
                        0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7
                        0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5L373
                        389.9z" />
                    </svg>
                </button>
            </section>
            <section id="cargando"></section>
            <button class="no-seleccionable btn-p" id="fichar" name="Fichar">Fichar</button>
            <?php if (get_config('recaptcha_fichar')) : ?>
                <input type="hidden" name="recaptcha_token" id="recaptcha_token">
                <input type="hidden" name="recaptcha_action" id="recaptcha_action" value="login">
            <?php endif; ?>
            <aside id="ubicacion"></aside>
        <?php
        } else echo "<section><h1 class='rojo'>¡No hay ningún empleado!</h1></section>";
        ?>
        <?php if (get_config('permitir_fichador_cambiar_tema')) : ?>
            <a class="flex row" onclick="cambiar_modo_claro_oscuro()" id="claro-oscuro" title="Cambiar modo claro y oscuro" style="position: absolute; right:0;bottom:2rem; padding:1rem; border-top-left-radius:50%; border-bottom-left-radius:50%;">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640">
                    <path d="M512 320C512 214 426 128 320 128L320 512C426 512 512 426 512 320zM64 320C64 178.6 178.6 64 320 64C461.4 64 576 178.6 576 320C576 461.4 461.4 576 320 576C178.6 576 64 461.4 64 320z" />
                </svg>
            </a>
        <?php endif; ?>
    </section>
</section>



<?php if (get_config('recaptcha_fichar')) : ?>
    <script src="https://www.google.com/recaptcha/enterprise.js?render=<?= RECAPTCHA_CLAVE ?>"></script>
<?php endif; ?>
<script>
    window.onload = function() {
        document.getElementById('contraseña').addEventListener('input', validar);
        let fichar = document.getElementById('fichar');

        <?php if ($fichador_masivo): ?>
                // === Enlaza input ↔ datalist al cargar, no en el click ===
                // ====== AUTOCOMPLETADO INTELIGENTE ======
                (function() {
                    const input = document.getElementById('buscador_fichaje');
                    const lista = document.getElementById('lista_empleados');
                    const hidden = document.getElementById('id_empleado');

                    if (!input || !lista || !hidden) return;

                    // Cachea las opciones (value = nombre completo que ve el usuario; data-id = id)
                    const opciones = Array.from(lista.options).map((o, idx) => ({
                        idx,
                        value: o.value,
                        id: o.dataset.id || '',
                        norm: normaliza(o.value)
                    }));

                    function normaliza(s) {
                        return (s || '')
                            .toLowerCase()
                            .normalize('NFD').replace(/[\u0300-\u036f]/g, '') // quita acentos
                            .replace(/\s+/g, ' ') // espacios únicos
                            .trim();
                    }

                    // Scoring: mayor es mejor
                    function puntua(queryNorm, candidato) {
                        if (!queryNorm) return 0;
                        const hay = candidato.norm;
                        if (hay === queryNorm) return 1000; // match exacto
                        if (hay.startsWith(queryNorm)) return 900; // empieza por
                        // empieza por palabra
                        if (new RegExp(`(^|\\s)${escapeReg(queryNorm)}`).test(hay)) return 800;
                        if (hay.includes(queryNorm)) return 600; // contiene
                        // fuzzy (subsecuencia)
                        const fz = subsecuencia(queryNorm, hay);
                        if (fz) return 400 + Math.max(0, 50 - fz); // penaliza distancia
                        return 0;
                    }

                    function escapeReg(s) {
                        return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
                    }

                    // Devuelve “costo” de subsecuencia (0 = muy pegado, >0 peor). false si no es subsecuencia
                    function subsecuencia(needle, hay) {
                        let i = 0,
                            j = 0,
                            saltos = 0;
                        while (i < needle.length && j < hay.length) {
                            if (needle[i] === hay[j]) {
                                i++;
                                j++;
                            } else {
                                j++;
                                saltos++;
                            }
                        }
                        return i === needle.length ? saltos : false;
                    }

                    function mejorCoincidencia(q) {
                        const qn = normaliza(q);
                        if (!qn) return null;
                        let mejor = null;
                        let mejorScore = 0;
                        for (const op of opciones) {
                            const s = puntua(qn, op);
                            if (s > mejorScore || (s === mejorScore && mejor && op.value.length < mejor.value.length)) {
                                mejor = op;
                                mejorScore = s;
                            }
                        }
                        return mejorScore > 0 ? mejor : null;
                    }

                    function actualizar() {
                        const q = input.value;
                        const m = mejorCoincidencia(q);
                        if (m) {
                            hidden.value = m.id;
                            // (opcional) muestra el elegido como tooltip
                            input.title = m.value;
                            input.dataset.bestId = m.id;
                        } else {
                            hidden.value = '';
                            input.title = '';
                            delete input.dataset.bestId;
                        }
                    }

                    // Cambia dinámicamente según tecleas
                    input.addEventListener('input', actualizar);
                    input.addEventListener('change', () => {
                        actualizar();
                        enfocar_pin();
                    });


                    // Si el usuario pulsa Enter y hay “mejor”, fija el valor exacto
                    input.addEventListener('keydown', (e) => {
                        if (e.key === 'Enter' && !hidden.value && input.dataset.bestId) {
                            const m = mejorCoincidencia(input.value);
                            if (m) {
                                input.value = m.value; // autocompleta al mejor
                                hidden.value = m.id;
                            }
                        }
                    });

                    // Inicial
                    actualizar();
                })();

        <?php endif; ?>

        <?php if (get_config('tipo_registro_fichar')): ?>
        fichar.addEventListener('click', () => {
            if (pre_validar_fichaje()) {
                ajax('dialogs/dialog_tipo_registro', 'showdialog', '', ['cargar_dialog()']);
            }
        });
        <?php else: ?>
        fichar.addEventListener('click', () => fichar_empleado(''));
        <?php endif; ?>
    };

    function pre_validar_fichaje() {
        if (!comprobarConexion()) {
            crear_notificacion('error', 'No tienes conexión a Internet');
            <?php if (get_config('sonidos_fichador')) : ?>
            new Audio('assets/sounds/ficha_error.mp3').play();
            <?php endif; ?>
            return false;
        }
        <?php if ($fichador_masivo): ?>
            // Toma el ID ya resuelto en el hidden
            var idValor = document.getElementById('id_empleado').value;
            if (!idValor) {
                crear_notificacion('error', 'Selecciona un empleado de la lista.');
                <?php if (get_config('sonidos_fichador')) : ?>
                new Audio('assets/sounds/ficha_error.mp3').play();
                <?php endif; ?>
                document.getElementById('buscador_fichaje').focus();
                return false;
            }
        <?php else: ?>
            let empleadoSeleccionado = document.querySelector('input[name="fichaje"]:checked');
            if (!empleadoSeleccionado) {
                crear_notificacion('error', 'Selecciona tu nombre');
                <?php if (get_config('sonidos_fichador')) : ?>
                new Audio('assets/sounds/ficha_error.mp3').play();
                <?php endif; ?>
                return false;
            }
        <?php endif; ?>
        let pin = document.getElementById('contraseña');
        if (pin && pin.value == '') {
            crear_notificacion('error', 'No has introducido el pin');
            <?php if (get_config('sonidos_fichador')) : ?>
            new Audio('assets/sounds/ficha_error.mp3').play();
            <?php endif; ?>
            return false;
        }
        return true;
    }

    <?php if (LOCALIZACION) : ?>
    async function fichar_empleado(tipo = '') {
    <?php else: ?>
    function fichar_empleado(tipo = '') {
    <?php endif; ?>
        if (!pre_validar_fichaje()) return;
        
        let pin = document.getElementById('contraseña').value;
        <?php if (!$fichador_masivo): ?>
            let id_empleado = document.querySelector('input[name="fichaje"]:checked');
            var idValor = id_empleado ? id_empleado.value : '';
        <?php else: ?>
            // Toma el ID ya resuelto en el hidden
            var idValor = document.getElementById('id_empleado').value;
            if (!idValor) {
                crear_notificacion('error', 'Selecciona un empleado de la lista.');
                document.getElementById('buscador_fichaje').focus();
                return;
            }
        <?php endif; ?>

        <?php if (LOCALIZACION) : ?>
            let latitud = '';
            let longitud = '';
            // Comprobar si hay inputs estáticos (vienen por GET)
            let latitudEl = document.getElementById('latitud');
            let longitudEl = document.getElementById('longitud');
            if (latitudEl && latitudEl.value) {
                latitud = latitudEl.value;
                longitud = longitudEl ? longitudEl.value : '';
            } else if (typeof obtenerUbicacion === 'function') {
                // Obtener ubicación en tiempo real y esperar
                let ubicacion = await obtenerUbicacion();
                latitud = ubicacion.latitud;
                longitud = ubicacion.longitud;
            }
        <?php endif; ?>

        <?php if (get_config('recaptcha_fichar')) : ?>
            const SITE_KEY = '<?= RECAPTCHA_CLAVE ?>';
            const ACTION = '<?= RECAPTCHA_ACTION_FICHAR ?>';
            grecaptcha.enterprise.ready(function() {
                grecaptcha.enterprise.execute(SITE_KEY, {
                    action: ACTION
                }).then(function(token) {
                    document.getElementById('recaptcha_token').value = token;
                    document.getElementById('recaptcha_action').value = ACTION;
                });
            });
            let token = document.getElementById('recaptcha_token').value;
            let action = document.getElementById('recaptcha_action').value;
        <?php endif; ?>

        bloquear_btn_fichar();

        if (window.timeoutFichaje) clearTimeout(window.timeoutFichaje);
        window.timeoutFichaje = setTimeout(() => {
            crear_notificacion('error', 'Parece que tienes problemas de conexión, prueba cerrar por completo la aplicación y probar de nuevo');
            <?php if (get_config('sonidos_fichador')) : ?>
            let audioError = new Audio('assets/sounds/ficha_error.mp3');
            audioError.play();
            setTimeout(() => {
                let audioError2 = new Audio('assets/sounds/ficha_error.mp3');
                audioError2.play();
            }, 500);
            <?php endif; ?>
            desbloquear_btn_fichar();
        }, 20000);

        ajax('forms/fichar', 'notificaciones', 'pag_origen=index&tipo_registro=' + tipo + '&id_empleado=' + idValor + '&pin=' + pin +
            <?php
            if (LOCALIZACION) echo "'&latitud=' + latitud + '&longitud=' + longitud";
            else echo "''"; ?> +
            <?php
            if (get_config('recaptcha_fichar'))
                echo "'&recaptcha_token=' + token + '&recaptcha_action=' + action";
            else
                echo "''";
            ?>,
            ['vaciar_pin_y_enfoque()','desbloquear_btn_fichar()','if (window.timeoutFichaje) clearTimeout(window.timeoutFichaje)'
                <?= (get_config('mostrar_ult_registro_fichador')) ? ',"recargar_pag()"' : '' ?>
                <?= (get_config('sonidos_fichador')) ? ',"reproducir_sonido()"' : '' ?>
            ]);
    }

    function bloquear_btn_fichar(){
        let fichar = document.getElementById('fichar');
        fichar.style.display='none';
        poner_cargando();
    }

    function desbloquear_btn_fichar(){
        let fichar = document.getElementById('fichar');
        fichar.style.display='flex';
        quitar_cargando();
    }


    function validar() {
        var contra = document.getElementById('contraseña').value;
        var cleaned = contra.replace(/\D/g, '');

        if (cleaned.length > <?= get_config('digitos_pin') ?>) {
            cleaned = cleaned.slice(0, <?= get_config('digitos_pin') ?>);
        }

        document.getElementById('contraseña').value = cleaned;

        var patron = /^\d{<?= get_config('digitos_pin') ?>}$/;
        if (patron.test(cleaned)) {
            document.getElementById('contraseña').classList.remove('input-invalid');
            document.getElementById('contraseña').classList.add('input-valid');
            document.getElementById('fichar').focus();
            <?php if (get_config('autofichar')) : ?>
                <?php if (get_config('tipo_registro_fichar')): ?>
                    if (pre_validar_fichaje()) {
                        ajax('dialogs/dialog_tipo_registro', 'showdialog', '', ['cargar_dialog()']);
                    }
                <?php else: ?>
                    fichar_empleado('');
                <?php endif; ?>
            <?php endif; ?>
        } else {
            document.getElementById('contraseña').classList.remove('input-valid');
            document.getElementById('contraseña').classList.add('input-invalid');
        }
    }

    function enfocar_pin() {
        let contra = document.getElementById("contraseña");
        contra.focus();
    }

    function vaciar_pin_y_enfoque() {
        document.getElementById('contraseña').value = '';
        document.getElementById('fichar').blur();
        <?php if ($fichador_masivo) : ?>
            let buscador_fichaje = document.getElementById("buscador_fichaje");
            if (document.getElementsByClassName('noti-correcto').length > 0) {
                buscador_fichaje.value = '';
                buscador_fichaje.focus();
            } else if (document.getElementsByClassName('noti-advertencia').length > 0) {
                buscador_fichaje.value = '';
                buscador_fichaje.focus();
            } else {
                document.getElementById('contraseña').focus();
            }
        <?php
        else: ?>
            if (document.getElementsByClassName('noti-error').length > 0) {
                document.getElementById('contraseña').focus();
            }
        <?php endif; ?>
    }

    function comprobarConexion() {
        if (navigator.onLine)
            return true;
        else
            return false;
    }

    function recargar_pag() {
        if (comprobarConexion()) {
            setTimeout(function() {
                location.reload();
            }, 2000);
        }
    }
    <?php if (get_config('permitir_fichador_cambiar_tema')) : ?>

        function cambiar_modo_claro_oscuro() {
            const root = document.documentElement;
            const actual = getComputedStyle(root).colorScheme;
            let tema = root.getAttribute('data-theme');
            if (tema) {
                if (actual.includes('dark') && !actual.includes('light')) {
                    root.style.colorScheme = 'light';
                    root.setAttribute('data-theme', 'light');
                    actualizar_conf('fichador_tema', 'light');
                    localStorage.setItem('theme', root.style.colorScheme);
                } else {
                    root.style.colorScheme = 'dark';
                    root.setAttribute('data-theme', 'dark');
                    actualizar_conf('fichador_tema', 'dark');
                    localStorage.setItem('theme', root.style.colorScheme);
                }
            } else {
                root.style.colorScheme = 'light';
                root.setAttribute('data-theme', 'light');
                actualizar_conf('fichador_tema', 'light');
                localStorage.setItem('theme', root.style.colorScheme);
            }
        }

        function actualizar_conf(meta, valor) {
            ajax('forms/actualizar_configuracion', 'notificaciones', 'conf=' + meta + '&valor=' + valor, [])
        }
    <?php endif; ?>

    <?php if (get_config('sonidos_fichador')) : ?>

        function reproducir_sonido() {
            //Comprobar si es bueno o no
            if (document.getElementsByClassName('noti-correcto').length > 0)
                sonido = new Audio('assets/sounds/ficha.mp3');

            else
                sonido = new Audio('assets/sounds/ficha_error.mp3');

            sonido.play();
        }
    <?php endif; ?>
</script>
<?php footer(false) ?>