/**
 * Stripe Payment Element Integration
 *
 * Handles Stripe Payment Element for GGM Commerce checkout.
 * Initializes the Payment Element immediately on page load for better UX.
 *
 * @package GGM_Commerce
 */

(function($) {
    'use strict';

    // Stripe instance and elements
    let stripe = null;
    let elements = null;
    let paymentElement = null;
    let clientSecret = null;
    let paymentIntentId = null;
    let orderId = null;
    let isInitialized = false;

    /**
     * Initialize Stripe when the page loads.
     */
    function init() {
        // Skip initialization on order confirmation page (has order_id + key but NOT stripe_confirm)
        const urlParams = new URLSearchParams(window.location.search);
        if (urlParams.has('order_id') && urlParams.has('key') && !urlParams.has('stripe_confirm')) {
            // We're on the Thank You/Order Confirmation view, not checkout
            return;
        }

        if (typeof ggmcStripe === 'undefined' || !ggmcStripe.publishableKey) {
            console.warn('GGM Commerce: Stripe configuration not found.');
            return;
        }

        // Initialize Stripe
        stripe = Stripe(ggmcStripe.publishableKey, {
            locale: ggmcStripe.locale || 'auto'
        });

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

        // Listen for order creation - this is when we confirm the Stripe payment
        $(document).on('ggm_commerce_order_created', handleOrderCreated);

        // Listen for checkout form about to submit (before AJAX)
        // We need to intercept to ensure Stripe payment is ready
        $(document).on('ggm_commerce_before_checkout', handleBeforeCheckout);

        // Check if Stripe is already selected and initialize immediately
        if ($('input[name="payment_method"]:checked').val() === 'stripe') {
            showStripeElement();
            initializePaymentElementFromCart();
        }
    }

    /**
     * Handle payment method selection change.
     *
     * @param {Event} e Change event.
     */
    function handlePaymentMethodChange(e) {
        const method = $(e.target).val();

        if (method === 'stripe') {
            showStripeElement();
            if (!isInitialized) {
                initializePaymentElementFromCart();
            }
        } else {
            hideStripeElement();
        }
    }

    /**
     * Show Stripe Payment Element container.
     */
    function showStripeElement() {
        $('#ggmc-stripe-payment-element').show();
        $('#ggmc-paypal-button-container').hide();
    }

    /**
     * Hide Stripe Payment Element container.
     */
    function hideStripeElement() {
        $('#ggmc-stripe-payment-element').hide();
    }

    /**
     * Initialize Payment Element from cart total.
     * This creates a PaymentIntent immediately so the card form appears.
     */
    async function initializePaymentElementFromCart() {
        if (isInitialized) {
            return;
        }

        // Get cart total from the checkout page
        const cartTotal = getCartTotal();

        if (!cartTotal || cartTotal <= 0) {
            console.warn('GGM Commerce: No valid cart total found.');
            return;
        }

        try {
            // Create a PaymentIntent from the cart total
            const response = await fetch(ggmcStripe.createCartIntentUrl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-GGMC-Payment-Nonce': ggmcStripe.nonce || '',
                    'X-WP-Nonce': ggmcStripe.restNonce || ''
                },
                body: JSON.stringify({
                    amount: cartTotal,
                    currency: ggmcStripe.currency || 'GBP',
                    nonce: ggmcStripe.nonce || ''
                })
            });

            const result = await response.json();

            if (result.success && result.client_secret) {
                clientSecret = result.client_secret;
                paymentIntentId = result.payment_intent_id;
                initializePaymentElement();
            } else {
                // Extract error message from nested structure
                const errorMessage = result.error?.message || result.error || result.message || 'Failed to initialize payment form.';
                console.error('GGM Commerce: Failed to create PaymentIntent:', errorMessage, result);
                showError(errorMessage);
            }
        } catch (err) {
            console.error('GGM Commerce: Error creating PaymentIntent:', err);
            showError('Failed to initialize payment form. Please refresh the page.');
        }
    }

    /**
     * Get the cart total from the checkout page.
     *
     * @returns {number|null} Cart total or null if not found.
     */
    function getCartTotal() {
        // Try to get from data attribute on checkout form
        const formTotal = $('#ggmc-checkout-form').data('cart-total');
        if (formTotal) {
            return parseFloat(formTotal);
        }

        // Try to get from localized script data
        if (ggmcStripe.cartTotal) {
            return parseFloat(ggmcStripe.cartTotal);
        }

        // Try to get from order summary total element
        const totalElement = $('.ggmc-order-total-value, .order-total-value, [data-cart-total]');
        if (totalElement.length) {
            const totalText = totalElement.data('cart-total') || totalElement.text();
            // Remove currency symbols and parse
            const numericTotal = parseFloat(totalText.replace(/[^0-9.]/g, ''));
            if (!isNaN(numericTotal)) {
                return numericTotal;
            }
        }

        return null;
    }

    /**
     * Handle before checkout event - validate Stripe is ready.
     *
     * @param {Event} e Event.
     * @param {Object} data Checkout data.
     * @returns {boolean} Whether to proceed with checkout.
     */
    function handleBeforeCheckout(e, data) {
        const selectedMethod = $('input[name="payment_method"]:checked').val();

        if (selectedMethod !== 'stripe') {
            return true;
        }

        // Ensure Stripe is initialized
        if (!elements || !paymentElement || !clientSecret) {
            showError('Payment form not initialized. Please refresh the page.');
            return false;
        }

        return true;
    }

    /**
     * Handle order created event - confirm the Stripe payment.
     *
     * @param {Event} e Event.
     * @param {Object} data Order data from server.
     */
    async function handleOrderCreated(e, data) {
        if (data.payment_method !== 'stripe') {
            return;
        }

        orderId = data.order_id;

        if (!elements || !paymentElement || !clientSecret) {
            showError('Payment form not initialized. Please refresh the page.');
            return;
        }

        setLoading(true);

        try {
            // First update the PaymentIntent with order info
            if (paymentIntentId && data.order_id) {
                await updatePaymentIntentWithOrder(data.order_id, data.order_number, data.total);
            }

            // Now confirm the payment
            const { error, paymentIntent } = await stripe.confirmPayment({
                elements,
                confirmParams: {
                    return_url: ggmcStripe.returnUrl + '&order_id=' + data.order_id,
                    payment_method_data: {
                        billing_details: getBillingDetails()
                    }
                },
                redirect: 'if_required'
            });

            if (error) {
                // Show error to customer
                if (error.type === 'card_error' || error.type === 'validation_error') {
                    showError(error.message);
                } else {
                    showError(ggmcStripe.i18n?.error || 'An unexpected error occurred.');
                }
                setLoading(false);
                return;
            }

            // Payment succeeded without redirect
            if (paymentIntent && paymentIntent.status === 'succeeded') {
                handlePaymentSuccess(paymentIntent);
            } else if (paymentIntent && paymentIntent.status === 'requires_action') {
                // Handle 3D Secure - the redirect: 'if_required' should handle this
                // If we get here, the redirect will happen automatically
            }

        } catch (err) {
            console.error('Stripe payment error:', err);
            showError(ggmcStripe.i18n?.error || 'An unexpected error occurred.');
            setLoading(false);
        }
    }

    /**
     * Update PaymentIntent with order information.
     *
     * @param {number} orderIdParam Order ID.
     * @param {string} orderNumber Order number.
     * @param {number} total Order total.
     */
    async function updatePaymentIntentWithOrder(orderIdParam, orderNumber, total) {
        if (!paymentIntentId) {
            return;
        }

        try {
            await fetch(ggmcStripe.updateIntentUrl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-GGMC-Payment-Nonce': ggmcStripe.nonce || '',
                    'X-WP-Nonce': ggmcStripe.restNonce || ''
                },
                body: JSON.stringify({
                    payment_intent_id: paymentIntentId,
                    amount: total,
                    order_id: orderIdParam,
                    order_number: orderNumber,
                    nonce: ggmcStripe.nonce || ''
                })
            });
        } catch (err) {
            console.warn('GGM Commerce: Failed to update PaymentIntent with order:', err);
        }
    }

    /**
     * Initialize the Stripe Payment Element.
     */
    function initializePaymentElement() {
        if (!clientSecret || !stripe) {
            console.error('GGM Commerce: Cannot initialize Payment Element - missing configuration.');
            return;
        }

        const container = document.getElementById('ggmc-stripe-payment-element');
        if (!container) {
            console.error('GGM Commerce: Payment Element container not found.');
            return;
        }

        // Create Elements instance with the client secret
        elements = stripe.elements({
            clientSecret: clientSecret,
            appearance: getAppearance()
        });

        // Create and mount the Payment Element
        const paymentElementOptions = {
            layout: 'tabs',
            defaultValues: {
                billingDetails: getBillingDetails()
            }
        };

        // Filter payment methods based on settings
        if (ggmcStripe.paymentMethods) {
            paymentElementOptions.paymentMethodOrder = ggmcStripe.paymentMethods;
        }

        paymentElement = elements.create('payment', paymentElementOptions);
        paymentElement.mount('#ggmc-stripe-payment-element');

        // Handle element ready
        paymentElement.on('ready', function() {
            $('#ggmc-stripe-payment-element').addClass('ggmc-stripe-ready');
            isInitialized = true;
        });

        // Handle element change for validation
        paymentElement.on('change', function(event) {
            const messageEl = $('#ggmc-stripe-payment-message');

            if (event.error) {
                messageEl.text(event.error.message).show();
            } else {
                messageEl.hide();
            }
        });
    }

    /**
     * Get Stripe Elements appearance configuration.
     *
     * @returns {Object} Appearance object.
     */
    function getAppearance() {
        return {
            theme: 'stripe',
            variables: {
                colorPrimary: '#2563eb',
                colorBackground: '#ffffff',
                colorText: '#1e293b',
                colorDanger: '#dc2626',
                fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
                spacingUnit: '4px',
                borderRadius: '6px'
            },
            rules: {
                '.Input': {
                    border: '1px solid #e2e8f0',
                    boxShadow: 'none'
                },
                '.Input:focus': {
                    border: '1px solid #2563eb',
                    boxShadow: '0 0 0 3px rgba(37, 99, 235, 0.1)'
                },
                '.Input--invalid': {
                    border: '1px solid #dc2626'
                },
                '.Label': {
                    fontWeight: '500',
                    marginBottom: '6px'
                }
            }
        };
    }

    /**
     * Get billing details from checkout form.
     *
     * @returns {Object} Billing details object.
     */
    function getBillingDetails() {
        const form = $('#ggmc-checkout-form');

        return {
            name: (form.find('[name="customer[first_name]"]').val() || '') + ' ' +
                  (form.find('[name="customer[last_name]"]').val() || ''),
            email: form.find('[name="customer[email]"]').val() || '',
            phone: form.find('[name="customer[phone]"]').val() || '',
            address: {
                line1: form.find('[name="customer[billing_address_1]"]').val() || '',
                line2: form.find('[name="customer[billing_address_2]"]').val() || '',
                city: form.find('[name="customer[billing_city]"]').val() || '',
                state: form.find('[name="customer[billing_state]"]').val() || '',
                postal_code: form.find('[name="customer[billing_postcode]"]').val() || '',
                country: form.find('[name="customer[billing_country]"]').val() || ''
            }
        };
    }

    /**
     * Handle successful payment.
     *
     * @param {Object} paymentIntent The PaymentIntent object.
     */
    function handlePaymentSuccess(paymentIntent) {
        // Trigger success event
        $(document).trigger('ggm_commerce_payment_success', {
            gateway: 'stripe',
            order_id: orderId,
            transaction_id: paymentIntent.id
        });

        // Confirm payment on server
        confirmPaymentOnServer(paymentIntent.id);
    }

    /**
     * Confirm payment on server.
     *
     * @param {string} paymentIntentId Payment Intent ID.
     */
    function confirmPaymentOnServer(paymentIntentId) {
        $.ajax({
            url: ggmcStripe.confirmUrl,
            method: 'POST',
            headers: {
                'X-GGMC-Payment-Nonce': ggmcStripe.nonce || '',
                'X-WP-Nonce': ggmcStripe.restNonce || ''
            },
            data: {
                payment_intent_id: paymentIntentId,
                order_id: orderId,
                nonce: ggmcStripe.nonce || ''
            },
            success: function(response) {
                if (response.success) {
                    // Redirect to confirmation page or show success
                    $(document).trigger('ggm_commerce_order_complete', {
                        order_id: orderId,
                        gateway: 'stripe'
                    });
                } else {
                    showError(response.error || 'Payment confirmation failed.');
                }
                setLoading(false);
            },
            error: function(xhr, status, error) {
                console.error('Payment confirmation error:', error);
                // Payment succeeded but confirmation failed - still show success
                // The webhook will handle the order update
                $(document).trigger('ggm_commerce_order_complete', {
                    order_id: orderId,
                    gateway: 'stripe'
                });
                setLoading(false);
            }
        });
    }

    /**
     * Show error message.
     *
     * @param {string} message Error message.
     */
    function showError(message) {
        const messageEl = $('#ggmc-stripe-payment-message');
        messageEl.html('<p class="ggmc-payment-error">' + message + '</p>').show();

        // Scroll to error
        $('html, body').animate({
            scrollTop: messageEl.offset().top - 100
        }, 300);
    }

    /**
     * Set loading state.
     *
     * @param {boolean} isLoading Whether loading.
     */
    function setLoading(isLoading) {
        const submitBtn = $('#ggmc-checkout-form').find('button[type="submit"], input[type="submit"]');

        if (isLoading) {
            submitBtn.prop('disabled', true).addClass('ggmc-loading');
            submitBtn.data('original-text', submitBtn.text());
            submitBtn.text(ggmcStripe.i18n?.processing || 'Processing...');
        } else {
            submitBtn.prop('disabled', false).removeClass('ggmc-loading');
            submitBtn.text(submitBtn.data('original-text') || 'Place Order');
        }
    }

    /**
     * Handle return from 3D Secure redirect.
     */
    function handleRedirectReturn() {
        const urlParams = new URLSearchParams(window.location.search);

        // Skip on order confirmation page (has order_id + key but NOT stripe_confirm)
        if (urlParams.has('order_id') && urlParams.has('key') && !urlParams.has('stripe_confirm')) {
            return;
        }

        if (urlParams.has('payment_intent') && urlParams.has('stripe_confirm')) {
            const paymentIntentId = urlParams.get('payment_intent');
            const redirectStatus = urlParams.get('redirect_status');

            // Extract order_id from URL params (added during redirect)
            const urlOrderId = urlParams.get('order_id');
            if (urlOrderId) {
                orderId = parseInt(urlOrderId, 10);
            }

            if (redirectStatus === 'succeeded') {
                // Payment succeeded after redirect
                setLoading(true);
                confirmPaymentOnServer(paymentIntentId);
            } else if (redirectStatus === 'failed') {
                showError('Payment failed. Please try again.');
            }

            // Clean up URL
            window.history.replaceState({}, document.title, window.location.pathname);
        }
    }

    // Expose functions for external use
    window.ggmcStripePayment = {
        init: init,
        initializePaymentElement: initializePaymentElementFromCart,
        updateAmount: updatePaymentIntentWithOrder
    };

    // Initialize on document ready
    $(document).ready(function() {
        init();
        handleRedirectReturn();
    });

})(jQuery);
