/*!
 * Crafted with ❤ by Salla
 */
'use strict';

var index = require('./index-vstkdqRz.js');
var mail = require('./mail-Bgvt2hc9.js');

var AndroidPhoneIcon = `<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>android-phone</title>
<path d="M22.667 0h-13.333c-2.941 0-5.333 2.392-5.333 5.333v21.333c0 2.941 2.392 5.333 5.333 5.333h13.333c2.941 0 5.333-2.392 5.333-5.333v-21.333c0-2.941-2.392-5.333-5.333-5.333zM25.333 26.667c0 1.471-1.196 2.667-2.667 2.667h-13.333c-1.471 0-2.667-1.196-2.667-2.667v-2.667h18.667zM25.333 21.333h-18.667v-16c0-1.471 1.196-2.667 2.667-2.667h13.333c1.471 0 2.667 1.196 2.667 2.667zM13.333 28h5.333c0.736 0 1.333-0.597 1.333-1.333s-0.597-1.333-1.333-1.333h-5.333c-0.736 0-1.333 0.597-1.333 1.333s0.597 1.333 1.333 1.333z"></path>
</svg>
`;

const sallaVerifyCss = "salla-verify{display:block}.s-verify-input{}.s-verify-input::-webkit-outer-spin-button,.s-verify-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.s-verify-input[type=number]{-moz-appearance:textfield}";

