<?php
/**
 * Hyvä Themes - https://hyva.io
 * Copyright © Hyvä Themes. All rights reserved.
 * See COPYING.txt for license details.
 */

declare(strict_types=1);

use Hyva\Theme\Model\ViewModelRegistry;
use Hyva\Theme\ViewModel\DeployMode;
use Magento\Framework\Escaper;
use Magento\Framework\View\Element\Template;

// phpcs:disable Generic.Files.LineLength.TooLong

/** @var Template $block */
/** @var Escaper $escaper */
/** @var ViewModelRegistry $viewModels */
?>

<script>
    'use strict';
    (() => {
        function _calculateStrength({elementID, valid}) {
            const password = document.getElementById(elementID),
                emailElm = document.getElementById('email_address');
            let displayScore;
            // Display score is based on combination of whether password is empty, valid, and zxcvbn strength
            if (!password || !password.value) {
                displayScore = 0;
            } else {
                // We should only perform this check in case there is an email field on screen
                if (emailElm && password.value && emailElm.value &&
                    password.value.toLowerCase() === emailElm.value.toLowerCase()) {
                    displayScore = 1;
                } else {
                    const zxcvbnScore = zxcvbn(password.value).score;
                    displayScore = valid && zxcvbnScore > 0 ? zxcvbnScore : 1;
                }
            }

            _displayStrength(displayScore);
        }

        function _displayStrength(displayScore) {
            let strengthLabel = '',
                className;

            switch (displayScore) {
                case 0:
                    strengthLabel = "<?= $escaper->escapeJs(__('No Password')) ?>";
                    className = 'password-none';
                    break;

                case 1:
                    strengthLabel = "<?= $escaper->escapeJs(__('Weak')) ?>";
                    className = 'password-weak';
                    break;

                case 2:
                    strengthLabel = "<?= $escaper->escapeJs(__('Medium')) ?>";
                    className = 'password-medium';
                    break;

                case 3:
                    strengthLabel = "<?= $escaper->escapeJs(__('Strong')) ?>";
                    className = 'password-strong';
                    break;

                case 4:
                    strengthLabel = "<?= $escaper->escapeJs(__('Very Strong')) ?>";
                    className = 'password-very-strong';
                    break;
            }
            const meterElm = document.getElementById('password-strength-meter-container'),
                meterLabelElm = document.getElementById('password-strength-meter-label');
            meterElm.className = '';
            meterElm.classList.add(className);
            meterLabelElm.textContent = strengthLabel;
        }

        let loading = false;
        const callbacks = [];

        function loadZxcvbn(cb) {
            callbacks.push(cb);
            if (loading) return;
            loading = true;

            const script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = '<?= $escaper->escapeJs($block->getViewFileUrl('js/zxcvbn.js')) ?>';
            script.async = true;
            script.onload = () => callbacks.forEach(cb => cb());
            document.head.appendChild(script);
        }

        window.addEventListener('password-validate', function (evt) {
            const meterElm = document.getElementById('password-strength-meter-container'),
                meterLabelElm = document.getElementById('password-strength-meter-label');
            if (meterElm && meterLabelElm) {
                if (evt.detail && evt.detail.elementID) {
                    const cb = () => _calculateStrength(evt.detail);
                    window.zxcvbn ? cb() : loadZxcvbn(cb)
                }
            }
        });


        document.addEventListener('DOMContentLoaded', () => {
            hyva && hyva.formValidation && hyva.formValidation.addRule('password-strength', function(value, options, field, context) {
                let counter = 0;
                const minCharacterSets = options.minCharacterSets !== undefined ?  options.minCharacterSets : 1;
                if (value.match(/\d+/)) {
                    counter++;
                }

                if (value.match(/[a-z]+/)) {
                    counter++;
                }

                if (value.match(/[A-Z]+/)) {
                    counter++;
                }

                if (value.match(/[^a-zA-Z0-9]+/)) {
                    counter++;
                }

                queueMicrotask(() => {
                    window.dispatchEvent(new CustomEvent('password-validate', { detail: {
                            elementID: field.element.id || 'password',
                            valid: field.state.valid
                        }}));
                });

                if (counter < minCharacterSets) {
                    const missing = minCharacterSets - counter;
                    return hyva.str('<?= $escaper->escapeJs(__('The password must include at least %1 or more of: uppercase (A-Z), lowercase (a-z), number and symbol.')) ?>', missing);
                }
                return true;
            });
        })
    })();

</script>
