var Wick = Wick || {};
window.INIT_KLARNA_PAYMENT = window.INIT_KLARNA_PAYMENT || 'INIT_KLARNA_PAYMENT';
window.INIT_BILLIE_PAYMENT = window.INIT_BILLIE_PAYMENT || 'INIT_BILLIE_PAYMENT';
Wick.CheckoutPaymentDetails = (function () {
    const $modal = $('#modal-terms-and-conditions');

    let prevPaymentMethod = null;
    let prevClearableMethod;

    let detailsLabel = {
        inputName: 'card-name',
        buttonName: 'btn-enter-details',
    };

    const toggleBillieRepaymentTermsClass = 'js-billie-repayment-terms--has-selection';

    const elements = {
        $billieRepaymentTerms: $('.js-billie-repayment-terms'),
        $billieWidget: $('.checkout-payment-details__billie[data-billie]'),
        $wrapperPaymentInput: $('.checkout-payment-details__row'),
        paymentInputName: '[name=payment-method]',
        $cardDetails: $('.checkout-payment-details__card-details'),
        $placeOrder: $('.checkout-payment-details__place-order'),
        $billingAddress: $('.billing-address'),
        hiddenCardDetailsClass: 'checkout-payment-details__card-details_hidden',
        $billieBusiness: $('[data-billie-business]'),
        businessTypeName: '[name="businessType"]',
        $unregisteredFields: $('#unregistered-fields'),
        $registeredFields: $('#registered-fields'),
        hiddenClass: 'd-none',
    };

    let klarnaInited = false;
    let billieInited = false;

    function initKlarnaPayment() {
        if (klarnaInited) return Promise.resolve({ ok: true, cached: true });

        return new Promise((resolve, reject) => {
            const payload = {};
            const detail = {
                resolve: (data) => {
                    klarnaInited = true;
                    resolve(data);
                },
                reject,
            };

            const evt = createEvent(window.INIT_KLARNA_PAYMENT, payload, detail);
            window.dispatchEvent(evt);
        });
    }

    function initBilliePayment() {
        if (billieInited) return Promise.resolve({ ok: true, cached: true });

        return new Promise((resolve, reject) => {
            const payload = {};
            const detail = {
                resolve: (data) => {
                    billieInited = true;
                    resolve(data);
                },
                reject,
            };

            const evt = createEvent(window.INIT_BILLIE_PAYMENT, payload, detail);
            window.dispatchEvent(evt);
        });
    }

    function getBillieRepaymentTermsLength() {
        const billieRepaymentTerms =
            (window.Wick && window.Wick?.BillieData?.billiePaymentTerms) || [];

        return Array.isArray(billieRepaymentTerms) ? billieRepaymentTerms.length : 0;
    }

    function preparePage() {
        var modalOpened = $('.modal.show').length;
        if (!modalOpened) return;

        var modalContent = $modal.find('.modal-content').clone();
        $modal.modal('hide');
        modalContent.addClass('print-area');

        $('body').addClass('print-mode').append(modalContent);
    }

    function resetPage() {
        var modalPrintModeActive = $('body.print-mode').length;
        if (!modalPrintModeActive) return;

        $('body').removeClass('print-mode');
        $('.print-area').remove();
        $modal.modal('show');
    }

    function getPaymentMethods() {
        return $(elements.paymentInputName)
            .map((_, item) => $(item).val())
            .get();
    }

    function togglePaymentBlocks(paymentMethods, checkedMethod) {
        paymentMethods.forEach((method) => {
            $(`[data-${method}]`).hide();
        });

        const $selected = $(`[data-${checkedMethod}]`);
        if ($selected.length) {
            $selected.show();
        }
    }
    function resetAllCheckoutForms(keepPaymentMethod) {
        const $container = elements.$wrapperPaymentInput.closest('.checkout-payment-details');
        if (!$container.length) return;

        $container.find('form').each(function () {
            if (Wick.Forms && typeof Wick.Forms.clearValidationErrors === 'function') {
                Wick.Forms.clearValidationErrors(this);
            }
        });

        $container
            .find(
                'input[type="text"], input[type="email"], input[type="tel"], input[type="number"], input[type="password"], textarea'
            )
            .val('');

        $container.find('select').each(function () {
            this.selectedIndex = 0;
        });

        $container.find('input[type="checkbox"]').prop('checked', false);

        $container.find('input[type="radio"]').each(function () {
            const $radio = $(this);
            const name = $radio.attr('name');
            const val = $radio.val();

            if (name === 'payment-method') {
                $radio.prop('checked', val === keepPaymentMethod);
            } else {
                $radio.prop('checked', false);
            }
        });

        $container.find('.radio-expanded-content').hide();
    }

    function setBillingDetailsRowVisibility(isVisible) {
        const $row = elements.$billingAddress.find('.checkout-payment-details__row');
        $row.toggle(isVisible);
        $row.find(':input').prop('disabled', !isVisible);
    }

    function _syncBillieUI(isReady) {
        elements.$billieWidget.toggle(isReady);
        elements.$billieRepaymentTerms.toggleClass(toggleBillieRepaymentTermsClass, isReady);
    }

    function resetBillieUi() {
        _syncBillieUI(false);
    }

    function setBillieStepVisibility(isReady) {
        _syncBillieUI(isReady);
        setBillingDetailsRowVisibility(isReady);
    }

    function resetBillieRepaymentSelection() {
        elements.$billieRepaymentTerms.find('input[name="repaymentTerms"]').prop('checked', false);
    }

    function showBillieBusiness() {
        elements.$billieBusiness.removeClass(elements.hiddenClass);
    }

    function hideBillieBusiness() {
        elements.$billieBusiness.addClass(elements.hiddenClass);

        elements.$unregisteredFields.addClass(elements.hiddenClass).removeAttr('style');

        elements.$registeredFields.addClass(elements.hiddenClass).removeAttr('style');

        elements.$billieBusiness.find('input[type="radio"]').prop('checked', false);
        elements.$billieBusiness.find('input.tbx').val('');
    }

    function toggleBusinessTypeFields(type) {
        const isUnregistered = type === 'unregistered';
        const isRegistered = type === 'registered';

        elements.$unregisteredFields
            .toggleClass(elements.hiddenClass, !isUnregistered)
            .removeAttr('style');
        elements.$registeredFields
            .toggleClass(elements.hiddenClass, !isRegistered)
            .removeAttr('style');
    }

    function showBillingAddressDataCardFields() {
        const dataCardFields = elements.$billingAddress.find('[data-card]');
        if (dataCardFields) {
            dataCardFields.show();
        }
    }

    function changeDetailsBlock(checkedMethod) {
        if (checkedMethod !== 'billie') {
            resetBillieUi();
            setBillingDetailsRowVisibility(true);
            hideBillieBusiness();
        }

        if (checkedMethod === 'klarna') {
            initKlarnaPayment().catch(() => {});
        }

        if (checkedMethod === 'billie' && getBillieRepaymentTermsLength() === 1) {
            initBilliePayment().catch(() => {});
        }

        switch (checkedMethod) {
            case 'paypal':
                hideCardDetails();
                showPlaceOrder();
                hideBillingAddres();
                break;

            case 'klarna':
                hideBillingAddres();
                break;

            case 'billie':
                detailsLabel = {
                    ...detailsLabel,
                    labelText: 'Name on Billie account',
                    buttonText: 'Pay with Billie',
                };
                changeLabelText(detailsLabel);

                setBillieStepVisibility(getBillieRepaymentTermsLength() === 1);
                resetBillieRepaymentSelection();
                showBillieBusiness();
                break;

            case 'clearpay':
                detailsLabel = {
                    ...detailsLabel,
                    labelText: 'Name on Clearpay account',
                    buttonText: 'Pay with Clearpay',
                };
                prevClearableMethod === 'card' && clearInputFields();
                changeLabelText(detailsLabel);
                prevClearableMethod = checkedMethod;
                showBillingAddressDataCardFields();
                break;

            case 'apple-pay':
                hideCardDetails();
                hidePlaceOrder();
                hideBillingAddres();
                break;

            case 'google-pay':
                hideCardDetails();
                hidePlaceOrder();
                hideBillingAddres();
                break;

            case 'card':
                detailsLabel = {
                    ...detailsLabel,
                    labelText: 'Name on card',
                    buttonText: 'Enter card details',
                };
                prevClearableMethod === 'clearpay' && clearInputFields();
                changeLabelText(detailsLabel);
                prevClearableMethod = checkedMethod;
                break;

            default:
                showPlaceOrder();
        }
    }

    function hideCardDetails() {
        elements.$cardDetails.addClass(elements.hiddenCardDetailsClass);
    }

    function hideBillingAddres() {
        elements.$billingAddress.addClass(elements.hiddenClass);
    }

    function changeLabelText(params) {
        const { inputName, labelText, buttonName, buttonText } = params;

        elements.$billingAddress.removeClass(elements.hiddenClass);

        let labelElement = elements.$billingAddress.find('[for="' + inputName + '"]');
        let buttonElement = elements.$billingAddress.find('.' + buttonName + ' .btn__text');

        labelElement && labelElement.text(labelText);
        buttonElement && buttonElement.text(buttonText);
    }

    function clearInputFields() {
        elements.$billingAddress.find('input.tbx').val('');
    }

    function showPlaceOrder() {
        elements.$placeOrder.removeClass(elements.hiddenClass);
    }

    function hidePlaceOrder() {
        elements.$placeOrder.addClass(elements.hiddenClass);
    }

    function initBillieBusinessTypeToggle() {
        $(document).on('change', elements.businessTypeName, function () {
            toggleBusinessTypeFields($(this).val());
        });
    }

    function forceReflow($element) {
        if (!$element.length) return;
        void $element[0].offsetHeight;
        $(window).trigger('resize');
    }

    function init() {
        const paymentMethods = getPaymentMethods();
        initBillieBusinessTypeToggle();
        hideBillieBusiness();

        $(document).on('change', 'input[name="repaymentTerms"]', function () {
            const currentMethod = $(elements.paymentInputName + ':checked').val();
            if (currentMethod !== 'billie') return;

            requestAnimationFrame(() => {
                forceReflow(elements.$billieWidget);
            });

            const hasSelection = $('input[name="repaymentTerms"]:checked').length > 0;
            setBillieStepVisibility(hasSelection);

            const $row = $(this).closest('.form-row[data-row-required]');
            $row.removeClass('form-row_validation-error').find('.form-row__error').remove();
        });

        elements.$wrapperPaymentInput.on('change', elements.paymentInputName, function () {
            const checkedMethod = $(this).val();

            if (prevPaymentMethod && prevPaymentMethod !== checkedMethod) {
                resetAllCheckoutForms(checkedMethod);
            } else {
                const form = $(this).closest('form')[0];
                form &&
                    Wick.Forms &&
                    Wick.Forms.clearValidationErrors &&
                    Wick.Forms.clearValidationErrors(form);
            }

            togglePaymentBlocks(paymentMethods, checkedMethod);
            changeDetailsBlock(checkedMethod);

            prevPaymentMethod = checkedMethod;
        });

        $('.btn-new-card').on('click', function () {
            $('[data-new-card]').show();
            $('[data-existing-card]').hide();
            return false;
        });

        $('.btn-back-to-existing-card').on('click', function () {
            $('[data-new-card]').hide();
            $('[data-existing-card]').show();
            return false;
        });

        prevPaymentMethod = $(elements.paymentInputName + ':checked').val() || null;

        if (!$modal.length) return;

        if (typeof window.onbeforeprint !== 'undefined') {
            window.onbeforeprint = preparePage;
            window.onafterprint = resetPage;
        } else if (window.matchMedia) {
            var mediaQueryList = window.matchMedia('print');
            mediaQueryList.addListener(function (mql) {
                if (mql.matches) {
                    preparePage();
                } else {
                    resetPage();
                }
            });
        }
    }

    init();
})();