const SallaVerify = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        this.verified = index.createEvent(this, "verified");
        this.translationLoaded = false;
        /**
         * Should render component without modal
         */
        this.display = 'modal';
        /**
         * Verifying method
         */
        this.type = 'mobile';
        /**
         * should auto reloading the page after success verification
         */
        this.autoReload = true;
        /**
         * Once the api verify success, it will be login the customer in web pages
         */
        this.supportWebAuth = true;
        this.resendAfter = 30;
        /**
         * to use: `salla.api.auth.verify` or `salla.profile.verify`
         */
        this.isProfileVerify = false;
        salla.lang.onLoaded(() => {
            this.translationLoaded = true;
            this.title = salla.lang.get('pages.profile.verify_title') + salla.lang.get('common.elements.' + this.type);
            this.modal?.setTitle(this.title);
        });
        if (this.display == 'inline') {
            this.modal = { open: () => '', close: () => '', setTitle: () => '' };
            return;
        }
        //todo:: change this way, now we fire the event from the backend, we should listen to salla.profile.event.onUpdated
        salla.event.on('profile::verification', data => {
            let payload = Array.isArray(data) ? data[0] : data;
            this.isProfileVerify = true;
            this.open(payload);
            this.title = salla.lang.get('pages.profile.verify_title') + salla.lang.get('common.elements.' + payload.type);
            this.modal?.setTitle(this.title);
        });
        salla.event.on('modalClosed', () => {
            this.resendAfter = 0;
            this.timer.innerHTML = '30 : 00';
        });
    }
    splitNumber(e) {
        this.resetError();
        let data = e.data || e.target.value; // Chrome doesn't get the e.data, it's always empty, fallback to value then.
        if (!data)
            return; // Shouldn't happen, just in case.
        if (data.length === 1)
            return; // Here is a normal behavior, not a paste action.
        this.modifyNext(e.target, data);
    }
    modifyNext(el, data) {
        el.value = data[0]; // Apply first item to first input
        data = data.substring(1); // remove the first char.
        if (el.nextElementSibling && data.length) {
            // Do the same with the next element and next data
            this.modifyNext(el.nextElementSibling, data);
        }
        else if (!el.nextElementSibling && data.length === 0) {
            el.focus();
        }
        else if (el.nextElementSibling && data.length === 0) {
            el.nextElementSibling.focus();
        }
    }
    checkAllInputs() {
        let allFilled = true;
        for (let i = 0; i < this.otpInputs.length; i++) {
            if (this.otpInputs[i].value === '') {
                allFilled = false;
            }
        }
        return allFilled;
    }
    handleKeyUp(ev) {
        this.resetError();
        if (['Alt', 'Shift', 'Control', 'AltGraph', 'Ctrl'].includes(ev.key)) {
            return;
        }
        let key = ev.keyCode || ev.charCode;
        if (ev.target.value) {
            ev.target.nextElementSibling?.focus();
            ev.target.nextElementSibling?.select();
        }
        else if ([8, 46].includes(key)) {
            ev.target.previousElementSibling?.focus();
            ev.target.previousElementSibling?.select();
        }
        // If the target is populated to quickly, value length can be > 1
        if (ev.target.value.length > 1) {
            this.splitNumber(ev);
        }
    }
    handlePaste(ev) {
        this.resetError();
        const clipboardText = salla.helpers.number(ev.clipboardData.getData('text')) || '';
        let text = clipboardText.replace(/[^0-9]/g, '');
        text = text.substring(0, this.otpInputs.length);
        this.otpInputs.forEach(input => input.value = '');
        this.modifyNext(this.otpInputs[0], text);
    }
    handleInput(ev) {
        this.resetError();
        salla.helpers.inputDigitsOnly(ev.target);
        // check if all otpInputs has values then send the request
        if (this.checkAllInputs()) {
            setTimeout(() => {
                this.toggleOTPSubmit();
            }, 100);
        }
    }
    resetError() {
        this.hasError = false;
        this.errorMessage = '';
    }
    handleFocus(ev) {
        // If the focus element is the first one, do nothing
        if (ev.target === this.firstOtpInput)
            return;
        // If value of input 1 is empty, focus it.
        if (this.firstOtpInput?.value == '') {
            this.firstOtpInput.focus();
        }
        // If value of a previous input is empty, focus it.
        // To remove if you don't wanna force user respecting the fields order.
        if (ev.target.previousElementSibling.value == '') {
            ev.target.previousElementSibling.focus();
        }
    }
    /**
     * Get current code
     * @return {string}
     */
    async getCode() {
        return this.code.value;
    }
    /**
     * Open verifying modal
     * @param data
     */
    async open(data) {
        this.data = data;
        this.data.type = this.data.type || this.type;
        this.type = this.data.type;
        this.resendTimer();
        this.otpInputs = this.body.querySelectorAll('.s-verify-input');
        this.firstOtpInput = this.body.querySelector('#otp-1');
        this.reset();
        this.resetError();
        this.display == 'modal' && this.modal?.setTitle(this.title);
        this.modal.open();
        this.firstOtpInput?.addEventListener('input', e => this.splitNumber(e));
        // focus the first input after opening the modal
        setTimeout(() => this.otpInputs[0].focus(), 100);
    }
    toggleOTPSubmit() {
        let otp = [];
        this.otpInputs.forEach(input => input.value && otp.push(input.value));
        this.code.value = otp.join('');
        if (otp.length === 4) {
            this.btn.disable();
            this.btn.click();
            return;
        }
        this.btn.enable();
    }
    reset() {
        this.otpInputs.forEach((input) => input.value = '');
        this.code.value = '';
        this.otpInputs[0].focus();
    }
    resendTimer() {
        this.resendMessage.style.display = 'block';
        this.resend.style.display = 'none';
        this.resendAfter = 30;
        let timerId = setInterval(() => {
            if (this.resendAfter <= 0) {
                clearInterval(timerId);
                this.resend.style.display = 'block';
                this.resendMessage.style.display = 'none';
            }
            else {
                this.timer.innerHTML = `${this.resendAfter >= 10 ? this.resendAfter : '0' + this.resendAfter} : 00`;
                this.resendAfter--;
            }
        }, 1000);
    }
    resendCode() {
        return this.btn.stop()
            .then(() => this.btn.disable())
            .then(() => {
            this.otpInputs.forEach(input => input.value = '');
            this.otpInputs[0].focus();
        })
            .then(() => salla.api.auth.resend(this.data))
            .finally(() => this.resendTimer());
    }
    submit() {
        //if code not 4 digits, focus on the after filled input,
        if (this.code.value.length < 4) {
            this.otpInputs[this.code.value.length].focus();
            salla.log('Trying to submit without 4 digits!');
            return;
        }
        let data = { code: this.code.value, ...this.data };
        return this.btn.load()
            .then(() => this.btn.disable())
            .then(() => this.isProfileVerify ? salla.profile.verify(data) : salla.auth.verify(data, this.supportWebAuth))
            .then(response => this.verified.emit(response))
            .then(() => this.btn.stop() && this.btn.disable())
            .then(() => this.modal.close())
            .then(() => this.autoReload && window.location.reload())
            .catch((error) => {
            this.hasError = true;
            this.errorMessage = error.response?.data?.error?.message || salla.lang.get('common.errors.error_occurred');
            if (!error.response) {
                console.log('Unexpected error', error);
            }
            else {
                salla.logger.error(error);
            }
            this.btn.stop() && this.btn.enable() && this.reset();
        });
    }
    render() {
        return this.display == 'inline' ? index.h(index.Host, null, this.myBody()) :
            index.h("salla-modal", { width: "xs", class: "s-verify", ref: modal => this.modal = modal, "modal-title": this.title }, index.h("span", { slot: 'icon', class: "s-verify-header-icon", innerHTML: this.type == "mobile" ? AndroidPhoneIcon : mail.SIMail }), this.myBody());
    }
    myBody() {
        return (index.h("div", { class: "s-verify-body", ref: body => this.body = body }, index.h("div", { class: "s-verify-message", innerHTML: salla.lang.get('pages.profile.verify_message') }), index.h("slot", { name: "mobile" }), index.h("slot", { name: "email" }), index.h("input", { type: "hidden", name: "code", maxlength: "4", required: true, ref: code => this.code = code }), index.h("div", { class: { "s-verify-codes": true, "has-error": this.hasError }, dir: "ltr" }, [1, 2, 3, 4].map((i) => index.h("input", { type: "number", autocomplete: "one-time-code", pattern: "[0-9]*", inputmode: "numeric", maxlength: "1", value: "", id: `otp-${i}`, class: { "s-verify-input": true, "s-has-error": this.hasError }, onInput: e => this.handleInput(e), onPaste: e => this.handlePaste(e), onKeyUp: e => this.handleKeyUp(e), onFocus: e => this.handleFocus(e), required: true }))), this.hasError && this.errorMessage ? index.h("span", { class: "s-verify-error-message" }, this.errorMessage) : '', index.h("div", { slot: "footer", class: "s-verify-footer" }, index.h("salla-button", { class: "s-verify-submit", "loader-position": 'center', disabled: true, onClick: () => this.submit(), ref: b => this.btn = b }, salla.lang.get('pages.profile.verify')), index.h("p", { class: "s-verify-resend-message", ref: el => this.resendMessage = el }, salla.lang.get('blocks.header.resend_after'), index.h("b", { class: "s-verify-timer", ref: el => this.timer = el })), index.h("a", { href: "#", class: "s-verify-resend", onClick: () => this.resendCode(), ref: el => this.resend = el }, salla.lang.get('blocks.comments.submit'))), index.h("slot", { name: "after-footer" })));
    }
    get host() { return index.getElement(this); }
};
SallaVerify.style = sallaVerifyCss;

exports.salla_verify = SallaVerify;
