/**
 * Brama PIN-u. Na starcie strony zbiera cztery cyfry z klawiatury ekranowej
 * i składa z nich adresy backendu.
 *
 * Kod nie zna PIN-u i go nie sprawdza: serwer wystawia endpointy tylko pod
 * ścieżką z prawidłowym PIN-em, więc bez niego nie ma z czym rozmawiać. Zły PIN
 * poznajemy po tym, że gniazdo GUI się nie otwiera.
 *
 *   window.pinGate.unlock()  -> Promise<{ pin, uploadUrl, socketUrl }>
 *   window.pinGate.forget()  -> zapomina PIN (kolejny unlock znów pyta)
 */
(() => {
    const API_BASE = 'https://mcpforum.pl';
    const SOCKET_BASE = 'wss://mcpforum.pl';
    const PIN_LENGTH = 4;
    const STORAGE_KEY = 'accessPin';   // sessionStorage: przeżywa odświeżenie, ginie z kartą

    // PIN jest kolejnym segmentem ścieżki, więc reguły ProxyPass w Apache
    // (prefiksy /backendSrv02 i /gui-socket) dopasowują się bez zmian.
    const endpointsFor = (pin) => ({
        pin,
        uploadUrl: `${API_BASE}/backendSrv02/${pin}`,
        socketUrl: `${SOCKET_BASE}/gui-socket/${pin}`,
    });

    const remembered = () => {
        try {
            const pin = sessionStorage.getItem(STORAGE_KEY);
            return /^\d{4}$/.test(pin ?? '') ? pin : null;
        } catch (e) {
            return null;   // prywatny tryb bez sessionStorage — po prostu pytamy
        }
    };

    const remember = (pin) => {
        try { sessionStorage.setItem(STORAGE_KEY, pin); } catch (e) {}
    };

    function forget() {
        try { sessionStorage.removeItem(STORAGE_KEY); } catch (e) {}
    }

    // Klawiatura zasłania całą stronę, więc do przycisku nagrywania nie da się
    // dosięgnąć przed podaniem PIN-u.
    function buildKeypad(onDigit, onBackspace) {
        const overlay = document.createElement('div');
        overlay.className = 'pin-gate';
        overlay.innerHTML = `
            <p class="pin-gate-title">🔒 PIN</p>
            <div class="pin-gate-dots" id="pinDots"></div>
            <p class="pin-gate-message" id="pinMessage"></p>
            <div class="pin-gate-keys" id="pinKeys"></div>
        `;

        const keys = overlay.querySelector('#pinKeys');
        for (const label of ['1', '2', '3', '4', '5', '6', '7', '8', '9', '⌫', '0']) {
            const key = document.createElement('button');
            key.type = 'button';
            key.className = 'pin-gate-key';
            key.textContent = label;
            key.addEventListener('click', () => {
                if (label === '⌫') onBackspace();
                else onDigit(label);
            });
            keys.appendChild(key);
        }

        document.body.appendChild(overlay);
        return {
            overlay,
            dots: overlay.querySelector('#pinDots'),
            message: overlay.querySelector('#pinMessage'),
        };
    }

    let pendingMessage = '';   // komunikat pokazywany przy następnym pytaniu o PIN

    function unlock() {
        const stored = remembered();
        if (stored) {
            return Promise.resolve(endpointsFor(stored));
        }

        return new Promise((resolve) => {
            const digits = [];

            const render = () => {
                view.dots.textContent = '•'.repeat(digits.length) + '◦'.repeat(PIN_LENGTH - digits.length);
            };

            const view = buildKeypad(
                (digit) => {
                    if (digits.length >= PIN_LENGTH) return;
                    digits.push(digit);
                    render();

                    if (digits.length === PIN_LENGTH) {
                        const pin = digits.join('');
                        remember(pin);
                        view.overlay.remove();
                        resolve(endpointsFor(pin));
                    }
                },
                () => {
                    digits.pop();
                    render();
                }
            );

            view.message.textContent = pendingMessage;
            pendingMessage = '';
            render();
        });
    }

    // Zły PIN znaczy nieistniejący adres — pytamy jeszcze raz, z wyjaśnieniem.
    function reject(message = 'Zły PIN — spróbuj jeszcze raz.') {
        forget();
        pendingMessage = message;
    }

    window.pinGate = { unlock, forget, reject };
})();
