<?php
/**
 * @author Amasty Team
 * @copyright Copyright (c) Amasty (https://www.amasty.com)
 * @package Google Invisible reCaptcha for Magento 2
 */
/**
 * @var $block Magento\Framework\View\Element\Template
 * @var $viewModel Amasty\InvisibleCaptcha\ViewModel\Captcha
 * @var $escaper Magento\Framework\Escaper
 */

$viewModel = $block->getViewModel();
?>

<?php if ($viewModel->isNeedToShowCaptcha()): ?>
    <script type="text/x-magento-init">
        {
            "*": {
                "Amasty_InvisibleCaptcha/js/action/am-recaptcha-configure": {
                    "formsToProtect": "<?= $escaper->escapeJs(implode(',', $viewModel->getAllFormSelectors())) ?>",
                    "isEnabledOnPayments": "<?= $escaper->escapeJs($viewModel->isCaptchaOnPayments()) ?>",
                    "checkoutRecaptchaValidateUrl": "<?= $escaper->escapeHtml($viewModel->getCheckoutValidateCaptchaUrl()) ?>",
                    "invisibleCaptchaCustomForm": "<?= $escaper->escapeHtml($viewModel->getInvisibleCaptchaCustomForm()) ?>",
                    "recaptchaConfig": {
                        "lang": "<?= $escaper->escapeJs($viewModel->getLanguage()) ?>",
                        "theme": "<?= $escaper->escapeHtml($viewModel->getBadgeTheme()) ?>",
                        "badge": "<?= $escaper->escapeHtml($viewModel->getBadgePosition()) ?>",
                        "sitekey": "<?= $escaper->escapeHtml($viewModel->getSiteKey()) ?>",
                        "size": "<?= $escaper->escapeHtml($viewModel->getSize()) ?>",
                        "isInvisible": <?= $viewModel->isInvisibleCaptcha() ? 'true' : 'false' ?>,
                        "recaptchaVersion": <?= $escaper->escapeHtml($viewModel->getCaptchaVersion()) ?>
                    },
                    "reCaptchaErrorMessage": "<?= $escaper->escapeHtml(__('Prove you are not a robot')) ?>"
                 }
            }
        }
    </script>

    <?php if ($block->getRequest()->getFullActionName() !== 'checkout_index_index'): ?>
        <script>
            // Fix to prevent 'no reCaptcha Token' error while slow site loading.
            // Submit button should catch am-captcha.js initialization8 first
            (function () {
                if (document.readyState === 'loading') {
                    document.addEventListener('DOMContentLoaded', onReadyStateListener);
                } else {
                    onReadyState();
                }

                function onReadyStateListener() {
                    onReadyState();
                }

                function onReadyState (formsOnPage) {
                    if (typeof formsOnPage === 'undefined') {
                        let formsToProtect = "<?= $escaper->escapeJs(implode(',', $viewModel->getAllFormSelectors())) ?>";
                        let forms = formsToProtect.split(',');

                        formsOnPage = [];
                        forms.forEach(form => {
                            let existingForm = form ? document.querySelectorAll(form) : [];

                            if (existingForm.length) {
                                formsOnPage.push(existingForm);
                            }
                        })
                    }

                    formsOnPage.forEach(form => {
                        let submit = form[0].querySelector('[type="submit"]');
                        if (submit) {
                            let isAlreadyDisabled = submit.getAttribute('disabled');

                            if (!isAlreadyDisabled) {
                                submit.setAttribute('disabled', true);
                                submit.setAttribute('am-captcha-protect', true);

                                // Fallback: if Amasty's own JS (am-recaptcha.js) doesn't
                                // initialize in time (slow page, JS contention), this
                                // button would otherwise stay disabled forever. After a
                                // grace period, if it is still stuck, take over and run a
                                // minimal recaptcha render/execute ourselves so a real
                                // token still gets generated (instead of just unlocking
                                // the button and letting a token-less submit fail).
                                setTimeout(function () {
                                    if (submit.getAttribute('am-captcha-protect') !== 'true'
                                        || !submit.hasAttribute('disabled')
                                    ) {
                                        return;
                                    }

                                    submit.removeAttribute('disabled');

                                    require([
                                        'Amasty_InvisibleCaptcha/js/model/am-recaptcha',
                                        'Amasty_InvisibleCaptcha/js/action/am-recaptcha-loader'
                                    ], function (amReCaptchaModel, amReCaptchaLoader) {
                                        var form = submit.closest('form');

                                        function bindAndRender() {
                                            var container = document.createElement('div');
                                            form.appendChild(container);

                                            var widgetId = window.grecaptcha.render(container, Object.assign(
                                                {},
                                                amReCaptchaModel.getRecaptchaConfig(),
                                                {
                                                    callback: function (token) {
                                                        var input = document.createElement('input');
                                                        input.type = 'hidden';
                                                        input.name = 'g-recaptcha-response';
                                                        input.value = token;
                                                        form.appendChild(input);
                                                        form.submit();
                                                    },
                                                    'error-callback': function () {
                                                        submit.removeAttribute('disabled');
                                                    }
                                                }
                                            ));

                                            submit.addEventListener('click', function (e) {
                                                e.preventDefault();
                                                e.stopImmediatePropagation();
                                                submit.setAttribute('disabled', true);
                                                window.grecaptcha.execute(widgetId);
                                            });
                                        }

                                        if (typeof window.grecaptcha !== 'undefined' && window.grecaptcha.render) {
                                            bindAndRender();
                                            return;
                                        }

                                        // Amasty's own component never loaded the API (it only
                                        // does so lazily, on the first submit, from code that
                                        // never ran). Load it ourselves, reusing Amasty's own
                                        // loader/callback so we don't duplicate the script URL.
                                        // If it never fires, the button stays a plain submit
                                        // button - the server's own captcha validation message
                                        // handles that case, no need to intercept it here.
                                        window[amReCaptchaModel.onLoadCallback] = function () {
                                            amReCaptchaModel.isScriptLoaded = true;
                                            bindAndRender();
                                        };

                                        amReCaptchaLoader.addReCaptchaScript();
                                    });
                                }, 4000);
                            }
                        }
                    })
                }

                <?php if ($viewModel->getInvisibleCaptchaCustomForm()): ?>
                window.addEventListener('amform-elements-rendered', function (event) {
                    onReadyState([event.detail.form]);
                });
                window.addEventListener('am-recaptcha-submit-event', function (event) {
                    onReadyState([event.detail.form]);
                });
                <?php endif; ?>
            })();
        </script>
    <?php endif; ?>
<?php endif; ?>
