/**
 * PayPal Smart Payment Buttons Integration
 *
 * Handles PayPal payment buttons for GGM Commerce checkout.
 *
 * @package GGM_Commerce
 */

(function($) {
    'use strict';

    // State
    let orderId = null;
    let buttonsRendered = false;

    /**
     * Initialize PayPal when the page loads.
     */
    function init() {
        if (typeof ggmcPayPal === 'undefined' || !ggmcPayPal.clientId) {
            console.warn('GGM Commerce: PayPal configuration not found.');
            return;
        }

        // Wait for PayPal SDK to load
        if (typeof paypal === 'undefined') {
            setTimeout(init, 100);
            return;
        }

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

        // Listen for order creation
        $(document).on('ggm_commerce_order_created', handleOrderCreated);

        // Check if PayPal is already selected
        if ($('input[name="payment_method"]:checked').val() === 'paypal') {
            showPayPalButtons();
        }
    }

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

        if (method === 'paypal') {
            showPayPalButtons();
        } else {
            hidePayPalButtons();
        }
    }

    /**
     * Show PayPal buttons container.
     */
    function showPayPalButtons() {
        $('#ggmc-paypal-button-container').show();
        $('#ggmc-stripe-payment-element').hide();

        if (!buttonsRendered) {
            renderPayPalButtons();
        }
    }

    /**
     * Hide PayPal buttons container.
     */
    function hidePayPalButtons() {
        $('#ggmc-paypal-button-container').hide();
    }

    /**
     * Handle order created event.
     *
     * @param {Event} e Event.
     * @param {Object} data Order data from server.
     */
    function handleOrderCreated(e, data) {
        if (data.payment_method !== 'paypal') {
            return;
        }

        orderId = data.order_id;

        // Re-render buttons if needed
        if (!buttonsRendered) {
            renderPayPalButtons();
        }
    }

    /**
     * Render PayPal Smart Payment Buttons.
     */
    function renderPayPalButtons() {
        const container = document.getElementById('ggmc-paypal-button-container');

        if (!container || buttonsRendered) {
            return;
        }

        // Get button style from data attributes or config
        const buttonStyle = getButtonStyle();

        try {
            paypal.Buttons({
                style: buttonStyle,

                /**
                 * Create PayPal order when button is clicked.
                 *
                 * @returns {Promise<string>} PayPal order ID.
                 */
                createOrder: async function(data, actions) {
                    // First, submit the checkout form to create GGM order
                    if (!orderId) {
                        orderId = await createGGMOrder();
                    }

                    if (!orderId) {
                        throw new Error('Failed to create order');
                    }

                    // Create PayPal order
                    const response = await fetch(ggmcPayPal.createOrderUrl, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'X-GGMC-Payment-Nonce': ggmcPayPal.nonce || '',
                            'X-WP-Nonce': ggmcPayPal.restNonce || ''
                        },
                        body: JSON.stringify({
                            order_id: orderId,
                            nonce: ggmcPayPal.nonce || ''
                        })
                    });

                    const result = await response.json();

                    if (!result.success || !result.paypal_order_id) {
                        throw new Error(result.error || 'Failed to create PayPal order');
                    }

                    return result.paypal_order_id;
                },

                /**
                 * Handle approved payment.
                 *
                 * @param {Object} data Approval data containing orderID.
                 * @param {Object} actions PayPal actions.
                 */
                onApprove: async function(data, actions) {
                    setLoading(true);
                    hideError();

                    try {
                        // Capture the payment
                        const response = await fetch(ggmcPayPal.captureUrl, {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                                'X-GGMC-Payment-Nonce': ggmcPayPal.nonce || '',
                                'X-WP-Nonce': ggmcPayPal.restNonce || ''
                            },
                            body: JSON.stringify({
                                paypal_order_id: data.orderID,
                                order_id: orderId,
                                nonce: ggmcPayPal.nonce || ''
                            })
                        });

                        const result = await response.json();

                        if (result.success) {
                            handlePaymentSuccess(result);
                        } else {
                            showError(result.error || 'Payment capture failed');
                        }
                    } catch (err) {
                        console.error('PayPal capture error:', err);
                        showError(ggmcPayPal.i18n?.error || 'An error occurred. Please try again.');
                    } finally {
                        setLoading(false);
                    }
                },

                /**
                 * Handle payment cancellation.
                 */
                onCancel: function(data) {
                    // User cancelled - no need to show error
                },

                /**
                 * Handle errors.
                 *
                 * @param {Error} err Error object.
                 */
                onError: function(err) {
                    console.error('PayPal error:', err);
                    showError(ggmcPayPal.i18n?.error || 'An error occurred with PayPal. Please try again.');
                }
            }).render('#ggmc-paypal-button-container');

            buttonsRendered = true;

        } catch (err) {
            console.error('Failed to render PayPal buttons:', err);
            showError('Failed to initialize PayPal. Please refresh the page.');
        }
    }

    /**
     * Get button style configuration.
     *
     * @returns {Object} Button style object.
     */
    function getButtonStyle() {
        const container = document.getElementById('ggmc-paypal-button-container');
        const config = ggmcPayPal.buttonStyle || {};

        return {
            layout: container?.dataset?.layout || config.layout || 'vertical',
            color: container?.dataset?.color || config.color || 'gold',
            shape: container?.dataset?.shape || config.shape || 'rect',
            label: container?.dataset?.label || config.label || 'paypal',
            height: 45
        };
    }

    /**
     * Create GGM Commerce order via checkout form submission.
     *
     * @returns {Promise<number|null>} Order ID or null on failure.
     */
    async function createGGMOrder() {
        return new Promise((resolve, reject) => {
            const form = $('#ggmc-checkout-form');

            if (!form.length) {
                reject(new Error('Checkout form not found'));
                return;
            }

            // Validate form
            if (!form[0].checkValidity()) {
                form[0].reportValidity();
                reject(new Error('Please fill in all required fields'));
                return;
            }

            // Collect form data
            const formData = new FormData(form[0]);
            formData.append('action', 'ggm_commerce_create_order');
            formData.append('payment_method', 'paypal');
            // Use the checkout nonce from localized data (freshly generated by PHP)
            formData.append('nonce', ggmcPayPal.checkoutNonce || '');

            // Add cart items from localized data (since they're not in the form)
            if (ggmcPayPal.cartItems && Array.isArray(ggmcPayPal.cartItems)) {
                ggmcPayPal.cartItems.forEach(function(item, index) {
                    formData.append('cart_items[' + index + '][product_id]', item.product_id);
                    formData.append('cart_items[' + index + '][quantity]', item.quantity);
                });
            }

            // Submit order
            $.ajax({
                url: ggmcPayPal.ajaxUrl || '/wp-admin/admin-ajax.php',
                method: 'POST',
                data: formData,
                processData: false,
                contentType: false,
                success: function(response) {
                    // Response structure: { success: true, data: { message: '...', order: { order_id: 123, order_number: '...', ... } } }
                    if (response.success && response.data && response.data.order && response.data.order.order_id) {
                        orderId = response.data.order.order_id;
                        resolve(response.data.order.order_id);
                    } else {
                        showError(response.data?.message || 'Failed to create order');
                        reject(new Error(response.data?.message || 'Order creation failed'));
                    }
                },
                error: function(xhr, status, error) {
                    showError('Network error. Please try again.');
                    reject(new Error(error));
                }
            });
        });
    }

    /**
     * Handle successful payment.
     *
     * @param {Object} result Capture result.
     */
    function handlePaymentSuccess(result) {
        // Trigger success event
        $(document).trigger('ggm_commerce_payment_success', {
            gateway: 'paypal',
            order_id: orderId,
            transaction_id: result.transaction_id
        });

        // Trigger order complete
        $(document).trigger('ggm_commerce_order_complete', {
            order_id: orderId,
            gateway: 'paypal'
        });
    }

    /**
     * Show error message.
     *
     * @param {string} message Error message.
     */
    function showError(message) {
        const messageEl = $('#ggmc-paypal-payment-message');
        messageEl.html('<p class="ggmc-payment-error" style="color: #dc2626; padding: 10px; background: #fef2f2; border-radius: 4px;">' + message + '</p>').show();

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

    /**
     * Hide error message.
     */
    function hideError() {
        $('#ggmc-paypal-payment-message').hide().empty();
    }

    /**
     * Set loading state.
     *
     * @param {boolean} isLoading Whether loading.
     */
    function setLoading(isLoading) {
        const container = $('#ggmc-paypal-button-container');

        if (isLoading) {
            container.addClass('ggmc-loading');
            container.append('<div class="ggmc-loading-overlay" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(255,255,255,0.8); display: flex; align-items: center; justify-content: center;"><span>' + (ggmcPayPal.i18n?.processing || 'Processing...') + '</span></div>');
        } else {
            container.removeClass('ggmc-loading');
            container.find('.ggmc-loading-overlay').remove();
        }
    }

    /**
     * Reset PayPal state (for retrying).
     */
    function reset() {
        orderId = null;
        hideError();
    }

    // Expose functions for external use
    window.ggmcPayPalPayment = {
        init: init,
        reset: reset,
        showButtons: showPayPalButtons,
        hideButtons: hidePayPalButtons
    };

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

})(jQuery);
