<?php
// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}


// Add settings page
add_action('admin_menu', 'lucydream_add_settings_page');

function lucydream_add_settings_page() {
    add_options_page('LucyDream Payments Settings', 'LucyDream Payments', 'manage_options', 'lucydream-payments', 'lucydream_settings_page_callback');
}

function lucydream_settings_page_callback() {
    ?>
    <div class="wrap">
        <h1>LucyDream Payments Settings</h1>
        <form method="post" action="options.php">
            <?php
            settings_fields('lucydream_payments_settings');
            do_settings_sections('lucydream-payments');
            submit_button();
            ?>
        </form>
    </div>
    <?php
}

add_action('admin_init', 'lucydream_register_settings');

function lucydream_register_settings() {
    register_setting('lucydream_payments_settings', 'lucydream_paypal_env');
    register_setting('lucydream_payments_settings', 'lucydream_paypal_live_client_id');
    register_setting('lucydream_payments_settings', 'lucydream_paypal_live_secret');
    register_setting('lucydream_payments_settings', 'lucydream_paypal_sandbox_client_id');
    register_setting('lucydream_payments_settings', 'lucydream_paypal_sandbox_secret');
    register_setting('lucydream_payments_settings', 'lucydream_stripe_env');
    register_setting('lucydream_payments_settings', 'lucydream_stripe_live_publishable');
    register_setting('lucydream_payments_settings', 'lucydream_stripe_live_secret');
    register_setting('lucydream_payments_settings', 'lucydream_stripe_test_publishable');
    register_setting('lucydream_payments_settings', 'lucydream_stripe_test_secret');

    add_settings_section('lucydream_main_section', 'Main Settings', null, 'lucydream-payments');

    add_settings_field('lucydream_paypal_env', 'PayPal Environment', 'lucydream_select_field_callback', 'lucydream-payments', 'lucydream_main_section', ['id' => 'lucydream_paypal_env', 'options' => ['live' => 'Live', 'sandbox' => 'Sandbox']]);
    add_settings_field('lucydream_paypal_live_client_id', 'PayPal Live Client ID', 'lucydream_text_field_callback', 'lucydream-payments', 'lucydream_main_section', ['id' => 'lucydream_paypal_live_client_id']);
    add_settings_field('lucydream_paypal_live_secret', 'PayPal Live Secret', 'lucydream_text_field_callback', 'lucydream-payments', 'lucydream_main_section', ['id' => 'lucydream_paypal_live_secret']);
    add_settings_field('lucydream_paypal_sandbox_client_id', 'PayPal Sandbox Client ID', 'lucydream_text_field_callback', 'lucydream-payments', 'lucydream_main_section', ['id' => 'lucydream_paypal_sandbox_client_id']);
    add_settings_field('lucydream_paypal_sandbox_secret', 'PayPal Sandbox Secret', 'lucydream_text_field_callback', 'lucydream-payments', 'lucydream_main_section', ['id' => 'lucydream_paypal_sandbox_secret']);
    add_settings_field('lucydream_stripe_env', 'Stripe Environment', 'lucydream_select_field_callback', 'lucydream-payments', 'lucydream_main_section', ['id' => 'lucydream_stripe_env', 'options' => ['live' => 'Live', 'test' => 'Test']]);
    add_settings_field('lucydream_stripe_live_publishable', 'Stripe Live Publishable Key', 'lucydream_text_field_callback', 'lucydream-payments', 'lucydream_main_section', ['id' => 'lucydream_stripe_live_publishable']);
    add_settings_field('lucydream_stripe_live_secret', 'Stripe Live Secret Key', 'lucydream_text_field_callback', 'lucydream-payments', 'lucydream_main_section', ['id' => 'lucydream_stripe_live_secret']);
    add_settings_field('lucydream_stripe_test_publishable', 'Stripe Test Publishable Key', 'lucydream_text_field_callback', 'lucydream-payments', 'lucydream_main_section', ['id' => 'lucydream_stripe_test_publishable']);
    add_settings_field('lucydream_stripe_test_secret', 'Stripe Test Secret Key', 'lucydream_text_field_callback', 'lucydream-payments', 'lucydream_main_section', ['id' => 'lucydream_stripe_test_secret']);
}

