/* global Square, fkwcsq_square_smart_buttons, wc_add_to_cart_params */

(function ($) {
    'use strict';
    const block_data = {
        message: null,
        overlayCSS: {
            background: '#fff', opacity: 0.6
        }
    };

    let smart_button_promise = [];

    async function createPaymentInstance() {
        return await Square.payments(fkwcsq_square_smart_buttons.application_id, fkwcsq_square_smart_buttons.location_id);
    }

    function getCurrentPageType() {
        // Check for "yes"/"no" values (WooCommerce convention)
        if (fkwcsq_square_smart_buttons.is_product === 'yes') {
            return 'product';
        } else if (fkwcsq_square_smart_buttons.is_cart === 'yes') {
            return 'cart';
        } else if (fkwcsq_square_smart_buttons.is_pay_for_order === 'yes') {
            return 'pay_for_order';
        } else if (fkwcsq_square_smart_buttons.is_checkout === 'yes') {
            return 'checkout';
        }
        return 'checkout'; // default fallback
    }

    function prepareAddressData(billingContact, prefix = 'billing_') {
        return {
            [`${prefix}first_name`]: billingContact.givenName || '',
            [`${prefix}last_name`]: billingContact.familyName || '',
            [`${prefix}email`]: billingContact.email || '',
            [`${prefix}phone`]: billingContact.phone || '',
            [`${prefix}address_1`]: billingContact.addressLines ? billingContact.addressLines[0] || '' : '',
            [`${prefix}address_2`]: billingContact.addressLines ? billingContact.addressLines[1] || '' : '',
            [`${prefix}city`]: billingContact.city || '',
            [`${prefix}state`]: billingContact.administrativeArea || billingContact.state || '',
            [`${prefix}postcode`]: billingContact.postalCode || '',
            [`${prefix}country`]: billingContact.countryCode || ''
        };
    }

    function isVariableProduct() {
        return $('form.variations_form').length > 0;
    }

    async function run_ajax(endpoint = '', data = {}) {
        return new Promise((resolve, reject) => {
            const requestData = {
                url: wc_add_to_cart_params.wc_ajax_url.toString().replace('%%endpoint%%', endpoint),
                type: 'POST',
                data,
                success(response) {
                    if (response.error) {
                        reject(new Error(response.error));
                    } else if (response.success) {
                        resolve(response.data);
                    } else {
                        resolve(response);
                    }
                },
                error(xhr, status, error) {
                    reject(new Error(`AJAX error: ${error}`));
                }
            };
            if (data instanceof FormData) {
                requestData.processData = false;
                requestData.contentType = false;
            }

            $.ajax(requestData);
        });
    }

    function handleRegularGatewayEvents(skipClick) {
        const selectGateway = () => {
            setTimeout(() => {
                const selected_gateway = $('input[name=\'payment_method\']:checked').val();
                if (selected_gateway === 'fkwcsq_apple_pay') {
                    $('.funnelkit-apple-pay-wrapper').show();
                    $('.funnelkit-regular-gateway-gpay-square-wrapper').hide();
                    $('#place_order').hide();
                } else if (selected_gateway === 'fkwcsq_google_pay') {
                    $('.funnelkit-apple-pay-wrapper').hide();
                    $('.funnelkit-regular-gateway-gpay-square-wrapper').show();
                    $('#place_order').hide();
                } else {
                    $('.funnelkit-apple-pay-wrapper').hide();
                    $('.funnelkit-regular-gateway-gpay-square-wrapper').hide();
                    $('#place_order').show();
                }
            }, 400);
        };

        // Hide Apple Pay gateway if setting is enabled
        if (fkwcsq_square_smart_buttons.apple_hide_in_payment_list === 'yes') {
            $('.wc_payment_method.payment_method_fkwcsq_apple_pay').hide();
            if (!skipClick) $('.wc_payment_method:visible input[name=\'payment_method\']').eq(0).trigger('click');
        }
        if (fkwcsq_square_smart_buttons.gpay_hide_in_payment_list === 'yes') {
            $('.wc_payment_method.payment_method_fkwcsq_google_pay').hide();
            if (!skipClick) $('.wc_payment_method:visible input[name=\'payment_method\']').eq(0).trigger('click');
        }

        $(document.body).off('change.fkwcsq_gateway').on('change.fkwcsq_gateway', 'input[name=\'payment_method\']', function () {
            selectGateway();
        });
        selectGateway();
        $(document.body).on('checkout_error', function () {
            $('body').unblock();
        });
    }

    async function addToCart(el) {
        const $cartForm = el.parents('form.cart');
        const formData = new FormData($cartForm[0]);
        if ($cartForm.length) {
            const single_btn = $('.single_add_to_cart_button');
            if (single_btn.length > 0 && parseInt(single_btn.val()) > 0) {
                formData.append('fkwcsq-add-to-cart', single_btn.val());
            }
            if (formData.get('add-to-cart') > 0) {
                formData.append('fkwcsq-add-to-cart', formData.get('add-to-cart'));
                formData.delete('add-to-cart');
            }

        }
        // Add nonce for security
        if (fkwcsq_square_smart_buttons.nonce) {
            formData.append('nonce', fkwcsq_square_smart_buttons.nonce);
        }
        return run_ajax('fkwcsq_add_to_cart', formData);
    }

    async function processPayment(googlePay, payments, instance = 'google', type = 'express') {
        try {

            const result = await googlePay.tokenize();
            $('body').block(block_data);
            if (result.status !== 'OK') {
                throw new Error(`Failed to process Google Pay payment: ${result.errors ? result.errors[0].message : 'Unknown error'}`);
            }
            // Extract billing and shipping contact information
            const billingContact = result.details?.billing || {};
            const shippingContact = result.details?.shipping || {};
            let form_data = {};
            let _billing = {};
            let _shipping = {};
            if (Object.keys(billingContact).length > 0) {
                _billing = prepareAddressData(billingContact);
            }
            if (Object.keys(shippingContact).length > 0 && Object.prototype.hasOwnProperty.call(shippingContact, 'contact')) {
                _shipping = prepareAddressData(shippingContact.contact, 'shipping_');
                form_data.ship_to_different_address = 'on';
            }
            // Use Apple detection + Google fallback because Uglify can incorrectly
            // collapse `instanceof GooglePayHandler` checks in minified output.
            const isApplePayInstance = instance instanceof ApplePayHandler;
            // Card Token
            form_data.fkwcsq_square_nonce = result.token;
            if (isApplePayInstance) {
                form_data.fkwcsq_apple_pay_nonce = result.token;
            } else {
                form_data.fkwcsq_google_pay_nonce = result.token;
            }
            form_data.terms = 1;
            if ($('._wfacp_post_id').length > 0) {
                form_data.wfacp_post = $('._wfacp_post_id').val();
                form_data._wfacp_post_id = $('._wfacp_post_id').val();
                form_data.wfacp_source = $('#wfacp_source').val();
                form_data.wfacp_timezone = $('#wfacp_timezone').val();
            }
            const paymentRequestData = instance.paymentRequestData || {};
            if (isApplePayInstance) {
                form_data.payment_method = 'fkwcsq_apple_pay';
            } else {
                form_data.payment_method = 'fkwcsq_google_pay';
            }
            form_data = $.extend(form_data, _billing, _shipping);

            const amount = Math.round(parseFloat(paymentRequestData || '0') * 100);
            const verificationDetails = {
                amount: amount.toString(),
                currencyCode: (fkwcsq_square_smart_buttons.currency || fkwcsq_square_smart_buttons.currency).toUpperCase(),
                intent: 'CHARGE',
                billingContact
            };

            const verificationResults = await payments.verifyBuyer(result.token, verificationDetails);
            if (verificationResults && verificationResults.token) {
                // Add the verification token to the form data
                form_data.fkwcsq_verification_token = verificationResults.token;
            } else {
                throw new Error('Invalid verification results received');
            }
            if (type === 'checkout') {
                let $form = $('form.checkout');
                if ($form.length === 0) {
                    $form = $('form#order_review');
                }
                if ($form.length > 0) {
                    const nonceInput = $('<input>').attr({
                        type: 'hidden',
                        name: 'fkwcsq_square_nonce',
                        value: form_data.fkwcsq_square_nonce
                    });
                    if (isApplePayInstance) {
                        $form.append($('<input>').attr({type: 'hidden', name: 'fkwcsq_apple_pay_nonce', value: form_data.fkwcsq_square_nonce}));
                    } else {
                        $form.append($('<input>').attr({type: 'hidden', name: 'fkwcsq_google_pay_nonce', value: form_data.fkwcsq_square_nonce}));
                    }
                    $('#terms')?.prop('checked', true);
                    $form.append(nonceInput);
                    // Add verification token if available
                    if (form_data.fkwcsq_verification_token) {
                        const verificationInput = $('<input>').attr({
                            type: 'hidden',
                            name: 'fkwcsq_verification_token',
                            value: form_data.fkwcsq_verification_token
                        });
                        $form.append(verificationInput);
                    }
                    // Submit the form
                    $form.submit();
                    return;
                }
            }

            // Pass the WooCommerce checkout nonce so WC can validate it inside
            // process_checkout() without us injecting it server-side.
            if (fkwcsq_square_smart_buttons.checkout_nonce) {
                form_data['woocommerce-process-checkout-nonce'] = fkwcsq_square_smart_buttons.checkout_nonce;
            }

            const response = await run_ajax('fkwcsq_process_smart_button_payment', form_data);

            if (response.result === 'success') {
                // Payment was successful, redirect to the thank you page
                window.location.href = response.redirect;
            } else {
                window.location.reload();
            }

        } catch (error) {
            $('body').unblock();
        }
    }

    function return_payment_data() {
        return {
            countryCode: fkwcsq_square_smart_buttons.country || 'US',
            currencyCode: fkwcsq_square_smart_buttons.currency || fkwcsq_square_smart_buttons.currency,
            total: {
                amount: '1',
                label: 'Total'
            },
            shippingOptions: [],
            requestBillingContact: true,
            requestShippingContact: true,
            requestEmail: true,
            requestPhone: true
        };
    }

    class GooglePayHandler {
        constructor() {
            this.payments = null;
            this.googlePay = null;
            this.paymentRequest = null;
            this.paymentRequestData = return_payment_data();
        }

        async init() {
            try {
                await this.initializeSquare();
                await this.events();

                // Note: On checkout pages, Google Pay regular button initialization is handled
                // by run_events() to avoid duplicate fkwcsq_get_request_data AJAX calls.
                // run_events() fetches request data once and passes it to both Apple Pay
                // and Google Pay handlers.

                return {'status': 'success', 'button': 'gpay'};
            } catch (e) {
                return {'status': 'failed', 'button': 'gpay'};
            }
        }

        async initializeSquare() {
            this.payments = await createPaymentInstance();
        }

        async preparePaymentRequest(data) {

            this.paymentRequest = this.payments.paymentRequest(data);
            this.paymentRequestData = data;
            this.paymentRequest.addEventListener('shippingoptionchanged', (option) => {
                return this.fetchShippingDetails({'fkwcsq_choosen_shipping_method': option.id});
            });
            this.paymentRequest.addEventListener('shippingcontactchanged', async (option) => {
                const addressData = {
                    city: option.city || '',
                    countryCode: option.countryCode || '',
                    postalCode: option.postalCode || '',
                    state: option.state || '',
                    addressLines: option.addressLines || []
                };
                // Send address data to WooCommerce session and get shipping options
                return this.fetchShippingDetails({'fkwcsq_shipping_address_contact': addressData});

            });
            this.googlePay = await this.payments.googlePay(this.paymentRequest);
        }

        async RegularGatewayPreparePaymentRequest(data) {
            if (this._regularGatewayInitializing) return;
            if ($('.funnelkit-regular-gateway-gpay-square-wrapper').length === 0) return;
            this._regularGatewayInitializing = true;
            try {
                const self = this;
                delete data.requestShippingContact;
                delete data.shippingOptions;

                // Clear early (before awaits) to prevent race-condition duplicates
                $('.funnelkit-regular-gateway-gpay-square-wrapper').empty();

                const payments = await createPaymentInstance();
                const paymentRequest = payments.paymentRequest(data);
                const googlePay = await payments.googlePay(paymentRequest);

                // Apply theme class to the wrapper for styling
                const buttonTheme = this.get_button_theme();
                $('.funnelkit-regular-gateway-gpay-square-wrapper').addClass(`fkwcs_google_button_theme_${buttonTheme}`);

                googlePay.attach('.funnelkit-regular-gateway-gpay-square-wrapper', this.get_button_options());

                // Set up click handler for the Google Pay button
                $(document.body).off('click', '.funnelkit-regular-gateway-gpay-square-wrapper').on('click', '.funnelkit-regular-gateway-gpay-square-wrapper', async () => {
                    await processPayment(googlePay, payments, self, 'checkout');
                });

                return [paymentRequest, googlePay];
            } catch (e) {
                // Silently handle payment request preparation failure.
            } finally {
                this._regularGatewayInitializing = false;
            }
        }

        async events() {

            if ('checkout' === getCurrentPageType()) {
                await this.checkoutEvents();
            }
            if ('pay_for_order' === getCurrentPageType()) {
                await this.orderpayEvents();
            } else if ('product' === getCurrentPageType()) {
                await this.productEvents();
            }

        }

        async checkoutEvents() {
            const self = this;

            $(document.body).on('click', '#funnelkit-square-google-pay-button-container', async function () {
                await processPayment(self.googlePay, self.payments, self);
            });
            await this.updateRequestData();
        }

        async orderpayEvents() {
            this.handleUpdatedCheckout(fkwcsq_square_smart_buttons.order_pay_data);
        }

        async productEvents() {
            const self = this;
            await this.updateRequestData(this.paymentRequestData);
            const googlePayButton = $('#funnelkit-square-google-pay-button-container.fkwcsq_gpay_product');
            // Hide Google Pay button initially for variable products
            if (isVariableProduct()) {
                googlePayButton.hide();
                // Check if variation is already selected on page load
                this.checkInitialVariationState();

                // Listen for variation change events
                $(document.body).on('found_variation', 'form.variations_form', function (_event, _variation) {
                    // Show Google Pay button when variation is selected

                    googlePayButton.show();
                });

                // Hide button when variation is reset
                $(document.body).on('reset_data', 'form.variations_form', function () {
                    googlePayButton.hide();
                });

                // Hide button when variation is unselected
                $(document.body).on('hide_variation', 'form.variations_form', function () {
                    googlePayButton.hide();
                });
            } else {
                googlePayButton.show();
            }

            $('#funnelkit-square-google-pay-button-container.fkwcsq_gpay_product .fkwcsq_hidden_wrap').on('click', async function () {
                $(this).parent('.fkwcsq_gpay_product').find('button').addClass('loading');
                const payment_request = await addToCart($(this));
                await self.preparePaymentRequest(payment_request);
                $(this).parent('.fkwcsq_gpay_product').find('button').removeClass('loading');
                await processPayment(self.googlePay, self.payments, self);
            });
        }

        async updateRequestData(payment_request = {}) {
            if (Object.keys(payment_request).length === 0) {
                payment_request = await run_ajax('fkwcsq_get_request_data');
            }

            await this.preparePaymentRequest(payment_request);
            // Only attach button if it doesn't exist
            if ($('#funnelkit-square-google-pay-button-container').length > 0 && $('#funnelkit-square-google-pay-button-container button').length === 0) {
                this.googlePay.attach('#funnelkit-square-google-pay-button-container', this.get_button_options());
            }
        }

        get_button_options() {
            return {
                buttonColor: this.get_button_theme(),
                buttonType: this.get_button_type(),
                buttonSizeMode: this.get_button_size(),
                buttonHeight: 42,
                buttonBorderType: 'default_border'
            };
        }

        get_button_theme() {
            return fkwcsq_square_smart_buttons.gpay_button_theme;
        }

        get_button_type() {
            return fkwcsq_square_smart_buttons.gpay_button_type;
        }

        get_button_size() {
            return fkwcsq_square_smart_buttons.gpay_button_size;
        }

        /**
         * Check if variation is already selected on page load
         */
        checkInitialVariationState() {
            const $form = $('form.variations_form');
            if ($form.length > 0) {
                // Check if variation is already selected
                const selectedVariation = $form.find('input[name="variation_id"]').val();
                if (selectedVariation && parseInt(selectedVariation) > 0) {
                    // Variation is already selected, show the button
                    $('#funnelkit-square-google-pay-button-container.fkwcsq_gpay_product').show();
                }
            }
        }

        async fetchShippingDetails(address = {}) {
            // Add nonce for security
            if (fkwcsq_square_smart_buttons.nonce) {
                address.nonce = fkwcsq_square_smart_buttons.nonce;
            }
            return run_ajax('fkwcsq_fetch_cart_details', address);
        }

        /**
         * Process the Google Pay payment
         * @param googlePay
         * @param payments
         * @param type - 'express' for express checkout, 'checkout' for regular checkout
         */

        async handleUpdatedCheckout(paymentRequest) {
            if (paymentRequest.show === false) {
                // Body class fkwcsq_gpay_pay_visible already removed by updated_checkout handler.
                // .hide() here is a guard for any edge case where this method
                // is called without going through the updated_checkout path.
                $('#funnelkit-square-google-pay-button-container').hide();
                return;
            }
            $('#funnelkit-square-google-pay-button-container').show();
            await this.updateRequestData(paymentRequest);
            if (fkwcsq_square_smart_buttons.gpay_hide_in_payment_list !== 'yes') {
                this.RegularGatewayPreparePaymentRequest(paymentRequest);
            }
        }

        cartHandler(request_data) {
            this.updateRequestData(request_data);
            $(document.body).on('click', '#funnelkit-square-google-pay-button-container', async () => {
                await processPayment(this.googlePay, this.payments, this);
            });
        }

        cartUpdated(request_data) {
            $('#funnelkit-square-google-pay-button-container').show();
            this.updateRequestData(request_data);
        }

        cartEmptied() {
            $('#funnelkit-square-google-pay-button-container').hide();
        }
    }

    class ApplePayHandler {
        constructor() {
            this.payments = null;
            this.applePay = null;
            this.paymentRequest = null;
            this.paymentRequestData = return_payment_data();
        }

        async init() {
            try {
                await this.initializeSquare();
                await this.events();
                return {'status': 'success', 'button': 'apple'};
            } catch (e) {
                return {'status': 'failed', 'button': 'apple', e};
            }
        }

        async initializeSquare() {
            this.payments = await createPaymentInstance();
        }

        async preparePaymentRequest(data) {
            this.paymentRequest = this.payments.paymentRequest(data);
            this.paymentRequestData = data;
            this.paymentRequest.addEventListener('shippingoptionchanged', (option) => {
                return this.fetchShippingDetails({'fkwcsq_choosen_shipping_method': option.id});
            });
            this.paymentRequest.addEventListener('shippingcontactchanged', async (option) => {
                const addressData = {
                    city: option.city || '',
                    countryCode: option.countryCode || '',
                    postalCode: option.postalCode || '',
                    state: option.state || '',
                    addressLines: option.addressLines || []
                };
                // Send address data to WooCommerce session and get shipping options
                return this.fetchShippingDetails({'fkwcsq_shipping_address_contact': addressData});
            });
            this.applePay = await this.payments.applePay(this.paymentRequest);
        }

        async RegularGatewayPreparePaymentRequest(data) {
            try {
                const self = this;
                delete data.requestShippingContact;
                delete data.shippingOptions;
                const payments = await createPaymentInstance();
                const paymentRequest = payments.paymentRequest(data);
                const applePay = await payments.applePay(paymentRequest);
                $(document.body).off('click', '.funnelkit-apple-pay-wrapper').on('click', '.funnelkit-apple-pay-wrapper', async function () {
                    await processPayment(applePay, payments, self, 'checkout');
                });
                this.appendTinyHtml();
                if ('fkwcsq_apple_pay' === $('input[name="payment_method"]:checked').val()) {
                    $('.funnelkit-apple-pay-wrapper').show();
                }
                $(document.body).addClass('fkwcsq_apple_pay_visible');
                $(document.body).removeClass('fkwcsq_apple_pay_error');
                return [paymentRequest, applePay];
            } catch (e) {
                $(document.body).addClass('fkwcsq_apple_pay_error');
            }
        }

        async events() {

            // Initialize button containers with proper CSS classes
            this.initializeButtonContainers();
            const pageType = getCurrentPageType();
            if ('checkout' === pageType) {
                await this.checkoutEvents();
            } else if ('pay_for_order' === getCurrentPageType()) {
                await this.orderpayEvents();
            } else if ('product' === pageType) {
                await this.productEvents();
            } else if ('cart' === pageType) {
                this.applePay = await this.payments.applePay(this.paymentRequest);
            }
        }

        /**
         * Initialize button containers with proper CSS classes for styling
         */
        initializeButtonContainers() {
            const currentPage = getCurrentPageType();
            const $container = $('#funnelkit-square-apple-pay-button-container');

            // Remove any existing page-specific classes
            $container.removeClass('fkwcsq_apay_product fkwcsq_apay_cart fkwcsq_apay_checkout');

            // Add the appropriate class based on current page
            if (currentPage === 'product') {
                $container.addClass('fkwcsq_apay_product');
            } else if (currentPage === 'cart') {
                $container.addClass('fkwcsq_apay_cart');
            } else if (currentPage === 'checkout') {
                $container.addClass('fkwcsq_apay_checkout');
            }
        }

        async checkoutEvents() {
            const self = this;
            $(document.body).on('click', '#funnelkit-square-apple-pay-button-container', function () {
                processPayment(self.applePay, self.payments, self);
            });

            this.appendTinyHtml();
            await this.updateRequestData();
        }

        async orderpayEvents() {
            try {
                this.handleUpdatedCheckout(fkwcsq_square_smart_buttons.order_pay_data);
                $(document.body).addClass('fkwcsq_apple_pay_visible');
            } catch (e) {
                $(document.body).addClass('fkwcsq_apple_pay_error');
            }
        }

        appendTinyHtml() {

        }

        async productEvents() {
            const self = this;
            this.paymentRequestData.total.amount = fkwcsq_square_smart_buttons.product_data.amount;
            if ('yes' === fkwcsq_square_smart_buttons.product_data.requestShippingContact) {
                this.paymentRequestData.requestShippingContact = true;
                this.paymentRequestData.shippingOptions = fkwcsq_square_smart_buttons.product_data.shippingOptions;
            }

            await this.updateRequestData(this.paymentRequestData);
            const applePayButton = $('#funnelkit-square-apple-pay-button-container.fkwcsq_apay_product');
            // Hide Apple Pay button initially for variable products
            if (isVariableProduct()) {
                applePayButton.hide();
                // Check if variation is already selected on page load
                this.checkInitialVariationState();

                // Listen for variation change events
                $(document.body).on('show_variation', 'form.variations_form', async function (event, variation) {
                    if (variation.is_in_stock === true && variation.is_purchasable === true) {
                        self.paymentRequestData.total.amount = variation.display_price;
                        await self.updateRequestData(this.paymentRequestData);
                        // Show Apple Pay button when variation is selected
                        applePayButton.show();
                    }
                });
                // Hide button when variation is reset
                $(document.body).on('reset_data', 'form.variations_form', function () {
                    applePayButton.hide();
                });

                // Hide button when variation is unselected
                $(document.body).on('hide_variation', 'form.variations_form', function () {
                    applePayButton.hide();
                });
            } else {
                applePayButton.show();
            }

            $('#funnelkit-square-apple-pay-button-container.fkwcsq_apay_product').on('click', function () {
                addToCart($(this));
                //await self.preparePaymentRequest(payment_request);
                processPayment(self.applePay, self.payments, self);
            });
        }

        async updateRequestData(payment_request = {}) {
            if (Object.keys(payment_request).length === 0) {
                payment_request = await run_ajax('fkwcsq_get_request_data');
            }

            await this.preparePaymentRequest(payment_request);

        }

        /**
         * Check if variation is already selected on page load
         */
        checkInitialVariationState() {
            const $form = $('form.variations_form');
            if ($form.length > 0) {
                // Check if variation is already selected
                const selectedVariation = $form.find('input[name="variation_id"]').val();
                if (selectedVariation && parseInt(selectedVariation) > 0) {
                    // Variation is already selected, show the button
                    $('#funnelkit-square-apple-pay-button-container.fkwcsq_apay_product').show();
                }
            }
        }

        async fetchShippingDetails(address = {}) {
            // Add nonce for security
            if (fkwcsq_square_smart_buttons.nonce) {
                address.nonce = fkwcsq_square_smart_buttons.nonce;
            }
            return run_ajax('fkwcsq_fetch_cart_details', address);
        }

        async handleUpdatedCheckout(paymentRequest) {
            if (paymentRequest.show === false) {
                $('#funnelkit-square-apple-pay-button-container').hide();
                $('.funnelkit-apple-pay-wrapper').hide();
                return;
            }
            await apple_pay.updateRequestData(paymentRequest);
            this.RegularGatewayPreparePaymentRequest(paymentRequest);
        }

        cartHandler(request_data) {
            this.updateRequestData(request_data);
            $(document.body).off('click', '#funnelkit-square-apple-pay-button-container').on('click', '#funnelkit-square-apple-pay-button-container .fkwcsq_hidden_wrap', async () => {
                await processPayment(this.applePay, this.payments, this);
            });
        }

        cartUpdated(request_data) {

            this.updateRequestData(request_data);
        }

        cartEmptied() {

        }
    }

    // Initialize the Apple Pay handler
    const apple_pay = new ApplePayHandler();
    // Initialize the Google Pay handler
    const google_pay = new GooglePayHandler();

    smart_button_promise = [
        google_pay.init(),
        apple_pay.init()

    ];

    Promise.all(smart_button_promise).then((values) => {
        let btn_visible = false;
        values.forEach(value => {
            if (value.status === 'success') {
                btn_visible = true;
            }
            if (value.button === 'apple') {
                if (value.status === 'success') {
                    $(document.body).addClass('fkwcsq_apple_pay_visible');
                    if (fkwcsq_square_smart_buttons.apple_hide_in_payment_list !== 'yes') {
                        $('.wc_payment_method.payment_method_fkwcsq_apple_pay').show();
                        $('#wfacp_smart_button_fkwcsq_apple_pay').show();
                    }
                } else {
                    $(document.body).addClass('fkwcsq_apple_pay_error');
                }
            }
            if (value.button === 'gpay') {
                if (value.status === 'success') {
                    if (fkwcsq_square_smart_buttons.gpay_hide_in_payment_list !== 'yes') {
                        $(document.body).addClass('fkwcsq_gpay_pay_visible');
                        $('.wc_payment_method.payment_method_fkwcsq_google_pay').show();
                    }
                } else {
                    $(document.body).addClass('fkwcsq_gpay_pay_error');
                }
            }
        });

        if (btn_visible) {
            run_events();
        } else {
            $('.fkwcsq_express_container')?.hide();
        }
    });
    function run_events() {

        handleRegularGatewayEvents();
        $('.fkwcsq_express_container')?.show();
        $(document.body).addClass('fkwcsq_express_container_show');

        async function cartEvents() {
            const request_data = await run_ajax('fkwcsq_get_request_data');
            apple_pay.cartHandler(request_data);
            google_pay.cartHandler(request_data);
            $(document.body).on('updated_cart_totals', async () => {
                const request_data = await run_ajax('fkwcsq_get_request_data');
                apple_pay.cartUpdated(request_data);
                google_pay.cartUpdated(request_data);
            });
            $(document.body).on('wc_cart_emptied', async () => {
                apple_pay.cartEmptied();
                google_pay.cartEmptied();
            });
        }

        if ('cart' === getCurrentPageType()) {
            cartEvents();
        }
        if ('checkout' === getCurrentPageType()) {
            (async () => {
                const request_data = await run_ajax('fkwcsq_get_request_data');
                apple_pay.handleUpdatedCheckout(request_data);
                google_pay.handleUpdatedCheckout(request_data);
            })();
        }
        if ('pay_for_order' === getCurrentPageType() && Object.prototype.hasOwnProperty.call(fkwcsq_square_smart_buttons, 'order_pay_data')) {
            handleRegularGatewayEvents();
        }

        $(document.body).on('updated_checkout', async (e, v) => {
            handleRegularGatewayEvents(true);
            if (Object.prototype.hasOwnProperty.call(v, 'fragments') && Object.prototype.hasOwnProperty.call(v.fragments, 'fkwcsq_payment_request')) {
                const paymentRequest = v.fragments['fkwcsq_payment_request'];
                if (paymentRequest.show === false) {
                    $('.fkwcsq_express_container').hide();
                    $('#funnelkit-square-google-pay-button-container').hide();
                    // Must remove this body class — CSS rule `.fkwcsq_gpay_pay_visible .fkwcsq_gpay_checkout { display:flex !important }`
                    // overrides jQuery's inline display:none, making .hide() ineffective without this removal.
                    $(document.body).removeClass('fkwcsq_express_container_show fkwcsq_gpay_pay_visible');
                } else {
                    $('.fkwcsq_express_container').show();
                    $(document.body).addClass('fkwcsq_express_container_show');
                    // Restore gpay visibility class only if GPay actually initialized (no error class)
                    if (!$(document.body).hasClass('fkwcsq_gpay_pay_error')) {
                        $('#funnelkit-square-google-pay-button-container').show();
                        $(document.body).addClass('fkwcsq_gpay_pay_visible');
                    }
                }
                apple_pay.handleUpdatedCheckout(paymentRequest);
                google_pay.handleUpdatedCheckout(paymentRequest);
            }
        });
    }

})(jQuery);
