/*!
 * Copyright 2024-2025 Simply.IN Sp. z o.o.
 *
 * NOTICE OF LICENSE
 * Licensed under the EUPL-1.2 or later.
 * You may not use this work except in compliance with the Licence.
 * Copy of the Licence is available at: https://joinup.ec.europa.eu/software/page/eupl
 * It is bundled with this package in the file LICENSE.txt
 *
 * @author    Simply.IN Sp. z o.o.
 * @copyright 2024-2025 Simply.IN Sp. z o.o.
 * @license   https://joinup.ec.europa.eu/software/page/eupl
 */

const $ = window.jQuery;
const simplyin = window.simplyin;

$(function () {
    window.SimplyInPayment = {
        errorMsgBlik: null,
        successMsgBlik: null,
        cc: null,
        successMsg: null,
        errorMsg: null,
        ott_corect: false,
        blik_corect: false,
        inputs: [],
        newImg: false,
        card_interval: null,
        duplicated_card: null,
        init: function () {
            this.inlinePaymentOptionLogo();
            this.setupCardForm();
            this.setupBlikInputs();
            this.setupPaymentOptionChange();
            this.setupBlikEvents();
            this.setupOrderStatusCheck();
            this.bindPaymentMethodChecker();
            this.autoSelectPayment();
        },
        // PaymentOption::setLogo() lets the theme place the logo where it wants — classic wraps it
        // into a second <label> that breaks onto its own line below the caption. Pull it inline in
        // front of the caption (the pre-setLogo look) wherever the theme put it.
        inlinePaymentOptionLogo: function () {
            $('input[type="radio"][data-module-name^="simplyin"]').each(function () {
                const $paymentOption = $(this).closest('.payment-option');
                if (!$paymentOption.length) return;

                const $label = $paymentOption.find('label').first()
                    .css({ display: 'flex', alignItems: 'center', gap: '8px' });
                const $themeLogo = $paymentOption.find('img[src*="/simplyin/views/img/"]').first();
                if (!$themeLogo.length) return;

                $themeLogo.css({ maxHeight: '20px', width: 'auto' });
                if ($label.find('img').length) return;

                const $logoLabel = $themeLogo.closest('label');
                $label.prepend($themeLogo);
                if ($logoLabel.length && !$logoLabel.is($label) && $logoLabel.children().length === 0 && $logoLabel.text().trim() === '') {
                    $logoLabel.remove();
                }
            });
        },
        bindGeneralConfirmationEvent: function () {
            const self = this;
            const button = document.querySelector('#payment-confirmation button');
            if (!button) return;

            const handler = (e) => {
                const selected = $('.simplyin-payment-option:checked');
                const errorContainer = $('#simplyin-payment-error');

                if (!selected.length) {
                    e.preventDefault();
                    e.stopPropagation();
                    e.stopImmediatePropagation();

                    if (errorContainer) {
                        errorContainer.html(self.l('Please select a payment method'));
                        errorContainer.fadeIn();
                        $('.simplyin-payment-option-item').addClass('select-method');
                    }
                    return false;
                }

                if (errorContainer) {
                    errorContainer.fadeOut();
                }
            };

            if (button._simplyinGeneralHandler) {
                button.removeEventListener('click', button._simplyinGeneralHandler, { capture: true });
            }

            button.addEventListener('click', handler, { capture: true });
            button._simplyinGeneralHandler = handler;
        },

        unbindGeneralConfirmationEvent: function () {
            const button = document.querySelector('#payment-confirmation button');
            if (button && button._simplyinGeneralHandler) {
                button.removeEventListener('click', button._simplyinGeneralHandler, { capture: true });
                delete button._simplyinGeneralHandler;
            }
        },

        bindPaymentMethodChecker: function () {
            const self = this;
            $(document).on('change', 'input[name=payment-option]', function () {
                if ($(this).data('module-name') && $(this).data('module-name').startsWith('simplyin')) {
                    if ($('.simplyin-payment-option:checked').length == 0) {
                        self.bindGeneralConfirmationEvent();
                        return true;
                    }
                } else {
                    self.unbindGeneralConfirmationEvent();
                    return true;
                }
            });
        },
        l: function (string) {
            if (typeof simplyin.labels !== 'undefined' && simplyin.labels[string]) {
                return simplyin.labels[string];
            }
            return string;
        },
        setupCardForm: function () {
            const self = this;
            if (self.duplicated_card) {
                clearTimeout(self.duplicated_card);
            }
            self.duplicated_card = setTimeout(function () {
                if ($('#simplyin-add-card-payment-method input[name="simplyin-payment-option"]').length && $('#card-number').find('div').length == 0) {
                    let iframe_url = $('#simplyin-add-card-payment-method input[name="simplyin-payment-option"]').data('iframe-url');
                    let integrator_id = $('#simplyin-add-card-payment-method input[name="simplyin-payment-option"]').data('integrator-id');
                    const integratorId = integrator_id;
                    const iframeUrl = iframe_url;

                    const script = document.createElement('script');
                    script.src = iframeUrl;
                    script.onload = () => self.initCardForm(integratorId);
                    document.head.appendChild(script);

                    self.watchCardFocus();
                }
            }, 150);
        },

        watchCardFocus: function () {
            var self = this;
            if (this._cardFocusObserver) {
                this._cardFocusObserver.disconnect();
            }
            var roots = document.querySelectorAll('#card-holder, #card-number, #expiry-date, #verification-code');
            if (!roots.length) {
                return;
            }
            this._cardFocusObserver = new MutationObserver(function () {
                self.hideCardErrors();
            });
            for (var i = 0; i < roots.length; i++) {
                this._cardFocusObserver.observe(roots[i], { attributes: true, attributeFilter: ['class'], subtree: true });
            }
        },
        hideCardErrors: function () {
            if ($('.ccIframe-component.has-focus').length) {
                $(this.errorMsg).hide();
            }
        },
        initCardForm: function (integratorId) {
            try {
                this.cc = CCIframe({ integratorId: integratorId });

                const styleConfig = {
                    fonts: [{
                        family: 'Inter',
                        src: "url(https://fonts.gstatic.com/s/inter/v18/UcCo3FwrK3iLTcviYwYZ8UA3.woff2) format('woff2')",
                        style: 'normal',
                        weight: '100 900',
                    }],
                    styles: {
                        base: {
                            color: 'rgba(0, 0, 0, 0.8)',
                            fontFamily: 'Inter',
                            fontSize: '14px',
                        },
                    },
                };

                this.cc.createComponent('cardHolder', '#card-holder', styleConfig);
                this.cc.createComponent('cardNumber', '#card-number', styleConfig);
                this.cc.createComponent('cardExp', '#expiry-date', styleConfig);
                this.cc.createComponent('cardCvv', '#verification-code', styleConfig);

                this.successMsg = '#card-success-message-1';
                this.errorMsg = '#form-error-1';
            } catch (e) {
            }
        },

        setupBlikInputs: function () {
            this.successMsgBlik = '#blik-success-message-1';
            this.errorMsgBlik = '#blik-form-error-1';
            this.inputs = '.simplyin-blik-digit-input';

            const self = this;

            $(document).on('click', this.inputs, function () {
                if (!$('input[name="simplyin-payment-option"][data-payment-type="blik"]').is(':checked')) {
                    $('input[name="simplyin-payment-option"][data-payment-type="blik"]').prop('checked', true).trigger('change');
                }
            });
            $(document).on('input', this.inputs, function () {
                let $input = $(this);
                const $inputs = $(self.inputs);
                let index = $inputs.index(this);

                let value = $input.val().replace(/\D/g, '');
                $input.val(value.substring(0, 1));

                if (value && index < $inputs.length - 1) {
                    $($inputs[index + 1]).focus();
                }
            });

            $(document).on('keydown', this.inputs, function (e) {
                if (e.key === 'Backspace') {
                    const $input = $(this);
                    const $inputs = $(self.inputs);
                    let index = $inputs.index(this);

                    if (!$input.val() && index > 0) {
                        $($inputs[index - 1]).focus();
                    }
                }
            });

            $(document).on('paste', this.inputs, function (e) {
                e.preventDefault();
                const $inputs = $(self.inputs);
                const $input = $(this);
                let index = $inputs.index(this);

                const paste = (e.originalEvent.clipboardData || window.clipboardData).getData('text').replace(/\D/g, '');
                if (!paste) return;

                [...paste].slice(0, $inputs.length).forEach((digit, i) => {
                    $($inputs[i]).val(digit);
                });

                const lastIndex = Math.min(paste.length, $inputs.length) - 1;
                $($inputs[lastIndex]).focus();
                $($inputs[$inputs.length - 1]).trigger('change');
            });
        },

        getBlikCode: function () {
            return $(this.inputs).map(function () {
                return $(this).val();
            }).get().join('');
        },

        checkBlikCode: function () {
            const self = this;
            let blik_code = this.getBlikCode();
            let result = (blik_code.length === 6);
            return result;
        },
        setPaymentsTerm: function (target) {
            const self = this;
            let regulationsUrl = target.data('regulationsurl');
            let gdprUrl = target.data('gdprurl');
            let provider = target.data('payment-provider-name');

            let terms_string = self.l('By paying, I accept the terms and [conditions] and [privacy policy] of %s');

            terms_string = terms_string.replace(/\[(.*?)\]/, `<a class="simplyin-payment-provider-url" href="${regulationsUrl}" target="_blank">$1</a>`);
            terms_string = terms_string.replace(/\[(.*?)\]/, `<a class="simplyin-payment-provider-url" href="${gdprUrl}" target="_blank">$1</a>`);

            terms_string = terms_string.replace('%s', provider);

            $('.simplyin-payment-provider-footer').html(
                `<p>${terms_string}</p>`
            );
        },
        setupPaymentOptionChange: function () {
            const self = this;
            $(document).on('change', '#simplyin-save-card', function () {
                if ($(this).is(':checked')) {
                    $('.simplyin-card-name').fadeIn();
                } else {
                    $('.simplyin-card-name').fadeOut();
                }
            });
            $(document).on('change', 'input[name="simplyin-payment-option"]', (e) => {
                let target = $(e.currentTarget);
                let payment_type = target.data('payment-type');
                let params = {
                    action: 'selectPaymentMethod',
                    ajax: 1,
                    ajax_token: simplyin.ajax_token,
                    cart_token: simplyin.cart_token,
                    payment_id: target.val(),
                    payment_type: payment_type,
                    payment_provider: target.data('payment-provider-name'),
                    provider_image: target.data('provider-image'),
                    logo: target.data('logo'),
                };
                self.setPaymentsTerm(target);
                if (payment_type === 'card') {
                    params.card_name = target.data('card-name');
                    params.last_digits = target.data('last-digits');
                    params.card_provider = target.data('card-provider');
                    this.unbindCardConfirmationEvents();
                    this.unbindBlikConfirmationEvents();
                } else if (payment_type === 'blik') {
                    this.unbindCardConfirmationEvents();
                    this.bindBlikConfirmationEvents();
                } else if (payment_type === 'add-card') {
                    this.bindCardConfirmationEvents();
                    this.unbindBlikConfirmationEvents();
                }

                $.ajax({
                    url: simplyin.controllers.payment_ajax,
                    method: 'POST',
                    data: params,
                    dataType: 'json',
                });
                self.unbindGeneralConfirmationEvent();
                $('#simplyin-payment-error').hide();
                $('.simplyin-payment-option-item').removeClass('select-method');
            });
        },

        setupBlikEvents: function () {
            const self = this;
            $(document).on('focus', '.simplyin-blik-digit-input', () => {
                $('.simplyin-blik-digit-input').removeClass('valid error');
                $('.simplyin-blik-error').hide();
            });

            $(document).on('change', 'input[name="simplyin-payment-option"]', function () {
                if ($(this).data('payment-type') !== 'blik') {
                    $('.simplyin-blik-container').hide();
                    $('.simplyin-blik-digit-input').removeClass('valid error').val('');
                    $('#blik-form-error-1').hide();
                } else {
                    $('.simplyin-blik-container').show();
                }
            });

            $(document).on('keyup', '.simplyin-blik-digit-input', () => {
                let blik_code = this.getBlikCode();
                self.checkBlikCode();
                if (blik_code.length === 6) {
                    let params = {
                        action: 'enterBlikCode',
                        ajax: 1,
                        ajax_token: simplyin.ajax_token,
                        cart_token: simplyin.cart_token,
                        blik_code: blik_code,
                    };
                    $('.simplyin-blik-digit-input').addClass('valid');
                    $('.simplyin-blik-error').hide();
                    $.ajax({
                        url: simplyin.controllers.payment_ajax,
                        method: 'POST',
                        data: params,
                        dataType: 'json',
                    }).done(data => {
                        if (data.status === 'success') {
                            $('.simplyin-blik-error').hide();
                        }
                    });
                }
            });

            $(document).on('focusout', '.simplyin-blik-inputs-grid', (e) => {
                if ($(e.relatedTarget).closest('.simplyin-blik-inputs-grid').length) {
                    return;
                }
                if (this.checkBlikCode() === false) {
                    $('.simplyin-blik-digit-input').removeClass('valid').addClass('error');
                    $('.simplyin-blik-error').show();
                } else {
                    $('.simplyin-blik-digit-input').removeClass('error').addClass('valid');
                    $('.simplyin-blik-error').hide();
                }
            });
        },

        bindCardConfirmationEvents: function () {
            const self = this;
            const button = document.querySelector('#payment-confirmation button');
            if (!button) return;
            const handler = (e) => {
                if (this.ott_corect) return true;
                e.preventDefault();
                e.stopPropagation();
                e.stopImmediatePropagation();

                $(this.errorMsg).hide();
                $(this.successMsg).hide();

                this.cc.createToken().then((res) => {
                    if (res && res.oneTimeToken) {
                        $(this.successMsg).show();
                        let params = {
                            action: 'selectPaymentMethod',
                            ajax: 1,
                            ajax_token: simplyin.ajax_token,
                            cart_token: simplyin.cart_token,
                            payment_id: $('input[name="simplyin-payment-option"]:checked').val(),
                            payment_type: 'add-card',
                            payment_provider: $('input[name="simplyin-payment-option"]:checked').data('payment-provider-name'),
                            provider_image: $('input[name="simplyin-payment-option"]:checked').data('provider-image'),
                            logo: $('input[name="simplyin-payment-option"]:checked').data('logo'),
                        };
                        if ($('#simplyin-save-card').is(':checked')) {
                            params.card_name = $('#card-name').val();
                            params.card_save = '1';
                        } else {
                            params.card_name = '';
                            params.card_save = '0';
                        }
                        params.last_digits = res.last4digits;
                        params.card_provider = res.organization;
                        params.ott = res.oneTimeToken;
                        this.unbindCardConfirmationEvents();
                        $.ajax({
                            url: simplyin.controllers.payment_ajax,
                            method: 'POST',
                            data: params,
                            dataType: 'json',
                        }).done(() => {
                            this.ott_corect = true;
                            setTimeout(() => {
                                $('#payment-confirmation button').click();
                            }, 300);
                        });
                    } else {
                        $(this.errorMsg).text(self.l('Invalid tokenization response'));
                        $(this.errorMsg).show();
                    }
                }).catch((err) => {
                    $(this.errorMsg).text(self.l('Problem processing card'));
                    $(this.errorMsg).show();
                });
            };

            button.addEventListener('click', handler, { capture: true });
            button._simplyinHandler = handler;
        },

        unbindCardConfirmationEvents: function () {
            const button = document.querySelector('#payment-confirmation button');
            if (button && button._simplyinHandler) {
                button.removeEventListener('click', button._simplyinHandler, { capture: true });
                delete button._simplyinHandler;
            }
        },

        bindBlikConfirmationEvents: function () {
            const self = this;
            const button = document.querySelector('#payment-confirmation button');
            if (!button) return;

            const handler = (e) => {
                if (this.blik_corect) return true;
                e.preventDefault();
                e.stopPropagation();
                e.stopImmediatePropagation();

                $(this.errorMsgBlik).hide();
                $(this.successMsgBlik).hide();

                if (!this.checkBlikCode()) {
                    $(this.errorMsgBlik).text(self.l('Invalid BLIK code'));
                    $(this.errorMsgBlik).show();
                    return;
                }

                let blik_code = this.getBlikCode();

                let params = {
                    action: 'selectPaymentMethod',
                    ajax: 1,
                    ajax_token: simplyin.ajax_token,
                    cart_token: simplyin.cart_token,
                    payment_id: $('input[name="simplyin-payment-option"]:checked').val(),
                    payment_type: 'blik',
                    blik_code: blik_code,
                    payment_provider: $('input[name="simplyin-payment-option"]:checked').data('payment-provider-name'),
                    provider_image: $('input[name="simplyin-payment-option"]:checked').data('provider-image'),
                    logo: $('input[name="simplyin-payment-option"]:checked').data('logo'),
                };

                this.unbindBlikConfirmationEvents();

                $.ajax({
                    url: simplyin.controllers.payment_ajax,
                    method: 'POST',
                    data: params,
                    dataType: 'json',
                }).done((data) => {
                    if (data.success === true) {
                        this.blik_corect = true;
                        setTimeout(() => {
                            $('#payment-confirmation button').click();
                        }, 300);
                    } else {
                        $(this.errorMsgBlik).text(self.l('BLIK code rejected'));
                        $(this.errorMsgBlik).show();
                    }
                }).fail(() => {
                    $(this.errorMsgBlik).text(self.l('Problem with BLIK processing'));
                    $(this.errorMsgBlik).show();
                });
            };

            button.addEventListener('click', handler, { capture: true });
            button._simplyinBlikHandler = handler;
        },

        unbindBlikConfirmationEvents: function () {
            const button = document.querySelector('#payment-confirmation button');
            if (button && button._simplyinBlikHandler) {
                button.removeEventListener('click', button._simplyinBlikHandler, { capture: true });
                delete button._simplyinBlikHandler;
            }
        },

        setupOrderStatusCheck: function () {
            if (typeof (simplyin.order_sended) !== 'undefined' && !simplyin.order_status_paid) {
                if (simplyin.payment_status == 'PAID') {
                    $('#status-success').show().css('display', 'flex');
                    $('#status-pending').hide();
                    return;
                }
                $('#status-pending').show().css('display', 'flex');
                var checkCount = 0;
                var maxChecks = 100;
                let check_status_interval = setInterval(() => {
                    checkCount++;
                    if (checkCount > maxChecks) {
                        clearInterval(check_status_interval);
                        $('#status-error').show().css('display', 'flex');
                        $('#status-pending').hide();
                        return;
                    }
                    let params = {
                        id_cart: simplyin.id_cart,
                        ajax: 1,
                        ajax_token: simplyin.ajax_token,
                        cart_token: simplyin.cart_token,
                        action: 'checkOrderStatus',
                        id_module: simplyin.id_module,
                        payment_check_token: simplyin.payment_check_token,
                    };
                    $.ajax({
                        url: simplyin.controllers.payment_ajax,
                        method: 'POST',
                        data: params,
                        dataType: 'json',
                    }).done(data => {
                        if (data.status === 'PAID') {
                            $('#status-success').show().css('display', 'flex');
                            $('#status-pending').hide();
                            clearInterval(check_status_interval);
                        } else if (data.status == 'REJECTED' || data.status == 'FAILED' || data.status == 'FAILD') {
                            $('#status-error').show().css('display', 'flex');
                            $('#status-pending').hide();
                            clearInterval(check_status_interval);
                        }
                    });
                }, 3000);
            }
        },

        autoSelectPayment: function () {
            const self = this;
            if ($('input[type="radio"][data-module-name^="simplyin"]').length) {
                $('input[type="radio"][data-module-name^="simplyin"]').prop('checked', true).trigger('change');
            }
        },
    };

    if (simplyin.checkout == 'classic' || simplyin.checkout == 'hummingbird') {
        window.SimplyInPayment.init();
    }
});