function lucydream_text_field_callback($args) {
    $value = get_option($args['id']);
    echo '<input type="text" id="' . esc_attr($args['id']) . '" name="' . esc_attr($args['id']) . '" value="' . esc_attr($value) . '" class="regular-text">';
}

function lucydream_select_field_callback($args) {
    $value = get_option($args['id']);
    echo '<select id="' . esc_attr($args['id']) . '" name="' . esc_attr($args['id']) . '">';
    foreach ($args['options'] as $key => $label) {
        echo '<option value="' . esc_attr($key) . '"' . selected($value, $key, false) . '>' . esc_html($label) . '</option>';
    }
    echo '</select>';
}

// Register the shortcode
add_shortcode('payments_form', 'lucydream_payments_form_shortcode');

function lucydream_payments_form_shortcode($atts) {
    if (!is_user_logged_in()) {
        return '<div id="no-user-id-message" class="notice notice-warning">Please log in to your account to buy credits.</div>';
    }

    $current_user = wp_get_current_user();
    $user_id = $current_user->ID;
    $user_email = $current_user->user_email;

    $paypal_env = get_option('lucydream_paypal_env', 'live');
    $stripe_env = get_option('lucydream_stripe_env', 'live');
    $paypal_client_id = ($paypal_env === 'live') ? get_option('lucydream_paypal_live_client_id') : get_option('lucydream_paypal_sandbox_client_id');
    $stripe_publishable = ($stripe_env === 'live') ? get_option('lucydream_stripe_live_publishable') : get_option('lucydream_stripe_test_publishable');
    $paypal_sdk_domain = ($paypal_env === 'sandbox') ? 'sandbox.paypal' : 'paypal';
    $nonce = wp_create_nonce('lucydream_ajax');

    ob_start();
    ?>
    <style>
        #payment-status { margin-top: 20px; color: green; display: none; }
        #payment-error { margin-top: 20px; color: red; display: none; }
        #stripe-pay-button { margin-top: 10px; padding: 10px 20px; background: #6772e5; color: white; border: none; border-radius: 4px; cursor: pointer; display: none; }
        #stripe-pay-button:hover { background: #5469d4; }
        #stripe-pay-button:disabled { background: #ccc; cursor: not-allowed; }
        .payment-options { display: flex; gap: 10px; margin-bottom: 20px; }
        .payment-option { padding: 10px; border: 1px solid #ccc; border-radius: 4px; cursor: pointer; }
        .payment-option.selected { border-color: #007bff; background: #f0f8ff; }
        #credits-select { padding: 10px; border: 1px solid #ccc; border-radius: 4px; font-size: 16px; width: 150px; }
        .credits-selection { margin-bottom: 10px; }
        .contact-link { margin-top: 10px; font-size: 14px; }
        .contact-link a { color: #007bff; text-decoration: none; }
        .contact-link a:hover { text-decoration: underline; }
    </style>

    <h2>Buy Credits</h2>
    <div class="credits-selection">
        <p style="margin-bottom: 5px;">1 Credit = 1 USD</p>
        <select id="credits-select">
            <option value="1">1 Credit</option>
            <option value="5">5 Credits</option>
            <option value="10" selected>10 Credits</option>
            <option value="20">20 Credits</option>
        </select>
    </div>
    <div class="payment-options" id="payment-options" style="display: flex;">
        <div class="payment-option" onclick="selectPayment('paypal')">PayPal</div>
        <div class="payment-option" onclick="selectPayment('stripe')">Credit/Debit Card</div>
    </div>
    <div id="payment-container" style="display: none;"></div>
    <div id="payment-status"></div>
    <div id="payment-error"></div>

    <script>
        var currentUserId = <?php echo esc_js($user_id); ?>;
        var currentUserEmail = '<?php echo esc_js($user_email); ?>';
        var paypalClientId = '<?php echo esc_js($paypal_client_id); ?>';
        var stripePubKey = '<?php echo esc_js($stripe_publishable); ?>';
        var paypalSdkDomain = '<?php echo esc_js($paypal_sdk_domain); ?>';
        var ajaxNonce = '<?php echo esc_js($nonce); ?>';
        var ajaxUrl = '<?php echo esc_js(admin_url('admin-ajax.php')); ?>';
    </script>

    <script>
        // Global error handler to catch uncaught errors
        window.onerror = function(message, source, lineno, colno, error) {
            console.error('Global error:', message, 'at', source, lineno, colno, error);
            document.getElementById('payment-error').innerText = 'An unexpected error occurred. Please refresh the page or contact support.';
            document.getElementById('payment-error').style.display = 'block';
            return true;
        };

        function loadPayPalSDK() {
            return new Promise((resolve, reject) => {
                if (window.paypal) {
                    resolve();
                    return;
                }
                const script = document.createElement('script');
                script.src = 'https://www.' + paypalSdkDomain + '.com/sdk/js?client-id=' + paypalClientId + '&components=buttons,marks&enable-funding=paypal&intent=capture';
                script.async = true;
                script.onload = () => resolve();
                script.onerror = () => reject(new Error('Failed to load PayPal SDK'));
                document.head.appendChild(script);
            });
        }

        function loadStripeSDK() {
            return new Promise((resolve, reject) => {
                if (window.Stripe) {
                    resolve();
                    return;
                }
                const script = document.createElement('script');
                script.src = 'https://js.stripe.com/v3/';
                script.async = true;
                script.onload = () => resolve();
                script.onerror = () => reject(new Error('Failed to load Stripe SDK'));
                document.head.appendChild(script);
            });
        }

        let selectedPayment;
        let stripe;

        function resetPaymentUI() {
            document.getElementById('payment-container').style.display = 'none';
            document.getElementById('payment-status').style.display = 'none';
            document.getElementById('payment-error').style.display = 'none';
            document.getElementById('payment-container').innerHTML = '';
        }

        function selectPayment(method) {
            try {
                selectedPayment = method;
                document.querySelectorAll('.payment-option').forEach(option => option.classList.remove('selected'));
                document.querySelector(`.payment-option[onclick="selectPayment('${method}')"]`).classList.add('selected');

                loadPaymentForm();
            } catch (error) {
                console.error('Error in selectPayment:', error);
                document.getElementById('payment-error').innerText = 'Error selecting payment method. Please try again.';
                document.getElementById('payment-error').style.display = 'block';
            }
        }

        function loadPaymentForm() {
            try {
                const userId = currentUserId;

                resetPaymentUI();

                if (selectedPayment === 'paypal') {
                    document.getElementById('payment-container').style.display = 'block';
                    loadPayPalSDK()
                        .then(() => {
                            document.getElementById('payment-container').innerHTML = '<div id="paypal-button-container"></div>';
                            paypal.Buttons({
                                style: {
                                    layout: 'vertical',
                                    color: 'gold',
                                    shape: 'rect',
                                    label: 'pay'
                                },
                                createOrder: function(data, actions) {
                                    const credits = document.getElementById('credits-select').value;
                                    return actions.order.create({
                                        intent: 'CAPTURE',
                                        purchase_units: [{
                                            amount: { value: credits, 'currency_code': 'USD' },
                                            custom_id: userId
                                        }],
                                        application_context: {
                                            shipping_preference: 'NO_SHIPPING'
                                        }
                                    });
                                },
                                onApprove: function(data, actions) {
                                    let orderID = data.orderID;
                                    if (!orderID) {
                                        console.error('Order ID is undefined:', { data, actions });
                                        alert('Payment failed: Could not determine order ID. Please contact support.');
                                        throw new Error('Order ID is undefined');
                                    }
                                    alert('Payment approved! Transaction ID: ' + orderID);

                                    const credits = document.getElementById('credits-select').value;
                                    fetch(ajaxUrl, {
                                        method: 'POST',
                                        headers: {
                                            'Content-Type': 'application/x-www-form-urlencoded'
                                        },
                                        body: new URLSearchParams({
                                            action: 'lucydream_capture_paypal',
                                            order_id: orderID,
                                            amount: credits,
                                            user_id: userId,
                                            nonce: ajaxNonce
                                        })
                                    })
                                    .then(response => response.json())
                                    .then(data => {
                                        if (data.success) {
                                            document.getElementById('payment-status').innerHTML = 'Thank you! Check your balance!<br>Success! Transaction ID: ' + data.data.transaction_id;
                                            document.getElementById('payment-status').style.display = 'block';
                                            document.getElementById('payment-error').style.display = 'none';
                                        } else {
                                            alert('Payment failed: ' + (data.data ? data.data.message : 'Unknown server error'));
                                            document.getElementById('payment-error').innerText = 'Error: ' + (data.data ? data.data.message : 'Server error. Please contact support.');
                                            document.getElementById('payment-error').style.display = 'block';
                                            document.getElementById('payment-status').style.display = 'none';
                                        }
                                    })
                                    .catch(error => {
                                        console.error('Capture error:', error);
                                        alert('Capture error: ' + error.message);
                                        document.getElementById('payment-error').innerText = 'Error: Server error. Please contact support.';
                                        document.getElementById('payment-error').style.display = 'block';
                                    });
                                },
                                onError: function(err) {
                                    console.error('PayPal SDK error:', err);
                                    alert('Payment error: ' + err.message);
                                    document.getElementById('payment-error').innerText = 'Payment failed: ' + err.message + '. Please try again or contact support.';
                                    document.getElementById('payment-error').style.display = 'block';
                                }
                            }).render('#paypal-button-container');
                        })
                        .catch(error => {
                            console.error('PayPal SDK load error:', error);
                            alert('Token fetch error: ' + error.message);
                            document.getElementById('payment-error').innerText = 'Error loading payment system: ' + error.message + '. Please try again.';
                            document.getElementById('payment-error').style.display = 'block';
                        });
                } else if (selectedPayment === 'stripe') {
                    document.getElementById('payment-container').style.display = 'block';
                    loadStripeSDK()
                        .then(() => {
                            document.getElementById('payment-container').innerHTML = `
                                <button id="stripe-pay-button">Pay Now</button>
                            `;
                            stripe = Stripe(stripePubKey);

                            const payButton = document.getElementById('stripe-pay-button');
                            payButton.style.display = 'block';
                            payButton.disabled = false;

                            payButton.onclick = () => {
                                payButton.disabled = true;
                                const credits = document.getElementById('credits-select').value;
                                fetch(ajaxUrl, {
                                    method: 'POST',
                                    headers: {
                                        'Content-Type': 'application/x-www-form-urlencoded'
                                    },
                                    body: new URLSearchParams({
                                        action: 'lucydream_create_stripe_session',
                                        user_id: userId,
                                        amount: credits,
                                        nonce: ajaxNonce
                                    })
                                })
                                .then(response => response.json())
                                .then(data => {
                                    if (data.success) {
                                        stripe.redirectToCheckout({ sessionId: data.data.session_id })
                                            .then(result => {
                                                if (result.error) {
                                                    throw new Error(result.error.message);
                                                }
                                            });
                                    } else {
                                        throw new Error(data.data ? data.data.message : 'Failed to initiate payment');
                                    }
                                })
                                .catch(error => {
                                    console.error('Stripe payment initiation error:', error);
                                    alert('Payment error: ' + error.message);
                                    document.getElementById('payment-error').innerText = 'Error initiating payment: ' + error.message + '. Please try again or contact support.';
                                    document.getElementById('payment-error').style.display = 'block';
                                    payButton.disabled = false;
                                });
                            };
                        })
                        .catch(error => {
                            console.error('Stripe SDK load error:', error);
                            alert('Payment system error: ' + error.message);
                            document.getElementById('payment-error').innerText = 'Error loading payment system: ' + error.message + '. Please try again.';
                            document.getElementById('payment-error').style.display = 'block';
                        });
                }
            } catch (error) {
                console.error('Error in loadPaymentForm:', error);
                document.getElementById('payment-error').innerText = 'Error loading payment form. Please refresh the page or contact support.';
                document.getElementById('payment-error').style.display = 'block';
            }
        }

        document.addEventListener('DOMContentLoaded', function() {
            try {
                const urlParams = new URLSearchParams(window.location.search);
                const status = urlParams.get('status');
                const transactionId = urlParams.get('transaction_id');

                if (status === 'success' && transactionId) {
                    fetch(ajaxUrl, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/x-www-form-urlencoded'
                        },
                        body: new URLSearchParams({
                            action: 'lucydream_confirm_stripe',
                            session_id: transactionId,
                            nonce: ajaxNonce
                        })
                    })
                    .then(response => response.json())
                    .then(data => {
                        if (data.success) {
                            resetPaymentUI();
                            document.getElementById('payment-status').innerHTML = 'Thank you! Check your balance!<br>Success! Transaction ID: ' + transactionId;
                            document.getElementById('payment-status').style.display = 'block';
                        } else {
                            document.getElementById('payment-error').innerText = 'Payment confirmation failed: ' + (data.data ? data.data.message : 'Unknown error');
                            document.getElementById('payment-error').style.display = 'block';
                        }
                    })
                    .catch(error => {
                        console.error('Stripe confirmation error:', error);
                        document.getElementById('payment-error').innerText = 'Error confirming payment. Please contact support.';
                        document.getElementById('payment-error').style.display = 'block';
                    });
                } else if (status === 'cancel') {
                    resetPaymentUI();
                    document.getElementById('payment-error').innerText = 'Payment was canceled. Please try again.';
                    document.getElementById('payment-error').style.display = 'block';
                }

                selectPayment('paypal');
            } catch (error) {
                console.error('Error in DOMContentLoaded:', error);
                document.getElementById('payment-error').innerText = 'Error loading payment page. Please refresh or contact support.';
                document.getElementById('payment-error').style.display = 'block';
            }
        });
    </script>
    <?php
    return ob_get_clean();
}

// AJAX handler for PayPal capture
add_action('wp_ajax_lucydream_capture_paypal', 'lucydream_capture_paypal_handler');

function lucydream_capture_paypal_handler() {
    check_ajax_referer('lucydream_ajax', 'nonce');

    $order_id = sanitize_text_field($_POST['order_id']);
    $amount = floatval($_POST['amount']);
    $user_id = intval($_POST['user_id']);
    $credits = intval($amount); // 1 credit = 1 USD

    $env = get_option('lucydream_paypal_env', 'live');
    $client_id = ($env === 'live') ? get_option('lucydream_paypal_live_client_id') : get_option('lucydream_paypal_sandbox_client_id');
    $secret = ($env === 'live') ? get_option('lucydream_paypal_live_secret') : get_option('lucydream_paypal_sandbox_secret');
    $api_base = 'https://api' . ($env === 'sandbox' ? '.sandbox' : '') . '.paypal.com';

    // Get access token
    $auth_response = wp_remote_post($api_base . '/v1/oauth2/token', [
        'headers' => [
            'Authorization' => 'Basic ' . base64_encode($client_id . ':' . $secret),
        ],
        'body' => 'grant_type=client_credentials',
    ]);

    if (is_wp_error($auth_response)) {
        wp_send_json_error(['message' => 'Failed to get access token']);
    }

    $auth_body = wp_remote_retrieve_body($auth_response);
    $auth_data = json_decode($auth_body);

    if (!isset($auth_data->access_token)) {
        wp_send_json_error(['message' => 'Invalid access token response']);
    }

    $token = $auth_data->access_token;

    // Capture order
    $capture_response = wp_remote_post($api_base . '/v2/checkout/orders/' . $order_id . '/capture', [
        'headers' => [
            'Authorization' => 'Bearer ' . $token,
            'Content-Type' => 'application/json',
        ],
        'body' => '{}',
    ]);

    if (is_wp_error($capture_response)) {
        wp_send_json_error(['message' => 'Capture request failed']);
    }

    $capture_body = wp_remote_retrieve_body($capture_response);
    $capture_data = json_decode($capture_body);

    if (isset($capture_data->status) && $capture_data->status === 'COMPLETED') {
        $transaction_id = $capture_data->id; // or more specific capture ID

        global $wpdb;
        $table = $wpdb->prefix . 'lucydream_payments';

        $wpdb->insert($table, [
            'user_id' => $user_id,
            'amount' => $amount,
            'credits' => $credits,
            'psp' => 'paypal',
            'transaction_id' => $transaction_id,
            'status' => 'completed',
        ]);

        // Add credits to user meta
        $current_purchased = floatval(get_user_meta($user_id, 'purchased_credits', true));
        update_user_meta($user_id, 'purchased_credits', $current_purchased + $credits);

        wp_send_json_success(['transaction_id' => $transaction_id]);
    } else {
        wp_send_json_error(['message' => 'Capture failed: ' . ($capture_data->message ?? 'Unknown error')]);
    }
}

// AJAX handler for creating Stripe session
add_action('wp_ajax_lucydream_create_stripe_session', 'lucydream_create_stripe_session_handler');

function lucydream_create_stripe_session_handler() {
    check_ajax_referer('lucydream_ajax', 'nonce');

    $amount = floatval($_POST['amount']);
    $user_id = intval($_POST['user_id']);
    $credits = intval($amount);

    $env = get_option('lucydream_stripe_env', 'live');
    $secret = ($env === 'live') ? get_option('lucydream_stripe_live_secret') : get_option('lucydream_stripe_test_secret');

    $current_page_url = get_permalink();
    $success_url = add_query_arg(['status' => 'success', 'transaction_id' => '{CHECKOUT_SESSION_ID}'], $current_page_url);
    $cancel_url = add_query_arg(['status' => 'cancel'], $current_page_url);

    $body = http_build_query([
        'payment_method_types[]' => 'card',
        'line_items[0][price_data][currency]' => 'usd',
        'line_items[0][price_data][product_data][name]' => $credits . ' Credits',
        'line_items[0][price_data][unit_amount]' => $amount * 100,
        'line_items[0][quantity]' => 1,
        'mode' => 'payment',
        'success_url' => $success_url,
        'cancel_url' => $cancel_url,
        'metadata[user_id]' => $user_id,
        'metadata[credits]' => $credits,
    ]);

    $response = wp_remote_post('https://api.stripe.com/v1/checkout/sessions', [
        'headers' => [
            'Authorization' => 'Basic ' . base64_encode($secret . ':'),
            'Content-Type' => 'application/x-www-form-urlencoded',
        ],
        'body' => $body,
    ]);

    if (is_wp_error($response)) {
        wp_send_json_error(['message' => 'Session creation failed']);
    }

    $body_resp = wp_remote_retrieve_body($response);
    $data = json_decode($body_resp);

    if (isset($data->id)) {
        wp_send_json_success(['session_id' => $data->id]);
    } else {
        wp_send_json_error(['message' => 'Failed to create session: ' . ($data->error->message ?? 'Unknown error')]);
    }
}

// AJAX handler for confirming Stripe payment
add_action('wp_ajax_lucydream_confirm_stripe', 'lucydream_confirm_stripe_handler');

function lucydream_confirm_stripe_handler() {
    check_ajax_referer('lucydream_ajax', 'nonce');

    $session_id = sanitize_text_field($_POST['session_id']);
    $env = get_option('lucydream_stripe_env', 'live');
    $secret = ($env === 'live') ? get_option('lucydream_stripe_live_secret') : get_option('lucydream_stripe_test_secret');

    $response = wp_remote_get('https://api.stripe.com/v1/checkout/sessions/' . $session_id, [
        'headers' => [
            'Authorization' => 'Basic ' . base64_encode($secret . ':'),
        ],
    ]);

    if (is_wp_error($response)) {
        wp_send_json_error(['message' => 'Failed to retrieve session']);
    }

    $body = wp_remote_retrieve_body($response);
    $data = json_decode($body);

    if (isset($data->payment_status) && $data->payment_status === 'paid' && isset($data->metadata->user_id) && intval($data->metadata->user_id) === get_current_user_id()) {
        $user_id = intval($data->metadata->user_id);
        $credits = intval($data->metadata->credits);
        $amount = $credits; // Assuming 1:1

        global $wpdb;
        $table = $wpdb->prefix . 'lucydream_payments';

        // Check if already processed
        $exists = $wpdb->get_var($wpdb->prepare("SELECT id FROM $table WHERE transaction_id = %s AND status = 'completed'", $session_id));

        if (!$exists) {
            $wpdb->insert($table, [
                'user_id' => $user_id,
                'amount' => $amount,
                'credits' => $credits,
                'psp' => 'stripe',
                'transaction_id' => $session_id,
                'status' => 'completed',
            ]);

            $current_purchased = floatval(get_user_meta($user_id, 'purchased_credits', true));
            update_user_meta($user_id, 'purchased_credits', $current_purchased + $credits);

            wp_send_json_success();
        } else {
            wp_send_json_success(); // Already processed
        }
    } else {
        wp_send_json_error(['message' => 'Invalid payment status or metadata']);
    }
}
?>