/* global Square, fkwcsq_afterpay_params */

/**
 * FunnelKit Square Afterpay/Clearpay Handler
 *
 * Handles Square Afterpay/Clearpay initialization and tokenization.
 * Uses CSS body class approach for button visibility toggle.
 *
 * @package FunnelKit_Square
 */

(function ($) {
    'use strict';

    // State management
    let afterpay = null;
    let payments = null;
    let isProcessing = false;
    let isInitialized = false;
    let isInitializing = false;
    let paymentRequestData = null;

    /**
     * Toggle button visibility based on payment method selection.
     * Uses CSS body class for reliable visibility control.
     */
    function toggleButtons() {
        const selectedPayment = $('input[name="payment_method"]:checked').val();

        if (selectedPayment === 'fkwcsq_afterpay') {
            $('body').addClass('fkwcsq-afterpay-selected');
        } else {
            $('body').removeClass('fkwcsq-afterpay-selected');
        }
    }

    /**
     * Get the current cart total from payment request data
     *
     * @returns {string} Cart total amount
     */
    function getCartTotal() {
        // Use payment request data from checkout fragments (preferred)
        if (paymentRequestData && paymentRequestData.total && paymentRequestData.total.amount) {
            return paymentRequestData.total.amount;
        }

        // Fallback to localized params if available
        if (fkwcsq_afterpay_params.payment_request && fkwcsq_afterpay_params.payment_request.total) {
            return fkwcsq_afterpay_params.payment_request.total.amount;
        }

        return '0.00';
    }

    /**
     * Build payment request for Afterpay
     *
     * @param {Object} paymentsInstance Square payments instance
     * @returns {Object} Payment request
     */
    function buildPaymentRequest(paymentsInstance) {
        const total = getCartTotal();

        const paymentRequest = paymentsInstance.paymentRequest({
            countryCode: fkwcsq_afterpay_params.country_code,
            currencyCode: fkwcsq_afterpay_params.currency_code,
            total: {
                amount: total,
                label: 'Total'
            },
            requestShippingContact: true
        });

        // Add Afterpay-specific event listeners (required for proper initialization)
        paymentRequest.addEventListener('afterpay_shippingaddresschanged', function () {
            return {
                shippingOptions: [{
                    amount: '0.00',
                    id: 'shipping-option-1',
                    label: 'Shipping',
                    taxLineItems: [],
                    total: {
                        amount: total,
                        label: 'Total'
                    }
                }]
            };
        });

        paymentRequest.addEventListener('afterpay_shippingoptionchanged', function () {
            // Event listener for shipping option changes (informational only)
        });

        return paymentRequest;
    }

    /**
     * Initialize Afterpay payment method
     */
    async function initializeAfterpay() {
        const buttonWrapper = document.getElementById('fkwcsq-afterpay-button-wrapper');
        const buttonContainer = document.getElementById('fkwcsq-afterpay-button-container');

        // Check if containers exist
        if (!buttonWrapper || !buttonContainer) {
            return;
        }

        // Prevent concurrent initializations
        if (isInitializing) {
            return;
        }

        // Clear any previous errors
        hideError();

        // Check if already initialized
        if (isInitialized && afterpay) {
            return;
        }

        isInitializing = true;

        // Check if Square SDK is loaded
        if (typeof Square === 'undefined') {
            console.error('Square SDK not loaded');
            showError(fkwcsq_afterpay_params.i18n.error_generic);
            return;
        }

        // Check amount limits
        const total = parseFloat(getCartTotal());
        if (total < fkwcsq_afterpay_params.min_amount) {
            showError(fkwcsq_afterpay_params.i18n.amount_too_low);
            return;
        }
        if (total > fkwcsq_afterpay_params.max_amount) {
            showError(fkwcsq_afterpay_params.i18n.amount_too_high);
            return;
        }

        try {
            // Initialize Square payments
            if (!payments) {
                payments = await Square.payments(
                    fkwcsq_afterpay_params.application_id,
                    fkwcsq_afterpay_params.location_id
                );
            }

            // Build payment request
            const paymentRequest = buildPaymentRequest(payments);

            // Create Afterpay instance
            afterpay = await payments.afterpayClearpay(paymentRequest);

            // Attach button to the wrapper container
            await afterpay.attach('#fkwcsq-afterpay-button-container', {
                buttonColor: getButtonColor(),
                buttonType: getButtonType()
            });

            // Attach messaging if enabled (wrap in separate try-catch to not break button)
            if (fkwcsq_afterpay_params.show_messaging) {
                const messagingContainer = document.getElementById('fkwcsq-afterpay-messaging-container');
                if (messagingContainer) {
                    try {
                        await afterpay.attachMessaging('#fkwcsq-afterpay-messaging-container', {
                            amount: getCartTotal(),
                            currency: fkwcsq_afterpay_params.currency_code
                        });
                    } catch (messagingError) {
                        // Messaging may not be available in sandbox or for certain accounts
                        console.warn('Afterpay messaging not available:', messagingError.message);
                    }
                }
            }

            // Mark as initialized
            isInitialized = true;
            isInitializing = false;
            hideError();

        } catch (error) {


            if (error.name === 'AfterpayMerchantError') {
                showError(fkwcsq_afterpay_params.i18n.not_supported);
            } else if (error.name === 'AfterpayAmountOutsideLimitsError') {
                const total = parseFloat(getCartTotal());
                if (total < fkwcsq_afterpay_params.min_amount) {
                    showError(fkwcsq_afterpay_params.i18n.amount_too_low);
                } else {
                    showError(fkwcsq_afterpay_params.i18n.amount_too_high);
                }
            } else if (error.name === 'UnexpectedError') {
                // UnexpectedError usually means Afterpay is not available at this location
                // or the Square account is not properly configured for Afterpay
                console.error('Afterpay UnexpectedError - This usually indicates Afterpay is not enabled for this Square location');
                showError('Afterpay is not available. Please ensure your Square account has Afterpay enabled.');
            } else {
                showError(fkwcsq_afterpay_params.i18n.error_generic);
            }

            isInitializing = false;
        }
    }

    /**
     * Get button color based on theme setting
     *
     * @returns {string} Button color
     */
    function getButtonColor() {
        const themeMap = {
            black_on_mint: 'black',
            white_on_black: 'white',
            black_on_white: 'black',
            mint_on_black: 'mint'
        };
        return themeMap[fkwcsq_afterpay_params.button_theme] || 'black';
    }

    /**
     * Get button type based on setting
     *
     * @returns {string} Button type
     */
    function getButtonType() {
        return fkwcsq_afterpay_params.button_type || 'buy_now_with_afterpay';
    }

    /**
     * Handle Afterpay button click - triggers tokenization
     *
     * @param {Event} e Click event
     */
    async function handleAfterpayButtonClick(e) {
        e.preventDefault();
        e.stopPropagation();

        if (isProcessing || !afterpay) {
            return;
        }

        // Check if we already have a nonce
        if ($('#fkwcsq_afterpay_nonce').val()) {
            // Already have token, trigger place order
            $('body').removeClass('fkwcsq-afterpay-selected');
            $('form.checkout #place_order').trigger('click');
            return;
        }

        isProcessing = true;
        hideError();

        try {
            // Tokenize - payment request was set during initialization
            const result = await afterpay.tokenize();

            if (result.status === 'OK') {
                // Store the token
                $('#fkwcsq_afterpay_nonce').val(result.token);
                isProcessing = false;

                // Remove body class to show Place Order button
                $('body').removeClass('fkwcsq-afterpay-selected');

                // Trigger Place Order button click to run WooCommerce checkout AJAX
                $('form.checkout #place_order').trigger('click');
            } else if (result.status === 'Cancel') {
                // User cancelled - don't show error
                isProcessing = false;
            } else {
                // Error occurred
                const errorMessage = result.errors && result.errors[0]
                    ? result.errors[0].message
                    : fkwcsq_afterpay_params.i18n.error_generic;
                showError(errorMessage);
                isProcessing = false;
            }

        } catch (error) {
            console.error('Afterpay payment error:', error);
            showError(error.message || fkwcsq_afterpay_params.i18n.error_generic);
            isProcessing = false;
        }
    }

    /**
     * Handle form submission - validate Afterpay payment was completed
     *
     * When Afterpay is selected, user must click the Afterpay button to complete payment.
     * After successful tokenization, this handler allows form submission.
     *
     * @returns {boolean} Whether to proceed with submission
     */
    function handleFormSubmit() {
        // If we already have a nonce, proceed with form submission
        if ($('#fkwcsq_afterpay_nonce').val()) {
            return true;
        }

        // User must click Afterpay button to complete payment
        const brand = fkwcsq_afterpay_params.is_clearpay ? 'Clearpay' : 'Afterpay';
        showError('Please click the ' + brand + ' button to complete your payment.');
        return false;
    }

    /**
     * Show error message
     *
     * @param {string} message Error message
     */
    function showError(message) {
        $('#fkwcsq-afterpay-error')
            .text(message)
            .show();
    }

    /**
     * Hide error message
     */
    function hideError() {
        $('#fkwcsq-afterpay-error').hide();
    }

    /**
     * Destroy Afterpay instance and clear containers
     */
    async function destroyAfterpay() {
        if (afterpay) {
            try {
                await afterpay.destroy();
            } catch (error) {
                // Silently handle - instance may already be destroyed
            }
            afterpay = null;
        }

        // Always reset state
        isInitialized = false;
        isInitializing = false;

        // Clear containers to prevent duplicates on reinit
        $('#fkwcsq-afterpay-messaging-container').empty();
        $('#fkwcsq-afterpay-button-container').empty();

        // Remove any stray afterpay-placement elements (SDK adds them as siblings, not children)
        $('#fkwcsq-afterpay-container afterpay-placement').remove();
        $('#fkwcsq-afterpay-button-wrapper afterpay-placement').remove();
    }

    /**
     * Handle payment method change
     */
    async function handlePaymentMethodChange() {
        // Toggle button visibility based on selection
        toggleButtons();

        const selectedPayment = $('input[name="payment_method"]:checked').val();

        if (selectedPayment === 'fkwcsq_afterpay') {
            // Always destroy and clear before reinitializing (handles null case internally)
            await destroyAfterpay();
            initializeAfterpay();
        } else if (afterpay) {
            // Destroy when switching away from Afterpay to clean up
            await destroyAfterpay();
        }
    }

    /**
     * Initialize when document is ready
     */
    $(document).ready(function () {
        // Check if Afterpay params are available
        if (typeof fkwcsq_afterpay_params === 'undefined') {
            return;
        }

        // Initial button visibility toggle
        toggleButtons();

        // Initialize if Afterpay is the selected payment method
        const selectedPayment = $('input[name="payment_method"]:checked').val();
        if (selectedPayment === 'fkwcsq_afterpay') {
            initializeAfterpay();
        }

        // Handle payment method change
        $(document.body).on('change', 'input[name="payment_method"]', handlePaymentMethodChange);

        // Validate before form submission
        $('form.checkout').on('checkout_place_order_fkwcsq_afterpay', handleFormSubmit);

        // Handle Afterpay button click - triggers tokenization
        $(document.body).on('click', '#fkwcsq-afterpay-button-container', handleAfterpayButtonClick);

        // Handle FunnelKit checkout initialization
        $(document.body).on('init_checkout', async function () {
            // Toggle button visibility after checkout init
            toggleButtons();

            const selectedPayment = $('input[name="payment_method"]:checked').val();
            if (selectedPayment === 'fkwcsq_afterpay') {
                initializeAfterpay();
            }
        });
        // Reinitialize on checkout update
        $(document.body).on('updated_checkout', async function (_e, data) {
            // Capture payment request data from fragments
            if (data && data.fragments && data.fragments.fkwcsq_payment_request) {
                paymentRequestData = data.fragments.fkwcsq_payment_request;
            }

            // Toggle button visibility after checkout update
            toggleButtons();

            const selectedPayment = $('input[name="payment_method"]:checked').val();
            if (selectedPayment === 'fkwcsq_afterpay') {
                // Properly destroy previous instance before reinitializing
                await destroyAfterpay();
                initializeAfterpay();
            }
        });
    });

    // Cleanup on page unload
    $(window).on('unload', destroyAfterpay);

})(jQuery);
