<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>BladeCAPTCHA Demo - Adjusted Checkbox</title>
        <link rel="stylesheet" href="css/css.css">
        <style>
            :root {
                --bg-color: #1e1e1e;
                --text-color: #f5f5f5;
                --accent-color: #00bfa6;
                --button-bg: #00bfa6;
                --button-text: #000;
                --button-hover: #00a08d;
                font-size: 14px;
            }

            body {
                background-color: var(--bg-color);
                color: var(--text-color);
                font-family: Verdana, Geneva, sans-serif;
                margin: 2rem;
            }

            form { margin: 0 auto; max-width: 480px; }

            .form-group { display: flex; flex-direction: column; margin-bottom: 1.5rem; }

            label {
                color: var(--accent-color);
                font-weight: 600;
                margin-bottom: .3rem;
            }

            input[type=email], input[type=text], textarea {
                background-color: #222;
                border: 1px solid #555;
                border-radius: 5px;
                color: var(--text-color);
                font-family: Verdana, Geneva, sans-serif;
                font-size: 1rem;
                padding: .6rem .8rem;
                resize: vertical;
                transition: border-color .2s ease;
            }
            input:-webkit-autofill,
            input:-webkit-autofill:hover, 
            input:-webkit-autofill:focus,
            input:-webkit-autofill:active {
                -webkit-box-shadow: 0 0 0 30px #222 inset !important;
                -webkit-text-fill-color: var(--text-color) !important;
                caret-color: var(--text-color) !important;
            }
            @media (pointer: coarse) {
                textarea::-webkit-resizer {
                    display: none;
                }
                textarea {
                    resize: none;
                }
            }
            input:focus, textarea:focus { border-color: var(--button-bg); outline: none; }

            .checkbox-button-group {
                align-items: center;
                color: var(--accent-color);
                cursor: pointer;
                display: flex;
                flex-direction: row;
                font-size: 1rem;
                font-weight: 600;
                gap: .2rem;
                justify-content: center;
                user-select: none;
            }

            .checkbox-button-group input[type=checkbox] {
                appearance: none;
                -webkit-appearance: none;
                background-color: transparent;
                border: 2px solid var(--accent-color);
                border-radius: 4px;
                cursor: pointer;
                height: 18px;
                position: relative;
                top: -3px;
                transition: background-color .3s, border-color .3s;
                width: 18px;
            }

            .checkbox-button-group input[type=checkbox]:checked { display: none; }

            #btnEnviar, .checkbox-button-group label { cursor: pointer; }

            #btnEnviar {
                background-color: var(--accent-color);
                border: none;
                border-radius: 6px;
                color: var(--button-text);
                font-size: 1.1rem;
                font-weight: 700;
                padding: .8rem 2.2rem;
                transition: background-color .3s ease;
                user-select: none;
            }

            #btnEnviar:disabled { background-color: #555; cursor: not-allowed; }
            #btnEnviar:not(:disabled):hover { background-color: #008e7c; }

            .progress-circle { display: block; margin: 1rem auto; }
            .progress-bg { opacity: .3; }

            #verification-status>div {
                align-items: center;
                color: var(--accent-color);
                display: flex;
                font-size: 1.1rem;
                font-weight: 600;
                gap: .6rem;
                justify-content: center;
                margin-top: .3rem;
            }

            .check-icon { font-size: 1.8rem; margin: 0; }

            body, html { overflow: hidden; }

            .typing-dots .dots:after {
                animation: dots 1.5s steps(3) infinite;
                content: "";
                display: inline-block;
                text-align: left;
                width: 1em;
            }

            @keyframes dots {
                0% { content: ""; }
                33% { content: "."; }
                66% { content: ".."; }
                to { content: "..."; }
            }

            .error { color: #f44336; display: none; font-size: 1rem; padding: 3px 2px 0; }
            .onerror .error { display: block; }
        </style>
    </head>
    <body>
        <p style="max-width:480px; margin: 1rem auto 2rem; color: #aaa; font-style: italic; text-align: center;">
            This demo is fully functional: <strong>you can send us a real message or inquiry using this form.</strong>
        </p>
        <form id="demo-form" action="dispatcher.php" novalidate target="">
            <div class="form-group">
                <label for="nombre">First Name</label>
                <input type="text" id="nombre" name="nombre" required autocomplete="given-name" />
                <div class="error">Please fill out this field.</div>
            </div>
            <div class="form-group">
                <label for="apellido">Last Name</label>
                <input type="text" id="apellido" name="apellido" required autocomplete="family-name" />
                <div class="error">Please fill out this field.</div>
            </div>
            <div class="form-group">
                <label for="email">Email</label>
                <input type="email" id="email" name="email" required autocomplete="email" />
                <div class="error">Please fill out this field.</div>
            </div>
            <div class="form-group">
                <label for="comentarios">Comments</label>
                <textarea id="comentarios" name="comentarios" rows="4" required></textarea>
                <div class="error">Please fill out this field.</div>
            </div>

            <div class="form-group checkbox-button-group">
                <input type="checkbox" id="soyHumano" name="soyHumano" aria-describedby="verification-status" />
                <label for="soyHumano">I am human</label>
            </div>

            <div id="verification-status" aria-live="polite" role="status"></div>
            <input type="hidden" name="captcha_token">
            <div class="form-group" style="text-align:center; margin-top: 2rem;">
                <button type="submit" id="btnEnviar" disabled>Send</button>
            </div>
        </form>

        <script type="module">
            import {initCaptcha} from '../BladeCAPTCHA/public/js/captcha.min.js?v=2';

            const checkbox = document.getElementById('soyHumano');
            checkbox.checked = false;
            const statusDiv = document.getElementById('verification-status');
            const btnEnviar = document.getElementById('btnEnviar');
            let timmer = null;
            let lastPercent = 0;
            let animFrame = null;

            function setProgress(percent) {
                if (percent === 0) return;

                const circle = document.querySelector('.progress-bar');
                if (!circle) return;

                const radius = 20;
                const circumference = 2 * Math.PI * radius;

                if (animFrame) cancelAnimationFrame(animFrame);
                
                // lerp
                function step() {
                    lastPercent += (percent - lastPercent) * 0.15; // suavizado

                    const offset = circumference - (lastPercent / 100) * circumference;
                    circle.style.strokeDashoffset = offset;

                    if (Math.abs(percent - lastPercent) > 0.5) {
                        animFrame = requestAnimationFrame(step);
                    } else {
                        lastPercent = percent;
                        circle.style.strokeDashoffset = circumference - (percent / 100) * circumference;
                    }
                }
                step();
            }

            function showProgress() {
                statusDiv.innerHTML = `
                    <svg class="progress-circle" width="48" height="48" viewBox="0 0 48 48" aria-hidden="true" role="img">
                        <circle class="progress-bg" cx="24" cy="24" r="20" stroke="#444" stroke-width="4" fill="none"></circle>
                        <circle class="progress-bar" cx="24" cy="24" r="20" stroke="var(--accent-color)" stroke-width="4" fill="none" stroke-linecap="round" stroke-dasharray="125.6" stroke-dashoffset="125.6" transform="rotate(-90 24 24)"></circle>
                    </svg>
                    <div>
                        <div class="typing-dots">Verifying<span class="dots"></span></div>
                    </div>
                `;
            }

            function showSuccess() {
                const messageSpace = window.matchMedia("(min-width: 412px)").matches;
                setTimeout(() => {
                    if (messageSpace) {
                        statusDiv.innerHTML = `
                            <div>
                                <div><span class="emoji">✅</span> You are indeed human <span class="emoji">😊</span></div>
                            </div>
                        `;
                    } else {
                        statusDiv.innerHTML = `
                            <div>
                                <div><span class="emoji">✅</span> You're human</div>
                            </div>
                        `;
                    }
                    btnEnviar.disabled = false;
                }, 50);// pequeño retraso para percibir la animación final
            }

            function start() {
                if (!checkbox.checked) {
                    statusDiv.innerHTML = '';
                    btnEnviar.disabled = true;
                    return;
                }
                lastPercent = 0;
                btnEnviar.disabled = true;
                showProgress();
                checkbox.closest('div').style.display = 'none';
            }

            function ok(token) {
                showProgress();
                setProgress(100);
                showSuccess();
                document.querySelector('[name="captcha_token"]').value = token;

                timmer = setTimeout(() => {
                    checkbox.closest('div').style.display = 'flex';
                    checkbox.checked = false;
                    const msg = `Your validation has <strong>expired</strong>, please press <em>'I am human'</em> again. <span class="emoji" style="white-space:nowrap">🤖 ⛔ 👨 💻</span>`;
                    window.parent.postMessage({ type: 'showErrorModal', html: msg }, window.location.origin);
                    btnEnviar.disabled = true;
                    statusDiv.innerHTML = '';
                }, 55000);
            }
            
            function ko(err) {
                clearTimeout(timmer);
                setProgress(100); // opcional: mostrar el progreso completo antes de fallar
                setTimeout(() => {
                    const msg = `Hmm… Did you ever doubt your own <strong>humanity</strong>? <span class="emoji" style="white-space:nowrap">👀 🌍</span><br>
                        <strong>No worries!</strong> Just click <em>'I am human'</em> again… We’ll make sure everything’s fine 
                        (and you can sleep peacefully without existential questions at 3 AM). <span class="emoji" style="white-space:nowrap">🤖 ❔ 👶</span>`;
                    window.parent.postMessage({ type: 'showErrorModal', html: msg }, window.location.origin);
                    statusDiv.innerHTML = '';
                    checkbox.closest('div').style.display = 'flex';
                    checkbox.checked = false;
                    btnEnviar.disabled = true;
                }, 100); // pequeño retraso para percibir la animación
            }

            function addErrorHandlers(input, parent) {
                parent.classList.add('onerror');
                input.focus();
                input.addEventListener('input', function removeError() {
                    parent.classList.remove('onerror');
                    input.removeEventListener('input', removeError);
                });
            }

            function isValidEmail(email) {
                const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
                return re.test(email);
            }

            function showLoading() { window.parent.postMessage({ type: 'showLoading' }, window.location.origin); }
            function hideLoading() { window.parent.postMessage({ type: 'hideLoading' }, window.location.origin); }

            async function externalFetchWithErrorHandling(url, options = {}) {
                const response = await fetch(url, options);
                if (!response.ok) {
                    let errorData;
                    try { errorData = await response.json(); } 
                    catch { errorData = { message: await response.text().catch(() => '') || `HTTP ${response.status}` }; }
                    throw new Error(errorData.message || `HTTP ${response.status}`);
                }
                const contentType = response.headers.get('content-type') || '';
                return contentType.includes('application/json') ? await response.json() : await response.text();
            }

            document.getElementById('demo-form').addEventListener('submit', async e => {
                e.preventDefault();
                try {
                    let nombre, apellido, email, comentarios, captcha_token, proceso;
                    let input = document.querySelector('[name="nombre"]');
                    let parent = input.closest('div');
                    if (input.value.length < 2) { addErrorHandlers(input, parent); return; }
                    nombre = input.value;

                    input = document.querySelector('[name="apellido"]');
                    parent = input.closest('div');
                    if (input.value.length < 2) { addErrorHandlers(input, parent); return; }
                    apellido = input.value;

                    input = document.querySelector('[name="email"]');
                    parent = input.closest('div');
                    if (!isValidEmail(input.value)) { addErrorHandlers(input, parent); return; }
                    email = input.value;

                    input = document.querySelector('[name="comentarios"]');
                    parent = input.closest('div');
                    if (input.value.length < 2) { addErrorHandlers(input, parent); return; }
                    comentarios = input.value;

                    const captchaInput = document.querySelector('[name="captcha_token"]');
                    if (!captchaInput) throw new Error('CAPTCHA token not found in form');
                    captcha_token = captchaInput.value;
                    proceso = 'contact';

                    clearTimeout(timmer);
                    btnEnviar.disabled = true;
                    btnEnviar.innerHTML = `<div class="typing-dots">Sending<span class="dots"></span></div>`;
                    showLoading();

                    let response = await externalFetchWithErrorHandling(
                        '../BladeCAPTCHA/public/php/dispatcher_en.php', {
                            method: 'POST',
                            headers: { 'Accept': 'application/json' },
                            body: JSON.stringify({ proceso, nombre, apellido, email, comentarios, captcha_token })
                        }
                    );

                    btnEnviar.innerHTML = 'Send';
                    hideLoading();
                    statusDiv.innerHTML = '';
                    checkbox.closest('div').style.display = 'flex';
                    checkbox.checked = false;
                    btnEnviar.disabled = true;

                    const msg = response.message;
                    const myOrigin = window.location.origin;
                    window.parent.postMessage({
                        type: response.success ? 'showSuccessModal' : 'showErrorModal',
                        html: msg
                    }, myOrigin);

                    if(response.success) e.target.reset();

                } catch (err) {
                    btnEnviar.innerHTML = 'Send';
                    statusDiv.innerHTML = '';
                    checkbox.closest('div').style.display = 'flex';
                    checkbox.checked = false;
                    btnEnviar.disabled = true;
                    hideLoading();
                    const msg = err.message || err;
                    window.parent.postMessage({ type: 'showErrorModal', html: msg }, window.location.origin);
                }
            });

            (async () => {
                try {
                    await initCaptcha({
                        mode: 'manualHandling',
                        apiBaseUrl: '../BladeCAPTCHA/public/php',
                        verifyButtonSelector: '#soyHumano',
                        onStart: start,
                        onProgress: setProgress,
                        onSuccess: ok,
                        onError: ko
                    });
                } catch (err) { console.error(err || err.message); }
            })();
        </script>
        
        <script>
            function sendHeight() {
                const bodyRect = document.body.getBoundingClientRect();
                const htmlRect = document.documentElement.getBoundingClientRect();
                const height = Math.max(bodyRect.height, htmlRect.height);
                const myOrigin = window.location.origin;
                window.parent.postMessage({ type: 'iframe-height', height }, myOrigin);
            }
            window.addEventListener('load', sendHeight);
            new MutationObserver(sendHeight).observe(document.body, { childList: true, subtree: true, attributes: true, characterData: true });
            window.addEventListener('resize', sendHeight);
        </script>
    </body>
</html>