/* File Path: assets/js/mbs-arc-signup.js
 *
 * ARC Reviewer Self-Signup Form -- Front-End Handler
 *
 * Handles: client-side validation, CAPTCHA token acquisition (reCAPTCHA v3,
 * hCaptcha, Turnstile), fetch() POST to /wp-json/mbs/v1/arc/apply, and
 * success / error display.
 *
 * Per-form configuration is provided by the server as:
 *   window.MbsArcSignupData[postId] = {
 *       postId, successMessage, captchaProvider, captchaSiteKey,
 *       restBase, restNonce
 *   };
 *
 * Sprint F-027: ARC Signup Block.
 *
 * @package My_Book_Showroom
 * @since   1.2.0
 */
( function () {
    'use strict';
    var __ = wp.i18n.__;

    /** Widget IDs returned by hCaptcha / Turnstile render() calls. */
    var captchaWidgets = {};

    // -------------------------------------------------------------------------
    // Boot
    // -------------------------------------------------------------------------

    if ( 'loading' === document.readyState ) {
        document.addEventListener( 'DOMContentLoaded', init );
    } else {
        init();
    }

    /** Re-init hook for dynamically-loaded content. */
    window.MbsArcSignup = { init: init };

    // -------------------------------------------------------------------------
    // Initialization
    // -------------------------------------------------------------------------

    function init() {
        document.querySelectorAll( '.mbs-arc-signup' ).forEach( function ( wrapper ) {
            var postId = parseInt( wrapper.getAttribute( 'data-post-id' ), 10 );
            if ( ! postId ) { return; }

            var data = ( window.MbsArcSignupData || {} )[ postId ];
            if ( ! data ) { return; }

            initCaptchaWidget( postId, data );
            initForm( wrapper, postId, data );
        } );
    }

    /**
     * Render inline CAPTCHA widget where the provider places a visible widget.
     * reCAPTCHA v3 is invisible -- no widget rendered here; token fetched on submit.
     */
    function initCaptchaWidget( postId, data ) {
        var provider    = data.captchaProvider;
        var siteKey     = data.captchaSiteKey;
        var containerId = 'mbs-arc-' + postId + '-captcha';

        if ( 'hcaptcha' === provider && siteKey && window.hcaptcha ) {
            captchaWidgets[ postId ] = window.hcaptcha.render( containerId, {
                sitekey: siteKey,
            } );
        } else if ( 'turnstile' === provider && siteKey && window.turnstile ) {
            captchaWidgets[ postId ] = window.turnstile.render( '#' + containerId, {
                sitekey: siteKey,
            } );
        }
    }

    function initForm( wrapper, postId, data ) {
        var form = wrapper.querySelector( '.mbs-arc-signup__form' );
        if ( ! form ) { return; }

        form.addEventListener( 'submit', function ( e ) {
            e.preventDefault();
            handleSubmit( form, postId, data );
        } );
    }

    // -------------------------------------------------------------------------
    // Submit handler
    // -------------------------------------------------------------------------

    function handleSubmit( form, postId, data ) {
        var btn      = form.querySelector( '.mbs-arc-signup__submit' );
        var resultEl = form.querySelector( '.mbs-arc-signup__result' );

        clearResult( resultEl );

        // Honeypot: filled by bots -- silently show success without sending.
        var hp = form.querySelector( '[name="mbs_hp"]' );
        if ( hp && hp.value !== '' ) {
            showSuccess( form, resultEl, data.successMessage );
            return;
        }

        // Browser-native validation (required fields, email format).
        if ( ! form.checkValidity() ) {
            form.reportValidity();
            return;
        }

        var name    = fieldVal( form, '[name="mbs_arc_name"]' );
        var email   = fieldVal( form, '[name="mbs_arc_email"]' );
        var message = fieldVal( form, '[name="mbs_arc_message"]' );
        var nonce   = fieldVal( form, '[name="mbs_arc_nonce"]' );

        if ( btn ) { btn.disabled = true; }

        getCaptchaToken( postId, data )
            .then( function ( token ) {
                return fetch( data.restBase, {
                    method:  'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-WP-Nonce':   data.restNonce,
                    },
                    body: JSON.stringify( {
                        post_id:       postId,
                        name:          name,
                        email:         email,
                        message:       message,
                        nonce:         nonce,
                        captcha_token: token,
                    } ),
                } );
            } )
            .then( function ( response ) {
                return response.json().then( function ( json ) {
                    return { ok: response.ok, json: json };
                } );
            } )
            .then( function ( result ) {
                if ( result.ok && result.json && result.json.success ) {
                    showSuccess( form, resultEl, data.successMessage );
                } else {
                    var msg = ( result.json && result.json.message )
                        || __( 'Something went wrong. Please try again.', 'my-book-showroom' );
                    showError( resultEl, msg );
                    if ( btn ) { btn.disabled = false; }
                    resetCaptcha( postId, data );
                }
            } )
            .catch( function () {
                showError( resultEl, __( 'Something went wrong. Please try again.', 'my-book-showroom' ) );
                if ( btn ) { btn.disabled = false; }
                resetCaptcha( postId, data );
            } );
    }

    // -------------------------------------------------------------------------
    // CAPTCHA helpers
    // -------------------------------------------------------------------------

    /**
     * Returns a Promise that resolves with the CAPTCHA token string.
     * Resolves with '' when no CAPTCHA is configured.
     */
    function getCaptchaToken( postId, data ) {
        var provider = data.captchaProvider;
        var siteKey  = data.captchaSiteKey;

        if ( 'recaptcha_v3' === provider && siteKey && window.grecaptcha ) {
            return window.grecaptcha.execute( siteKey, { action: 'mbs_arc_apply' } );
        }

        if ( 'hcaptcha' === provider && window.hcaptcha &&
                captchaWidgets[ postId ] !== undefined ) {
            return Promise.resolve(
                window.hcaptcha.getResponse( captchaWidgets[ postId ] )
            );
        }

        if ( 'turnstile' === provider && window.turnstile ) {
            return Promise.resolve( window.turnstile.getResponse() );
        }

        return Promise.resolve( '' );
    }

    /** Reset visible CAPTCHA widget after a failed submission so user can retry. */
    function resetCaptcha( postId, data ) {
        var provider = data.captchaProvider;

        if ( 'hcaptcha' === provider && window.hcaptcha &&
                captchaWidgets[ postId ] !== undefined ) {
            window.hcaptcha.reset( captchaWidgets[ postId ] );
        } else if ( 'turnstile' === provider && window.turnstile ) {
            window.turnstile.reset();
        }
    }

    // -------------------------------------------------------------------------
    // UI helpers
    // -------------------------------------------------------------------------

    function showSuccess( form, resultEl, message ) {
        form.classList.add( 'is-submitted' );
        resultEl.textContent = message;
        resultEl.classList.remove( 'mbs-arc-signup__result--error' );
        resultEl.classList.add( 'mbs-arc-signup__result--success' );
        resultEl.style.display = 'block';
    }

    function showError( resultEl, message ) {
        resultEl.textContent = message;
        resultEl.classList.remove( 'mbs-arc-signup__result--success' );
        resultEl.classList.add( 'mbs-arc-signup__result--error' );
        resultEl.style.display = 'block';
    }

    function clearResult( resultEl ) {
        if ( ! resultEl ) { return; }
        resultEl.textContent = '';
        resultEl.style.display = 'none';
        resultEl.classList.remove(
            'mbs-arc-signup__result--success',
            'mbs-arc-signup__result--error'
        );
    }

    function fieldVal( form, selector ) {
        var el = form.querySelector( selector );
        return el ? el.value : '';
    }

} )();
