/* global Square, fkwcsq_cash_app_params */

/**
 * FunnelKit Square Cash App Handler
 *
 * Handles Square Cash App Pay initialization and tokenization.
 *
 * Note: Cash App Pay does NOT support programmatic tokenization like Afterpay.
 * Users must click the Cash App button to initiate payment. The token is
 * received via the 'ontokenization' event listener after user completes
 * the Cash App flow.
 *
 * @package FunnelKit_Square
 */

(function ($) {
    'use strict';

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

    /**
     * Initialize the Cash App handler
     */
    function init() {
        // Handle checkout update
        $(document.body).on('updated_checkout', handleCheckoutUpdate);

        // Handle FunnelKit checkout initialization
        $(document.body).on('init_checkout', function () {
            toggleButtons();
            maybeInitializeCashApp();
        });

        // Handle payment method change - use immediate toggle
        $(document.body).on('change', 'input[name="payment_method"]', function () {
            toggleButtons();
            maybeInitializeCashApp();
        });

        // Handle form submission
        $('form.checkout').on('checkout_place_order_fkwcsq_cash_app', handleFormSubmit);

        // Initial setup
        toggleButtons();
        maybeInitializeCashApp();
    }

    /**
     * Toggle Place Order / Cash App button visibility using body class
     */
    function toggleButtons() {
        const selectedPayment = $('input[name="payment_method"]:checked').val();

        if (selectedPayment === 'fkwcsq_cash_app') {
            // Add body class to hide Place Order and show Cash App button via CSS
            $('body').addClass('fkwcsq-cash-app-selected');
        } else {
            // Remove body class to show Place Order and hide Cash App button
            $('body').removeClass('fkwcsq-cash-app-selected');
        }
    }

    /**
     * Initialize Cash App if selected and not already initialized
     */
    async function maybeInitializeCashApp() {
        const selectedPayment = $('input[name="payment_method"]:checked').val();

        if (selectedPayment === 'fkwcsq_cash_app' && !isInitialized) {
            await initializeCashApp();
        }
    }

    /**
     * Handle checkout update - capture payment request data and reinitialize
     *
     * @param {Event} _e Event object
     * @param {Object} data Checkout update data containing fragments
     */
    async function handleCheckoutUpdate(_e, data) {
        // Capture payment request data from fragments
        if (data && data.fragments && data.fragments.fkwcsq_payment_request) {
            paymentRequestData = data.fragments.fkwcsq_payment_request;
        }

        // Toggle buttons immediately after checkout update (DOM may have changed)
        toggleButtons();

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

            // Toggle again after initialization in case DOM changed
            toggleButtons();
        }
    }

    /**
     * Get cart total from payment request data
     *
     * @returns {string} Cart total
     */
    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_cash_app_params.payment_request && fkwcsq_cash_app_params.payment_request.total) {
            return fkwcsq_cash_app_params.payment_request.total.amount;
        }

        return '0.00';
    }

    /**
     * Initialize Square Cash App Pay
     */
    async function initializeCashApp() {
        const container = document.getElementById('fkwcsq-cash-app-container');

        // Check if container exists
        if (!container) {
            return;
        }

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

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

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

            // Build payment request
            const paymentRequest = payments.paymentRequest({
                countryCode: fkwcsq_cash_app_params.country_code,
                currencyCode: fkwcsq_cash_app_params.currency_code,
                total: {
                    amount: getCartTotal(),
                    label: 'Total'
                }
            });

            // Create Cash App Pay instance
            cashAppPay = await payments.cashAppPay(paymentRequest, {
                redirectURL: fkwcsq_cash_app_params.checkout_url
            });

            // Attach to container
            await cashAppPay.attach('#fkwcsq-cash-app-container', {
                size: 'medium',
                width: 'full'
            });

            // Mark as initialized
            isInitialized = true;

            // Clear any previous error messages
            hideError();

            // Listen for tokenization events (fires when user completes Cash App flow)
            cashAppPay.addEventListener('ontokenization', handleTokenization);

        } catch (error) {
            console.error('Cash App initialization error:', error);

            // Cash App may not be available in this region/browser
            if (error.message && error.message.includes('not supported')) {
                showError(fkwcsq_cash_app_params.i18n.not_supported);
            } else {
                showError(fkwcsq_cash_app_params.i18n.error_generic);
            }
        }
    }

    /**
     * Handle tokenization event from Cash App
     *
     * This fires when user clicks Cash App button and completes the flow.
     *
     * @param {Object} event Tokenization event
     */
    function handleTokenization(event) {
        const { tokenResult } = event.detail;

        if (tokenResult.status === 'OK') {
            // Set the nonce value
            $('#fkwcsq_cash_app_nonce').val(tokenResult.token);
            isProcessing = false;

            // Remove body class to show Place Order button, then trigger click
            $('body').removeClass('fkwcsq-cash-app-selected');
            $('#place_order').trigger('click');
        } else if (tokenResult.status === 'Cancel') {
            // User cancelled - don't show error
            isProcessing = false;
        } else {
            const errorMessage = tokenResult.errors && tokenResult.errors[0]
                ? tokenResult.errors[0].message
                : fkwcsq_cash_app_params.i18n.error_generic;

            showError(errorMessage);
            isProcessing = false;
        }
    }

    /**
     * Handle form submission
     *
     * Cash App does not support programmatic tokenization. User must click
     * the Cash App button first. If they click "Place Order" without a token,
     * we show an error message.
     *
     * @returns {boolean} Whether to proceed with submission
     */
    function handleFormSubmit() {
        // If we already have a nonce, proceed with form submission
        if ($('#fkwcsq_cash_app_nonce').val()) {
            return true;
        }

        // Cash App requires user to click the Cash App button
        // We cannot programmatically trigger tokenization
        showError('Please click the Cash App button to complete your payment.');
        return false;
    }

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

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

    /**
     * Destroy Cash App instance and clear containers
     */
    async function destroyCashApp() {
        if (cashAppPay) {
            try {
                await cashAppPay.destroy();
            } catch (error) {
                // Silently handle - instance may already be destroyed
            }
            cashAppPay = null;
            isInitialized = false;
        }
    }

    // Initialize on document ready
    $(document).ready(init);

    // Cleanup on page unload (use pagehide to avoid "Leave site?" dialog on Place Order)
    $(window).on('pagehide', destroyCashApp);

})(jQuery);
