<?php
/**
 * Plugin Name: Flux Payments Gateway for WooCommerce
 * Plugin URI: https://fluxpayments.com
 * Description: Accept credit cards, ACH, and cryptocurrency payments with lower fees and zero chargeback risk on crypto transactions.
 * Version: 1.7.8
 * Author: Flux Payments
 * License: GPL-2.0-or-later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: flux-payments-gateway
 */

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;
add_action('plugins_loaded', 'init_flux_gateway_class');

function init_flux_gateway_class()
{
    if (!class_exists('WC_Payment_Gateway')) {
        return;
    }

    class WC_Gateway_Flux extends WC_Payment_Gateway
    {
        public function __construct()
        {



            $this->id = 'flux_gateway';
            $this->method_title = 'Flux Payments';
            $this->method_description = 'Accept payments with Flux Payments.';
            $this->icon = plugins_url('assets/logo.png', __FILE__);


            $this->init_form_fields();
            $this->init_settings();

            $this->title = $this->get_option('title');
            $this->description = $this->get_option('description');
            $this->enabled = $this->get_option('enabled');
            $this->has_fields = $this->is_hosted_fields_mode();

            add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']);

            if ($this->enabled !== "yes") {
                return;
            }

            // NOTE: Frontend asset enqueueing has been moved out of this
            // constructor to a top-level wp_enqueue_scripts handler
            // (flux_enqueue_frontend_assets, defined below). Reason: WC
            // instantiates payment gateways lazily — on the cart page nothing
            // forces instantiation until our flux_add_cart_checkout_button()
            // calls get_available_payment_gateways(), which runs after
            // wp_enqueue_scripts has already fired. Registering the action in
            // the constructor was a no-op on cart and mini-cart contexts.

            add_action('woocommerce_update_product', [$this, 'put_or_post_product'], 10, 1);
            add_action('woocommerce_api_flux_gateway_response', [$this, 'handle_flux_response']);

            // Modal HTML for cart/mini-cart pages
            if ($this->is_hosted_fields_mode()) {
                add_action('wp_footer', [$this, 'render_hosted_fields_modal']);
            }
        }

        public function put_or_post_product($product_id)
        {
            $product = wc_get_product($product_id);
            if (!$product) {
                return;
            }

            if (get_transient("flux_processed_product_{$product_id}")) {
                return;
            }


            set_transient("flux_processed_product_{$product_id}", true, 10);

            $flux_product_id = $product->get_meta('flux_product_id');
            $image_url = $this->get_product_image_url($product);
            $product_data = $this->build_flux_product_data($product, $flux_product_id, $image_url);

            try {
                $response = $this->sync_product_with_flux($product_data, $flux_product_id, $image_url);
            } catch (Exception $e) {
                if ($flux_product_id) {
                    // PUT failed — product may have been deleted on Flux side. Clear the stale ID and re-create.
                    error_log('Flux: PUT failed for product ' . $product->get_name() . ' (ID: ' . $product_id . '), re-creating: ' . $e->getMessage());
                    $product->delete_meta_data('flux_product_id');
                    $product->save();
                    $flux_product_id = null;
                    $product_data = $this->build_flux_product_data($product, null, $image_url);
                    try {
                        $response = $this->sync_product_with_flux($product_data, null, $image_url);
                    } catch (Exception $e2) {
                        error_log('Flux: Failed to re-create product ' . $product->get_name() . ' (ID: ' . $product_id . '): ' . $e2->getMessage());
                        return;
                    }
                } else {
                    error_log('Flux: Failed to sync product ' . $product->get_name() . ' (ID: ' . $product_id . '): ' . $e->getMessage());
                    return;
                }
            }

            if (!$flux_product_id && isset($response['createdObjects'][0]['id'])) {
                $product->update_meta_data('flux_product_id', $response['createdObjects'][0]['id']);
                $product->save();
            }
        }

        private function get_product_image_url($product)
        {
            $image_id = $product->get_image_id();
            if ($image_id) {
                $image_url = wp_get_attachment_url($image_id);
                if ($image_url) {
                    return $image_url;
                }
            } else {
            }
            return null;
        }

        private function build_flux_product_data($product, $flux_product_id, $image_url)
        {

            $is_virtual = $product->is_virtual();
            $is_downloadable = $product->is_downloadable();

            $is_physical = !$is_virtual && !$is_downloadable;



            $sale_price = $product->get_sale_price();
            $regular_price = $product->get_regular_price();

            $price_to_use = !empty($sale_price) ? $sale_price : $regular_price;
            
            // Ensure price is valid - convert to float and handle edge cases
            $price_to_use = floatval($price_to_use);
            if ($price_to_use <= 0) {
                error_log("Flux: Product {$product->get_name()} (ID: {$product->get_id()}) has invalid price: {$price_to_use}. Setting to 0.01");
                $price_to_use = 0.01; // Minimum price for Flux Payments
            }

            $data = [
                "name" => $product->get_name(),
                "sku" => $product->get_sku(),
                "price" => $price_to_use,
                "objectType" => "product",
                "description" => $product->get_description() ?: $product->get_name(),
                "type" => $is_physical ? "PHYSICAL_PRODUCT" : "SERVICE"
            ];

            if ($flux_product_id) {
                $data["id"] = $flux_product_id;
            }
            if ($image_url) {
                $data["imageUrl"] = basename(wp_parse_url($image_url, PHP_URL_PATH));
            }

            return $data;
        }

        private function sync_product_with_flux($product_data, $flux_product_id, $full_image_url)
        {
            $url = 'https://api.fluxpayments.com/api/product';
            $method = $flux_product_id ? 'PUT' : 'POST';
            $body = json_encode(
                !$flux_product_id
                ? ["createdObjects" => [$product_data]]
                : ["updatedObjects" => [$product_data]]
            );


            $response = $this->flux_api_request($url, $method, $body);

            if (!is_array($response)) {
                throw new Exception("Invalid response from Flux Payments: " . esc_textarea($response));
            }

            if (!$flux_product_id && !isset($response['createdObjects'][0]['id'])) {
                throw new Exception("Invalid response structure from Flux Payments");
            }

            if (empty($product_data['imageUrl'])) {
                return $response;
            }

            $image_url = $full_image_url;
            $image_response = wp_remote_get($image_url);

            if (is_wp_error($image_response)) {
                return $response;
            }

            $image_contents = wp_remote_retrieve_body($image_response);

            if (empty($image_contents)) {
                return $response;
            }

            $finfo = new finfo(FILEINFO_MIME_TYPE);
            $mime_type = $finfo->buffer($image_contents);

            $upload_url = $response['createdObjects'][0]['documentMap'][0]['uploadUrl'] ?? $response['updatedObjects'][0]['documentMap'][0]['uploadUrl'];


            if (!$upload_url) {
                return $response;
            }

            $upload_args = [
                'timeout' => 30,
                'method' => 'PUT',
                'headers' => [
                    'Content-Type' => $mime_type,
                    'Content-Length' => strlen($image_contents)
                ],
                'body' => $image_contents
            ];

            $upload_response = wp_remote_request($upload_url, $upload_args);

            if (is_wp_error($upload_response)) {
                return $response;
            }

            $http_code = wp_remote_retrieve_response_code($upload_response);

            if ($http_code >= 200 && $http_code < 300) {
            } else {
            }

            return $response;
        }
        private function flux_api_request($url, $method, $body)
        {
            $args = [
                'timeout' => 15000,
                'method' => $method,
                'headers' => [
                    'Content-Type' => 'application/json',
                    'Authorization' => 'Basic ' . base64_encode($this->get_option('flux_api_key'))
                ],
            ];

            if ($method !== 'GET' && !empty($body)) {
                $args['body'] = $body;
            }

            $response = wp_remote_request($url, $args);


            if (is_wp_error($response)) {
                throw new Exception("Failed to communicate with Flux Payments");
            }

            $httpCode = wp_remote_retrieve_response_code($response);
            $body = wp_remote_retrieve_body($response);

            error_log('Flux API Response Code: ' . $httpCode);
            error_log('Flux API Response Body: ' . $body);

            if ($httpCode !== 200) {
                throw new Exception("Failed to communicate with Flux Payments: " . esc_textarea($body));
            }

            error_log('Flux API Response: ' . print_r($body, true));

            return json_decode($body, true);
        }

        private function get_currencies()
        {
            $url = 'https://api.fluxpayments.com/api/currency';
            $response = $this->flux_api_request($url, 'GET', []);
            return $response;
        }

        private function get_wallets()
        {
            $url = 'https://api.fluxpayments.com/api/wallet';
            $response = $this->flux_api_request($url, 'GET', []);
            return $response;
        }

        private function is_hosted_fields_mode()
        {
            return $this->get_option('checkout_experience') === 'hosted_fields';
        }

        private function get_credentials()
        {
            $api_key = $this->get_option('flux_api_key');
            $parts = explode(':', $api_key, 2);
            return [
                'publicKey' => $parts[0] ?? '',
                'aesKey' => $parts[1] ?? '',
            ];
        }

        public function generate_sync_button_html($key, $data)
        {
            $field_key = $this->get_field_key($key);
            $defaults = ['title' => '', 'description' => ''];
            $data = wp_parse_args($data, $defaults);

            ob_start();
            ?>
            <tr valign="top">
                <th scope="row" class="titledesc">
                    <label><?php echo wp_kses_post($data['title']); ?></label>
                </th>
                <td class="forminp">
                    <button type="button" id="<?php echo esc_attr($field_key); ?>"
                        style="padding: 8px 20px; background: #2271b1; color: #fff; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; font-weight: 500;">
                        Sync Products
                    </button>
                    <p class="description"><?php echo wp_kses_post($data['description']); ?></p>
                </td>
            </tr>
            <?php
            return ob_get_clean();
        }

        public function init_form_fields()
        {

            $this->form_fields = [
                'enabled' => [
                    'title' => 'Enable/Disable',
                    'type' => 'checkbox',
                    'label' => 'Enable Flux Payments',
                    'default' => 'yes'
                ],
                'button_sync_products' => [
                    'title' => 'Sync Products',
                    'type' => 'sync_button',
                    'description' => 'Click to synchronize products with Flux Payments'
                ],
                'flux_api_key' => [
                    'title' => 'Flux API Key',
                    'type' => 'password',
                    'default' => ''
                ],
                'title' => [
                    'title' => 'Title',
                    'type' => 'text',
                    'default' => 'Flux Payments'
                ],
                'checkout_experience' => [
                    'title' => 'Checkout Experience',
                    'type' => 'select',
                    'description' => 'Choose how customers pay. "Redirect" sends customers to Flux\'s hosted page. "Hosted Fields" embeds card fields directly on your site.',
                    'default' => 'redirect',
                    'options' => [
                        'redirect' => 'Redirect to Flux (default)',
                        'hosted_fields' => 'Hosted Fields (inline card form)',
                    ],
                ],
                'accent_color' => [
                    'title' => 'Accent Color',
                    'type' => 'text',
                    'description' => 'Hex color for input focus borders and rings (e.g. #0f9a7b).',
                    'default' => '#0f9a7b',
                ],
                'button_color' => [
                    'title' => 'Button Color',
                    'type' => 'text',
                    'description' => 'Hex color for checkout buttons (e.g. #023857).',
                    'default' => '#023857',
                ],
                'clear_cart' => [
                    'title' => 'Clear Cart',
                    'type' => 'checkbox',
                    'label' => 'Automatically clear the cart after successful payment',
                    'default' => 'yes',
                ],
                'service_fee_rate' => [
                    'title' => 'Service Fee Rate (%)',
                    'type' => 'text',
                    'description' => 'Optional service fee percentage applied to orders (e.g. 3.5 for 3.5%). Leave blank for no fee.',
                    'default' => '',
                ],
                'crypto_enabled' => [
                    'title' => 'Enable Crypto',
                    'type' => 'checkbox',
                    'label' => 'Offer crypto at checkout',
                    'default' => 'no'
                ]
            ];


            $crypto_enabled = $this->get_option('crypto_enabled');
            if ($crypto_enabled === 'yes') {


                $wallets = $this->get_wallets();


                if (isset($wallets['count']) && $wallets['count'] == 0) {
                    $wallet_fields = [
                        'crypto_wallets_title' => [
                            'title' => 'No wallets found',
                            'type' => 'title',
                            'description' => 'No wallets found. Please create a wallet in the Flux Payments dashboard before setting up crypto.',
                        ]
                    ];
                    $this->form_fields = array_merge($this->form_fields ?? [], $wallet_fields);
                    return;
                }

                $wallet_fields = [
                    'crypto_wallets_title' => [
                        'title' => 'Allowed Wallets',
                        'type' => 'title',
                        'description' => 'Choose wallets you want to enable/monitor.',
                    ],
                ];

                if (isset($wallets['objects']) && is_array($wallets['objects'])) {
                    foreach ($wallets['objects'] as $wallet) {
                        $id = $wallet['id'] ?? '';
                        $address = substr($wallet['publicAddress'] ?? '', 0, 5);
                        $chain = $wallet['chain'] ?? '';
                        $memoTag = $wallet['memoTag'] ?? null;

                        $memoPart = $memoTag ? " - {$memoTag}" : "";
                        $label = "{$id} - {$address}{$memoPart} - {$chain}";

                        $wallet_fields["crypto_wallet_{$id}"] = [
                            'title' => $label,
                            'type' => 'checkbox',
                            'label' => 'Enable',
                            'default' => 'no',
                            'class' => 'crypto-wallet-row',
                        ];
                    }
                }

                $this->form_fields = array_merge($this->form_fields ?? [], $wallet_fields);

                $currencies = $this->get_currencies();

                $asset_fields = [
                    'crypto_assets_title' => [
                        'title' => 'Allowed Crypto Assets',
                        'type' => 'title',
                        'description' => 'Choose assets you support.',
                    ],
                ];

                if (isset($currencies['objects']) && is_array($currencies['objects'])) {
                    foreach ($currencies['objects'] as $currency) {
                        $id = $currency['id'] ?? '';
                        $shortName = $currency['shortName'] ?? '';
                        $issuer = $currency['issuer'] ?: '';
                        $chain = $currency['chain'] ?? '';

                        $label = "{$id} - {$shortName} - {$issuer} - {$chain}";

                        $asset_fields["crypto_asset_{$id}"] = [
                            'title' => $label,
                            'type' => 'checkbox',
                            'label' => 'Enable',
                            'default' => 'no',
                        ];
                    }
                }


                $this->form_fields = array_merge($this->form_fields ?? [], $asset_fields);



            }

        }

        private function get_order_flux_product_ids($order)
        {
            $product_ids = [];
            foreach ($order->get_items() as $item) {
                $product_id = $item->get_product_id();
                $product = wc_get_product($product_id);
                if ($product) {
                    $flux_id = $product->get_meta('flux_product_id');
                    if ($flux_id) {
                        $product_ids[] = $flux_id;
                    }
                }
            }
            return array_unique($product_ids);
        }


        public function process_payment($order_id)
        {
            $order = wc_get_order($order_id);
            $order->set_payment_method('flux_gateway');
            $order->save();

            // --- Hosted Fields mode (checkout page) ---
            if ($this->is_hosted_fields_mode() && empty($_POST['flux_card_token'])) {
                wc_add_notice('Please wait for card authorization to complete.', 'error');
                return ['result' => 'failure'];
            }

            if ($this->is_hosted_fields_mode() && !empty($_POST['flux_card_token'])) {
                $card_token = sanitize_text_field(wp_unslash($_POST['flux_card_token']));
                $last_four = sanitize_text_field(wp_unslash($_POST['flux_card_last_four'] ?? ''));
                $card_brand = sanitize_text_field(wp_unslash($_POST['flux_card_brand'] ?? ''));

                // Build products from cart
                $products = [];
                $cart_items = WC()->cart->get_cart();
                foreach ($cart_items as $cart_item) {
                    $product = wc_get_product($cart_item['product_id']);
                    if ($product) {
                        $flux_id = $product->get_meta('flux_product_id');
                        if ($flux_id) {
                            $products[] = [
                                'objectType' => 'product',
                                'id' => (int) $flux_id,
                                'orderQuantity' => (int) $cart_item['quantity'],
                            ];
                        }
                    }
                }

                if (empty($products)) {
                    wc_add_notice('Payment error: no synced products.', 'error');
                    return ['result' => 'failure'];
                }

                $credentials = $this->get_credentials();
                $basic_auth = base64_encode($credentials['publicKey'] . ':' . $credentials['aesKey']);

                $payload = [
                    'objectType' => 'payment_intent',
                    'cardToken' => $card_token,
                    'products' => $products,
                ];

                $fee_rate = $this->get_option('service_fee_rate', '');
                if ($fee_rate !== '' && is_numeric($fee_rate) && floatval($fee_rate) > 0) {
                    $payload['serviceFeeRate'] = floatval($fee_rate);
                }

                $response = wp_remote_post('https://api.fluxpayments.com/api/post/createPaymentIntent', [
                    'timeout' => 30,
                    'headers' => [
                        'Content-Type' => 'application/json',
                        'Authorization' => 'Basic ' . $basic_auth,
                    ],
                    'body' => wp_json_encode($payload),
                ]);

                if (is_wp_error($response)) {
                    wc_add_notice('Payment failed. Please try again.', 'error');
                    return ['result' => 'failure'];
                }

                $body = json_decode(wp_remote_retrieve_body($response), true);

                if (($body['paymentStatus'] ?? '') !== 'APPROVED') {
                    $msg = $body['declineReason'] ?? $body['errorMsg'] ?? 'Payment declined';
                    wc_add_notice($msg, 'error');
                    $order->update_status('failed');
                    $order->add_order_note('Flux Hosted Fields declined: ' . $msg);
                    return ['result' => 'failure'];
                }

                $transaction_id = $body['transactionId'] ?? '';
                $order->payment_complete($transaction_id);
                $order->add_order_note(sprintf(
                    'Flux Hosted Fields payment completed. Txn: %s, %s ending %s',
                    $transaction_id, $card_brand, $last_four
                ));
                $order->update_meta_data('flux_transaction_id', $transaction_id);
                $order->update_meta_data('flux_card_last_four', $last_four);
                $order->update_meta_data('flux_card_brand', $card_brand);

                // Populate billing from response
                if (!empty($body['customerFirstName'])) $order->set_billing_first_name(sanitize_text_field($body['customerFirstName']));
                if (!empty($body['customerLastName'])) $order->set_billing_last_name(sanitize_text_field($body['customerLastName']));
                if (!empty($body['customerEmail'])) $order->set_billing_email(sanitize_email($body['customerEmail']));
                if (!empty($body['customerPhone'])) $order->set_billing_phone(sanitize_text_field($body['customerPhone']));
                if (!empty($body['billingAddress'])) $order->set_billing_address_1(sanitize_text_field($body['billingAddress']));
                if (!empty($body['billingCity'])) $order->set_billing_city(sanitize_text_field($body['billingCity']));
                if (!empty($body['billingState'])) $order->set_billing_state(sanitize_text_field($body['billingState']));
                if (!empty($body['billingZip'])) $order->set_billing_postcode(sanitize_text_field($body['billingZip']));
                if (!empty($body['billingCountry'])) $order->set_billing_country(sanitize_text_field($body['billingCountry']));
                $order->save();

                if ($this->get_option('clear_cart', 'yes') === 'yes') {
                    WC()->cart->empty_cart();
                }

                return [
                    'result' => 'success',
                    'redirect' => $this->get_return_url($order),
                ];
            }

            // --- Existing redirect mode ---
            $redirect_url = $this->flux_cart_redirect($order->get_order_number());

            return array(
                'result' => 'success',
                'redirect' => $redirect_url
            );
        }
        public function flux_cart_redirect($order_number)
        {
            $cart_items = WC()->cart->get_cart();
            $product_ids = [];
            foreach ($cart_items as $cart_item) {
                $product_id = $cart_item['product_id'];
                $quantity = $cart_item['quantity']; // Get the quantity of the product in cart
                $product = wc_get_product($product_id);
                if ($product) {
                    $flux_id = $product->get_meta('flux_product_id');
                    if ($flux_id) {
                        $product_ids[] = [
                            'id' => $flux_id,
                            'quantity' => $quantity
                        ];
                    }
                }
            }

            $product_json = $this->build_flux_product_json($product_ids);

            try {
                $response = $this->create_flux_payment_link($product_json, $order_number);
            } catch (Exception $e) {
                echo '<p>Failed to create Flux payment link.</p>';
                return;
            }


            $payment_link = $response['createdObjects'][0]['paymentLink'] ?? null;
            $redirect_url = $payment_link ? "https://payments.fluxpayments.com/" . $payment_link : null;
            $payment_link_id = $response['createdObjects'][0]['id'] ?? null;

            $order = wc_get_order($order_number);
            if ($order) {
                $order->update_meta_data('flux_payment_link_id', $payment_link_id);
                $order->save();
            }

            return $redirect_url;
        }
        private function create_flux_payment_link($product_json, $order_number)
        {
            $order = wc_get_order($order_number);
            $nonce = wp_create_nonce('flux_transaction_' . $order_number);
            
            // Build the redirect URL properly
            $redirect_url = add_query_arg([
                'key' => $order->get_order_key(),
                'flux_nonce' => $nonce
            ], wc_get_endpoint_url('order-received', $order_number, wc_get_page_permalink('checkout')));
            
            // For JSON encoding, we need to escape the URL properly
            $redirect_url = str_replace(['/', '?', '=', '&'], ['\/', '\?', '\=', '\&'], $redirect_url);

            $enabled_wallet_ids = [];
            $enabled_asset_ids = [];


            foreach (array_keys($this->form_fields ?? []) as $key) {
                $value = $this->get_option($key);

                if ($value === 'yes') {
                    if (strpos($key, 'crypto_wallet_') === 0) {
                        $enabled_wallet_ids[] = (int) str_replace('crypto_wallet_', '', $key);
                    } elseif (strpos($key, 'crypto_asset_') === 0) {
                        $enabled_asset_ids[] = (int) str_replace('crypto_asset_', '', $key);
                    }
                }
            }


            $body = [
                "createdObjects" => [
                    [
                        "objectType" => "payment_link",
                        "products" => $product_json,
                        "emailNotificationDisabled" => true,
                        "isReusable" => true,
                        "redirectUrl" => $redirect_url,
                        "minutesToExpire" => 30
                    ]
                ]
            ];

            $wallet_json = [];
            $asset_json = [];

            foreach ($enabled_wallet_ids as $wallet_id) {
                $wallet_json[] = [
                    "objectType" => "wallet",
                    "id" => (int) $wallet_id
                ];
            }


            foreach ($enabled_asset_ids as $asset_id) {
                $asset_json[] = [
                    "objectType" => "currency",
                    "id" => (int) $asset_id
                ];
            }

            if (count($wallet_json) > 0) {
                $body['createdObjects'][0]['wallets'] = $wallet_json;
            }

            if (count($asset_json) > 0) {
                $body['createdObjects'][0]['currencies'] = $asset_json;
            }


            // Debug: Log the body to WordPress debug log
            error_log('Flux Payment Link Body: ' . print_r($body, true));
            
            // Debug: Also log to a custom file for easier viewing
            file_put_contents(WP_CONTENT_DIR . '/flux-debug.log', date('Y-m-d H:i:s') . " - Body: " . print_r($body, true) . "\n", FILE_APPEND);
            $url = 'https://api.fluxpayments.com/api/paymentLink';
            $body = json_encode($body);
            $response = $this->flux_api_request($url, 'POST', $body);
            error_log('Flux Payment Link Response: ' . print_r($response, true));
            return $response;
        }

        private function build_flux_product_json($product_ids)
        {
            $product_json = [];
            foreach ($product_ids as $product_id) {
                $product_json[] = [
                    "objectType" => "product",
                    "id" => (int) $product_id['id'],
                    "orderQuantity" => (int) $product_id['quantity']
                ];
            }
            return $product_json;
        }


        public function get_flux_transaction($transaction_id)
        {
            $url = 'https://api.fluxpayments.com/api/transaction/' . $transaction_id;
            $response = $this->flux_api_request($url, 'GET', []);
            return $response;
        }

        public function populate_order_from_transaction($order, $transaction_id)
        {
            error_log('Flux: populate_order_from_transaction called with txn_id: ' . $transaction_id);
            try {
                $txn_data = $this->get_flux_transaction($transaction_id);
                error_log('Flux: Transaction data for order population: ' . wp_json_encode($txn_data));
                $txn = $txn_data['objects'][0] ?? null;

                if (!$txn) {
                    error_log('Flux: No transaction object found for ID: ' . $transaction_id);
                    return;
                }

                if (!empty($txn['customerFirstName'])) $order->set_billing_first_name(sanitize_text_field($txn['customerFirstName']));
                if (!empty($txn['customerLastName'])) $order->set_billing_last_name(sanitize_text_field($txn['customerLastName']));
                if (!empty($txn['customerEmail'])) $order->set_billing_email(sanitize_email($txn['customerEmail']));
                if (!empty($txn['customerPhone'])) $order->set_billing_phone(sanitize_text_field($txn['customerPhone']));

                $address = $txn['billingAddress'] ?? $txn['address'] ?? null;
                if ($address) {
                    if (!empty($address['streetAddress'])) $order->set_billing_address_1(sanitize_text_field($address['streetAddress']));
                    if (!empty($address['city'])) $order->set_billing_city(sanitize_text_field($address['city']));
                    if (!empty($address['addressState'])) $order->set_billing_state(sanitize_text_field($address['addressState']));
                    if (!empty($address['zipCode'])) $order->set_billing_postcode(sanitize_text_field($address['zipCode']));
                    if (!empty($address['country'])) $order->set_billing_country(sanitize_text_field($address['country']));
                }

                $order->save();
            } catch (Exception $e) {
                error_log('Flux: Failed to populate order billing from transaction: ' . $e->getMessage());
            }
        }


        /**
         * 
         * TODO: UPDATE THE SHIPPING ADDRESS
         * 
         * 
         * @param mixed $order
         * @param mixed $transaction_id
         * @return void
         */
        public function thankyou_page($order, $transaction_id)
        {
            $transaction = $this->get_flux_transaction($transaction_id);


            $transaction_status = null;
            if (isset($transaction['objects'][0]['approvalStatus'])) {
                $transaction_status = $transaction['objects'][0]['approvalStatus'];
            }

            if ($transaction_status === 'FINALIZED') {
                $order->payment_complete();
                $order->add_order_note('Payment completed via Flux.');
            } else {
                $order->update_status('failed');
                $order->add_order_note('Payment pending via Flux.');
            }

            $order->update_meta_data('flux_transaction_id', $transaction_id);


        }


        public function handle_flux_response()
        {
            $order_id = isset($_GET['order_id']) ? absint($_GET['order_id']) : 0;
            $nonce = isset($_GET['flux_nonce']) ? sanitize_text_field(wp_unslash($_GET['flux_nonce'])) : '';
            
            // Verify nonce for security
            if (!wp_verify_nonce($nonce, 'flux_response_' . $order_id)) {
                wp_die(__('Security check failed. Invalid response verification.', 'flux-payments-gateway'));
            }
            
            $order = wc_get_order($order_id);

            if (!$order) {
                wp_die(__('Invalid order.', 'flux-payments-gateway'));
            }

            // Check user permissions
            if (!current_user_can('edit_shop_orders') && $order->get_billing_email() !== wp_get_current_user()->user_email) {
                $order_key = isset($_GET['key']) ? sanitize_text_field(wp_unslash($_GET['key'])) : '';
                if (!$order_key || !hash_equals($order->get_order_key(), $order_key)) {
                    wp_die(__('You do not have permission to view this order.', 'flux-payments-gateway'));
                }
            }

            $order->payment_complete();
            $order->add_order_note('Payment completed via Flux.');

            wp_redirect($this->get_return_url($order));
            exit;
        }

        public function ajax_generate_auth_token()
        {
            check_ajax_referer('flux_hosted_auth', 'nonce');

            $credentials = $this->get_credentials();
            $basic_auth = base64_encode($credentials['publicKey'] . ':' . $credentials['aesKey']);

            $max_retries = 7;
            $attempt = 0;
            $response = null;

            while ($attempt < $max_retries) {
                $response = wp_remote_post('https://api.fluxpayments.com/api/post/generateAuthToken', [
                    'timeout' => 30,
                    'headers' => [
                        'Content-Type' => 'application/json',
                        'Authorization' => 'Basic ' . $basic_auth,
                    ],
                    'body' => wp_json_encode(['objectType' => 'generate_auth_token']),
                ]);

                if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) {
                    break;
                }

                $attempt++;
                if ($attempt < $max_retries) {
                    usleep(min(pow(2, $attempt) * 250000, 16000000)); // 500ms, 1s, 2s, 4s, 8s, 16s, 16s
                }
            }

            if (is_wp_error($response)) {
                wp_send_json_error(['message' => 'Failed to generate auth token']);
                return;
            }

            $body = json_decode(wp_remote_retrieve_body($response), true);
            $code = wp_remote_retrieve_response_code($response);

            if ($code !== 200 || empty($body['authToken'])) {
                wp_send_json_error(['message' => $body['errorMsg'] ?? 'Auth token generation failed']);
                return;
            }

            wp_send_json_success([
                'authToken' => $body['authToken'],
                'publicKey' => $body['publicKey'],
            ]);
        }

        public function ajax_process_hosted_payment()
        {
            check_ajax_referer('flux_hosted_pay', 'nonce');

            $order_id = isset($_POST['order_id']) ? absint($_POST['order_id']) : 0;
            $card_token = isset($_POST['card_token']) ? sanitize_text_field(wp_unslash($_POST['card_token'])) : '';
            $last_four = isset($_POST['last_four']) ? sanitize_text_field(wp_unslash($_POST['last_four'])) : '';
            $card_brand = isset($_POST['card_brand']) ? sanitize_text_field(wp_unslash($_POST['card_brand'])) : '';

            if (!$order_id || !$card_token) {
                wp_send_json_error(['message' => 'Missing order or card token']);
                return;
            }

            $order = wc_get_order($order_id);
            if (!$order) {
                wp_send_json_error(['message' => 'Invalid order']);
                return;
            }

            // Verify order ownership
            $customer_id = $order->get_customer_id();
            if ($customer_id && $customer_id !== get_current_user_id()) {
                wp_send_json_error(['message' => 'Unauthorized']);
                return;
            }

            // Build products array from order items
            $products = [];
            foreach ($order->get_items() as $item) {
                $product = wc_get_product($item->get_product_id());
                if ($product) {
                    $flux_id = $product->get_meta('flux_product_id');
                    if ($flux_id) {
                        $products[] = [
                            'objectType' => 'product',
                            'id' => (int) $flux_id,
                            'orderQuantity' => (int) $item->get_quantity(),
                        ];
                    }
                }
            }

            if (empty($products)) {
                wp_send_json_error(['message' => 'No synced products found in order']);
                return;
            }

            $credentials = $this->get_credentials();
            $basic_auth = base64_encode($credentials['publicKey'] . ':' . $credentials['aesKey']);

            $payload = [
                'objectType' => 'payment_intent',
                'cardToken' => $card_token,
                'products' => $products,
            ];

            $fee_rate = $this->get_option('service_fee_rate', '');
            if ($fee_rate !== '' && is_numeric($fee_rate) && floatval($fee_rate) > 0) {
                $payload['serviceFeeRate'] = floatval($fee_rate);
            }

            $response = wp_remote_post('https://api.fluxpayments.com/api/post/createPaymentIntent', [
                'timeout' => 30,
                'headers' => [
                    'Content-Type' => 'application/json',
                    'Authorization' => 'Basic ' . $basic_auth,
                ],
                'body' => wp_json_encode($payload),
            ]);

            if (is_wp_error($response)) {
                wp_send_json_error(['message' => 'Payment request failed']);
                return;
            }

            $body = json_decode(wp_remote_retrieve_body($response), true);
            $code = wp_remote_retrieve_response_code($response);

            if ($code !== 200 || empty($body['paymentStatus'])) {
                $error_msg = $body['errorMsg'] ?? $body['declineReason'] ?? 'Payment failed';
                $order->add_order_note('Flux Hosted Fields payment failed: ' . $error_msg);
                wp_send_json_error(['message' => $error_msg]);
                return;
            }

            if ($body['paymentStatus'] !== 'APPROVED') {
                $decline = $body['declineReason'] ?? 'Card declined';
                $order->update_status('failed');
                $order->add_order_note('Flux payment declined: ' . $decline);
                wp_send_json_error(['message' => $decline]);
                return;
            }

            // Payment approved
            $transaction_id = $body['transactionId'] ?? '';
            $order->payment_complete($transaction_id);
            $order->add_order_note(sprintf(
                'Flux Hosted Fields payment completed. Transaction: %s, Card: %s ending %s',
                $transaction_id,
                $card_brand,
                $last_four
            ));
            $order->update_meta_data('flux_transaction_id', $transaction_id);
            $order->update_meta_data('flux_card_last_four', $last_four);
            $order->update_meta_data('flux_card_brand', $card_brand);

            // Populate billing from response
            if (!empty($body['customerFirstName'])) $order->set_billing_first_name(sanitize_text_field($body['customerFirstName']));
            if (!empty($body['customerLastName'])) $order->set_billing_last_name(sanitize_text_field($body['customerLastName']));
            if (!empty($body['customerEmail'])) $order->set_billing_email(sanitize_email($body['customerEmail']));
            if (!empty($body['customerPhone'])) $order->set_billing_phone(sanitize_text_field($body['customerPhone']));
            if (!empty($body['billingAddress'])) $order->set_billing_address_1(sanitize_text_field($body['billingAddress']));
            if (!empty($body['billingCity'])) $order->set_billing_city(sanitize_text_field($body['billingCity']));
            if (!empty($body['billingState'])) $order->set_billing_state(sanitize_text_field($body['billingState']));
            if (!empty($body['billingZip'])) $order->set_billing_postcode(sanitize_text_field($body['billingZip']));
            if (!empty($body['billingCountry'])) $order->set_billing_country(sanitize_text_field($body['billingCountry']));
            $order->save();

            if ($this->get_option('clear_cart', 'yes') === 'yes') {
                WC()->cart->empty_cart();
            }

            wp_send_json_success([
                'redirect' => $this->get_return_url($order),
            ]);
        }

        public function get_icon()
        {
            if ($this->is_hosted_fields_mode()) {
                return '';
            }
            $icon_url = plugins_url('assets/flux-icon.svg', __FILE__);
            $icon = '<img src="' . esc_url($icon_url) . '" alt="Flux" style="width:-webkit-fill-available;height:100px;border-radius:6px;vertical-align:middle;" />';
            return apply_filters('woocommerce_gateway_icon', $icon, $this->id);
        }

        public function payment_fields()
        {
            if (!$this->is_hosted_fields_mode()) {
                echo '<div style="display:none;">Pay Securely with Flux</div>';
                return;
            }
            ?>
            <div id="flux-hosted-fields-form" class="flux-hosted-fields-form">
                <div class="flux-hf-section-title">Card Information</div>

                <div class="flux-hf-row">
                    <label>Card Number</label>
                    <div id="flux-hf-card-number" class="flux-hf-field-container"></div>
                    <div class="flux-hf-error" id="flux-hf-card-number-error"></div>
                </div>

                <div class="flux-hf-row-split">
                    <div class="flux-hf-field">
                        <label>Expiry</label>
                        <div id="flux-hf-card-expiry" class="flux-hf-field-container"></div>
                        <div class="flux-hf-error" id="flux-hf-card-expiry-error"></div>
                    </div>
                    <div class="flux-hf-field">
                        <label>CVV</label>
                        <div id="flux-hf-card-cvv" class="flux-hf-field-container"></div>
                        <div class="flux-hf-error" id="flux-hf-card-cvv-error"></div>
                    </div>
                </div>

                <div class="flux-hf-row">
                    <label>Name on Card</label>
                    <div id="flux-hf-card-name" class="flux-hf-field-container"></div>
                    <div class="flux-hf-error" id="flux-hf-card-name-error"></div>
                </div>

                <div class="flux-hf-row">
                    <label>Email </label>
                    <div id="flux-hf-email" class="flux-hf-field-container"></div>
                    <div class="flux-hf-error" id="flux-hf-email-error"></div>
                </div>

                <div class="flux-hf-row">
                    <label>Phone</label>
                    <div id="flux-hf-phone" class="flux-hf-field-container"></div>
                    <div class="flux-hf-error" id="flux-hf-phone-error"></div>
                </div>

                <div class="flux-hf-section-title">Billing Address</div>

                <div class="flux-hf-row flux-hf-address-wrapper">
                    <label>Street Address</label>
                    <div id="flux-hf-billing-address" class="flux-hf-field-container"></div>
                    <div id="flux-hf-address-suggestions" class="flux-hf-suggestions-dropdown"></div>
                    <div class="flux-hf-error" id="flux-hf-billing-address-error"></div>
                </div>

                <div class="flux-hf-row">
                    <label>Apt / Suite <span class="flux-hf-optional">(optional)</span></label>
                    <div id="flux-hf-billing-address2" class="flux-hf-field-container"></div>
                </div>

                <div class="flux-hf-row-split">
                    <div class="flux-hf-field">
                        <label>City</label>
                        <div id="flux-hf-billing-city" class="flux-hf-field-container"></div>
                        <div class="flux-hf-error" id="flux-hf-billing-city-error"></div>
                    </div>
                    <div class="flux-hf-field">
                        <label>State</label>
                        <div id="flux-hf-billing-state" class="flux-hf-field-container"></div>
                        <div class="flux-hf-error" id="flux-hf-billing-state-error"></div>
                    </div>
                </div>

                <div class="flux-hf-row-split">
                    <div class="flux-hf-field">
                        <label>ZIP Code</label>
                        <div id="flux-hf-billing-zip" class="flux-hf-field-container"></div>
                        <div class="flux-hf-error" id="flux-hf-billing-zip-error"></div>
                    </div>
                    <div class="flux-hf-field">
                        <label>Country</label>
                        <div id="flux-hf-billing-country" class="flux-hf-field-container"></div>
                        <div class="flux-hf-error" id="flux-hf-billing-country-error"></div>
                    </div>
                </div>

                <input type="hidden" name="flux_card_token" id="flux_card_token" value="" />
                <input type="hidden" name="flux_card_last_four" id="flux_card_last_four" value="" />
                <input type="hidden" name="flux_card_brand" id="flux_card_brand" value="" />

                <div id="flux-hf-auth-status" class="flux-hf-auth-status" style="display:none;">
                    <span class="flux-hf-spinner"></span> Authorizing card...
                </div>
                <div id="flux-hf-error-msg" class="flux-hf-error-msg" style="display:none;"></div>
            </div>
            <?php
        }


        public function render_flux_checkout_button(): void
        {
            // Re-use WC’s filter so merchants can still override text
            $label = apply_filters(
                'woocommerce_order_button_text',
                __('Pay With Flux', 'flux-payments-gateway')
            );

            printf(
                '<div id="flux-submit-button-container" style="display:none;">
                    <button id="place_order" type="button"
                        class="button alt flux-order-button wp-element-button">
                        %1$s
                    </button>
                </div>',
                esc_html($label)
            );
        }

        public function render_hosted_fields_modal()
        {
            if (!$this->is_hosted_fields_mode()) {
                return;
            }
            // Don't render modal on checkout page (it uses inline fields)
            if (is_checkout() && !is_wc_endpoint_url()) {
                return;
            }
            ?>
            <div id="flux-hf-modal-overlay" class="flux-hf-modal-overlay" style="display:none;">
                <div class="flux-hf-modal">
                    <div class="flux-hf-modal-header">
                        <span class="flux-hf-modal-title">Complete Payment</span>
                        <button type="button" class="flux-hf-modal-close" aria-label="Close">&times;</button>
                    </div>
                    <div class="flux-hf-modal-body">
                        <div class="flux-hf-section-title">Card Information</div>

                        <div class="flux-hf-row">
                            <label>Card Number</label>
                            <div id="flux-hf-modal-card-number" class="flux-hf-field-container"></div>
                            <div class="flux-hf-error" id="flux-hf-modal-card-number-error"></div>
                        </div>

                        <div class="flux-hf-row-split">
                            <div class="flux-hf-field">
                                <label>Expiry</label>
                                <div id="flux-hf-modal-card-expiry" class="flux-hf-field-container"></div>
                                <div class="flux-hf-error" id="flux-hf-modal-card-expiry-error"></div>
                            </div>
                            <div class="flux-hf-field">
                                <label>CVV</label>
                                <div id="flux-hf-modal-card-cvv" class="flux-hf-field-container"></div>
                                <div class="flux-hf-error" id="flux-hf-modal-card-cvv-error"></div>
                            </div>
                        </div>

                        <div class="flux-hf-row">
                            <label>Name on Card</label>
                            <div id="flux-hf-modal-card-name" class="flux-hf-field-container"></div>
                            <div class="flux-hf-error" id="flux-hf-modal-card-name-error"></div>
                        </div>

                        <div class="flux-hf-row">
                            <label>Email </label>
                            <div id="flux-hf-modal-email" class="flux-hf-field-container"></div>
                            <div class="flux-hf-error" id="flux-hf-modal-email-error"></div>
                        </div>

                        <div class="flux-hf-row">
                            <label>Phone</label>
                            <div id="flux-hf-modal-phone" class="flux-hf-field-container"></div>
                            <div class="flux-hf-error" id="flux-hf-modal-phone-error"></div>
                        </div>

                        <div class="flux-hf-section-title">Billing Address</div>

                        <div class="flux-hf-row flux-hf-address-wrapper">
                            <label>Street Address</label>
                            <div id="flux-hf-modal-billing-address" class="flux-hf-field-container"></div>
                            <div id="flux-hf-modal-address-suggestions" class="flux-hf-suggestions-dropdown"></div>
                            <div class="flux-hf-error" id="flux-hf-modal-billing-address-error"></div>
                        </div>

                        <div class="flux-hf-row">
                            <label>Apt / Suite <span class="flux-hf-optional">(optional)</span></label>
                            <div id="flux-hf-modal-billing-address2" class="flux-hf-field-container"></div>
                        </div>

                        <div class="flux-hf-row-split">
                            <div class="flux-hf-field">
                                <label>City</label>
                                <div id="flux-hf-modal-billing-city" class="flux-hf-field-container"></div>
                                <div class="flux-hf-error" id="flux-hf-modal-billing-city-error"></div>
                            </div>
                            <div class="flux-hf-field">
                                <label>State</label>
                                <div id="flux-hf-modal-billing-state" class="flux-hf-field-container"></div>
                                <div class="flux-hf-error" id="flux-hf-modal-billing-state-error"></div>
                            </div>
                        </div>

                        <div class="flux-hf-row-split">
                            <div class="flux-hf-field">
                                <label>ZIP Code</label>
                                <div id="flux-hf-modal-billing-zip" class="flux-hf-field-container"></div>
                                <div class="flux-hf-error" id="flux-hf-modal-billing-zip-error"></div>
                            </div>
                            <div class="flux-hf-field">
                                <label>Country</label>
                                <div id="flux-hf-modal-billing-country" class="flux-hf-field-container"></div>
                                <div class="flux-hf-error" id="flux-hf-modal-billing-country-error"></div>
                            </div>
                        </div>

                        <div id="flux-hf-modal-auth-status" class="flux-hf-auth-status" style="display:none;">
                            <span class="flux-hf-spinner"></span> Authorizing card...
                        </div>
                        <div id="flux-hf-modal-error-msg" class="flux-hf-error-msg" style="display:none;"></div>
                    </div>
                    <div class="flux-hf-modal-footer">
                        <button type="button" id="flux-hf-modal-pay-btn" class="flux-hf-modal-pay-btn" disabled>
                            Pay Now
                        </button>
                    </div>
                </div>
            </div>
            <?php
        }
    }

}


add_filter('woocommerce_payment_gateways', 'add_flux_gateway_class');
function add_flux_gateway_class($methods)
{
    $methods[] = 'WC_Gateway_Flux';
    return $methods;
}

/**
 * Frontend asset enqueueing.
 *
 * Registered at file scope so it runs regardless of when WC instantiates the
 * gateway class. The previous implementation registered this from inside
 * WC_Gateway_Flux::__construct() — but on the cart page WC doesn't load
 * payment gateways until something explicitly asks for them, which doesn't
 * happen until our cart-button render hook runs (after wp_enqueue_scripts has
 * already fired). Result: no JS on the cart page → Pay Now button dead.
 *
 * Reads gateway settings directly from wp_options so we don't need the
 * gateway instance.
 */
add_action('wp_enqueue_scripts', 'flux_enqueue_frontend_assets');
function flux_enqueue_frontend_assets() {
    $opts = get_option('woocommerce_flux_gateway_settings');
    if (empty($opts) || empty($opts['enabled']) || $opts['enabled'] !== 'yes') {
        return;
    }

    $is_hosted_fields = isset($opts['checkout_experience']) && $opts['checkout_experience'] === 'hosted_fields';

    wp_enqueue_style(
        'flux-paynow-styles',
        plugins_url('assets/flux-paynow.css', __FILE__),
        [],
        '1.1.1'
    );

    if ($is_hosted_fields) {
        wp_enqueue_style(
            'flux-hosted-checkout-styles',
            plugins_url('assets/flux-hosted-checkout.css', __FILE__),
            [],
            '1.0.0'
        );

        $accent_raw = isset($opts['accent_color']) ? $opts['accent_color'] : '#0f9a7b';
        $btn_raw    = isset($opts['button_color']) ? $opts['button_color'] : '#023857';
        $accent = preg_match('/^#[0-9a-fA-F]{6}$/', $accent_raw) ? $accent_raw : '#0f9a7b';
        $btn_bg = preg_match('/^#[0-9a-fA-F]{6}$/', $btn_raw) ? $btn_raw : '#023857';
        $ah = ltrim($accent, '#');
        $ar = hexdec(substr($ah, 0, 2));
        $ag = hexdec(substr($ah, 2, 2));
        $ab = hexdec(substr($ah, 4, 2));
        wp_add_inline_style(
            'flux-hosted-checkout-styles',
            ":root{--flux-accent:{$accent};--flux-accent-ring:rgba({$ar},{$ag},{$ab},0.08);--flux-btn-bg:{$btn_bg};}"
        );

        wp_enqueue_script(
            'flux-hosted-fields-sdk',
            'https://payments.fluxpayments.com/hosted-fields/flux-hosted-fields.js',
            [],
            null,
            true
        );

        wp_enqueue_script(
            'flux-hosted-checkout',
            plugins_url('assets/flux-hosted-checkout.js', __FILE__),
            ['flux-hosted-fields-sdk', 'jquery'],
            '1.0.7',
            true
        );

        $customer = function_exists('WC') && WC() && WC()->customer ? WC()->customer : null;
        $hosted_boot = [
            'ajax_url'        => admin_url('admin-ajax.php'),
            'auth_nonce'      => wp_create_nonce('flux_hosted_auth'),
            'pay_nonce'       => wp_create_nonce('flux_hosted_pay'),
            'checkout_nonce'  => wp_create_nonce('woocommerce-process_checkout'),
            'checkout_url'    => function_exists('wc_get_checkout_url') ? wc_get_checkout_url() : '',
            'is_checkout'     => function_exists('is_checkout') ? is_checkout() : false,
            'is_cart'         => function_exists('is_cart') ? is_cart() : false,
            'prefill' => [
                'billing_email'      => $customer ? $customer->get_billing_email() : '',
                'billing_first_name' => $customer ? $customer->get_billing_first_name() : '',
                'billing_last_name'  => $customer ? $customer->get_billing_last_name() : '',
                'billing_phone'      => $customer ? $customer->get_billing_phone() : '',
            ],
        ];
        wp_add_inline_script(
            'flux-hosted-checkout',
            'window.FLUX_HOSTED=' . wp_json_encode($hosted_boot) . ';',
            'before'
        );
    }

    wp_enqueue_script(
        'flux-paynow-script',
        plugins_url('assets/flux-paynow.js', __FILE__),
        ['jquery'],
        '1.1.1',
        true
    );

    $customer = function_exists('WC') && WC() && WC()->customer ? WC()->customer : null;
    $boot = [
        'ajax_url'      => class_exists('WC_AJAX') ? \WC_AJAX::get_endpoint('checkout') : '',
        'nonce'         => wp_create_nonce('woocommerce-process_checkout'),
        'checkout_url'  => function_exists('wc_get_checkout_url') ? wc_get_checkout_url() : '',
        'icon'          => plugins_url('assets/flux-icon.svg', __FILE__),
        'mode'          => $is_hosted_fields ? 'hosted_fields' : 'redirect',
        'cart_nonce'    => wp_create_nonce('flux_cart_checkout'),
        'cart_ajax_url' => admin_url('admin-ajax.php'),
        'prefill' => [
            'billing_email'      => $customer ? $customer->get_billing_email() : '',
            'billing_first_name' => $customer ? $customer->get_billing_first_name() : '',
            'billing_last_name'  => $customer ? $customer->get_billing_last_name() : '',
        ],
    ];
    wp_add_inline_script(
        'flux-paynow-script',
        'window.FLUX_PAYNOW=' . wp_json_encode($boot) . ';',
        'before'
    );
}


add_filter('woocommerce_checkout_fields', function ($fields) {
    $fields['billing'] = [];
    $fields['shipping'] = [];
    if (isset($fields['order']['order_comments'])) {
        unset($fields['order']['order_comments']);
    }
    return $fields;
});

add_action('wp', function () {
    remove_action('woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10);
    remove_action('woocommerce_checkout_order_review', 'woocommerce_order_review', 10);
});

add_filter('woocommerce_cart_needs_shipping', '__return_false');
add_filter('woocommerce_cart_needs_shipping_address', '__return_false');
add_filter('woocommerce_checkout_show_shipping', '__return_false');
add_filter('woocommerce_checkout_show_billing', '__return_false');

// This CSS is now included in flux-paynow.css

add_action('template_redirect', function () {
    // Only process on order-received pages
    if (!is_wc_endpoint_url('order-received')) {
        return;
    }

    $order_id = absint(get_query_var('order-received'));
    $transaction_id = isset($_GET['transactionId']) ? sanitize_text_field(wp_unslash($_GET['transactionId'])) : null;

    // If no transaction ID, this isn't a Flux callback
    if (!$order_id || !$transaction_id) {
        return;
    }

    $order = wc_get_order($order_id);
    if (!$order || !in_array($order->get_status(), ['pending', 'processing'])) {
        return;
    }

    // Verify order key for security (this is how WooCommerce normally validates order access)
    $order_key = isset($_GET['key']) ? sanitize_text_field(wp_unslash($_GET['key'])) : '';
    if (!$order_key || !hash_equals($order->get_order_key(), $order_key)) {
        wp_die(__('You do not have permission to view this order.', 'flux-payments-gateway'));
    }

    // Additional nonce verification if present (for extra security)
    $nonce = isset($_GET['flux_nonce']) ? sanitize_text_field(wp_unslash($_GET['flux_nonce'])) : '';
    if ($nonce && !wp_verify_nonce($nonce, 'flux_transaction_' . $order_id)) {
        wp_die(__('Security check failed. Invalid transaction verification.', 'flux-payments-gateway'));
    }

    if ($order->get_meta('_flux_thankyou_handled') === 'yes') {
        return;
    }

    if (class_exists('WC_Gateway_Flux')) {
        $gateway = new WC_Gateway_Flux();
        $gateway->thankyou_page($order, $transaction_id);
    }

    $order->update_meta_data('_flux_thankyou_handled', 'yes');
    $order->save();
});


add_action('admin_enqueue_scripts', function ($hook) {
    $screen = get_current_screen();
    if ($screen && $screen->id === 'woocommerce_page_wc-settings') {
        wp_enqueue_script(
            'flux-admin-script',
            plugins_url('assets/flux-admin.js', __FILE__),
            ['jquery'],
            '1.0.0',
            true
        );
        
        wp_localize_script('flux-admin-script', 'flux_admin', [
            'nonce' => wp_create_nonce('flux_sync_products'),
            'ajaxurl' => admin_url('admin-ajax.php')
        ]);
    }
});

add_action('wp_ajax_flux_sync_products', function () {
    check_ajax_referer('flux_sync_products');
    $args = array('post_type' => 'product', 'posts_per_page' => -1, 'fields' => 'ids');
    $products = get_posts($args);
    foreach ($products as $product_id) {
        (new WC_Gateway_Flux())->put_or_post_product($product_id);
    }
    wp_send_json_success('All products synced!');
});

add_action('wp_enqueue_scripts', function () {
    if (is_checkout()) {
        wp_enqueue_style(
            'flux-checkout',
            plugins_url('assets/flux-checkout.css', __FILE__),
            [],
            '1.0'
        );
    }
    
    // Enqueue scripts for cart page Flux button
    if (is_cart()) {
        wp_enqueue_script('jquery');
        // Make sure WooCommerce checkout params are available
        wp_localize_script('jquery', 'wc_checkout_params', [
            'ajax_url' => admin_url('admin-ajax.php')
        ]);
        
        // Add CSS to hide the default checkout button
        wp_add_inline_style('woocommerce-general', '
            .wc-proceed-to-checkout .checkout-button,
            .cart .checkout-button,
            .woocommerce-cart .checkout-button {
                display: none !important;
            }
        ');
    }
});


add_filter('woocommerce_order_button_text', function ($text) {
    return 'Pay With Flux';
});

add_filter('woocommerce_order_button_html', function ($button_html) {
    return str_replace('class="button', 'class="button flux-primary-btn', $button_html);
});

// Remove the default "Proceed to Checkout" button from cart page
add_action('wp', function() {
    if (is_cart()) {
        // Remove the checkout button action
        remove_action('woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20);
    }
});

// Disable all coupon functionality
add_filter('woocommerce_coupons_enabled', '__return_false');

// Remove coupon form from cart page
add_action('wp', function() {
    remove_action('woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10);
    // Don't remove cart totals - we need those for the Pay Now button
});

// Remove coupon field from checkout
add_filter('woocommerce_checkout_coupon_message', '__return_empty_string');

// Hide coupon-related elements with CSS
add_action('wp_head', function() {
    if (is_cart() || is_checkout()) {
        echo '<style>
            .woocommerce-form-coupon-toggle,
            .woocommerce-form-coupon,
            .checkout_coupon,
            .coupon,
            .woocommerce-remove-coupon,
            .cart-discount,
            .order-discount,
            .wc-block-components-totals-coupon,
            .wc-block-components-totals-discount,
            .woocommerce-cart-form .coupon,
            .woocommerce-checkout .coupon,
            .cart_totals .coupon,
            .shop_table .coupon,
            .woocommerce-coupon-data,
            .woocommerce-coupon-description,
            .coupon-info,
            .discount-info,
            .wc-coupon-form,
            .apply-coupon {
                display: none !important;
            }
        </style>';
    }
});

// Remove coupon functionality from admin
add_action('admin_init', function() {
    // Remove coupon menu from admin
    remove_menu_page('edit.php?post_type=shop_coupon');
});

// Disable coupon creation and usage completely
add_filter('wc_coupons_enabled', '__return_false');
add_filter('woocommerce_cart_totals_coupon_html', '__return_empty_string');
add_filter('woocommerce_cart_totals_coupon_label', '__return_empty_string');

// Add Flux Payments button to cart page
add_action('woocommerce_proceed_to_checkout', 'flux_add_cart_checkout_button');

function flux_add_cart_checkout_button() {
    // Only show if Flux gateway is enabled
    $gateways = WC()->payment_gateways->get_available_payment_gateways();
    if (!isset($gateways['flux_gateway']) || $gateways['flux_gateway']->enabled !== 'yes') {
        return;
    }
    $gw = $gateways['flux_gateway'];

    // Create a nonce for security
    $nonce = wp_create_nonce('flux_cart_checkout');

    // Use the merchant-configured button color (falls back to accent, then to
    // the historical lime). Pick a readable text color (black on light, white
    // on dark) using a quick luminance check on the chosen background.
    $btn_raw    = $gw->get_option('button_color', '');
    $accent_raw = $gw->get_option('accent_color', '');
    $bg = preg_match('/^#[0-9a-fA-F]{6}$/', $btn_raw)    ? $btn_raw
        : (preg_match('/^#[0-9a-fA-F]{6}$/', $accent_raw) ? $accent_raw
        : '#b6ff00');
    $hex = ltrim($bg, '#');
    $r = hexdec(substr($hex, 0, 2));
    $g = hexdec(substr($hex, 2, 2));
    $b = hexdec(substr($hex, 4, 2));
    // Standard relative-luminance approximation; threshold chosen to put
    // both lime and dark navy on the right side of "readable".
    $luma = (0.299 * $r + 0.587 * $g + 0.114 * $b) / 255;
    $fg = $luma > 0.6 ? '#000' : '#fff';

    $style = sprintf(
        'margin-left:10px;background:%s;color:%s;font-weight:bold;',
        esc_attr($bg),
        esc_attr($fg)
    );

    echo '<a href="#"
            id="flux-cart-checkout-btn"
            class="button alt flux-cart-checkout"
            style="' . $style . '"
            data-nonce="' . esc_attr($nonce) . '">
            Pay Now
          </a>';
    
    // In hosted fields mode, flux-hosted-checkout.js handles this button
    if ($gateways['flux_gateway']->get_option('checkout_experience') === 'hosted_fields') {
        return;
    }

    // Redirect mode: inline JavaScript to handle the button click.
    //
    // Uses event delegation on document so it works even when the theme
    // renders cart totals via AJAX (button isn't in the DOM at ready time).
    // Reads ajax_url from FLUX_PAYNOW.cart_ajax_url which is localized on
    // every page — wc_checkout_params is only defined on /checkout.
    ?>
    <script type="text/javascript">
    jQuery(function($) {
        var originalText = 'Pay Now';

        $(document).on('click', '#flux-cart-checkout-btn, .flux-cart-checkout', function(e) {
            e.preventDefault();
            e.stopPropagation();

            var $button = $(this);
            if ($button.prop('disabled')) return;

            var ajaxUrl = (window.FLUX_PAYNOW && window.FLUX_PAYNOW.cart_ajax_url)
                || (window.wc_checkout_params && window.wc_checkout_params.ajax_url);

            if (!ajaxUrl) {
                console.error('[Flux] No ajax_url available — flux-paynow not loaded?');
                alert('Checkout is not ready yet. Please refresh the page and try again.');
                return;
            }

            $button.text('Processing...').prop('disabled', true);

            $.ajax({
                url: ajaxUrl,
                type: 'POST',
                data: {
                    action: 'flux_create_cart_order',
                    nonce: $button.data('nonce')
                },
                success: function(response) {
                    if (response && response.success && response.data && response.data.redirect_url) {
                        window.location.href = response.data.redirect_url;
                    } else {
                        var msg = (response && response.data && response.data.message) || 'Failed to create order';
                        alert('Error: ' + msg);
                        $button.text(originalText).prop('disabled', false);
                    }
                },
                error: function() {
                    alert('Network error. Please try again.');
                    $button.text(originalText).prop('disabled', false);
                }
            });
        });

        // Reset the button label after a back-button bfcache restore.
        $(window).on('pageshow', function(event) {
            if (event.originalEvent && event.originalEvent.persisted) {
                $('#flux-cart-checkout-btn, .flux-cart-checkout').text(originalText).prop('disabled', false);
            }
        });
    });
    </script>
    <?php
}

// Handle AJAX request to create order from cart
add_action('wp_ajax_flux_create_cart_order', 'flux_handle_cart_checkout');
add_action('wp_ajax_nopriv_flux_create_cart_order', 'flux_handle_cart_checkout');

// Hosted Fields AJAX endpoints (registered globally so they fire during admin-ajax.php)
add_action('wp_ajax_flux_hosted_auth', 'flux_hosted_auth_handler');
add_action('wp_ajax_nopriv_flux_hosted_auth', 'flux_hosted_auth_handler');
function flux_hosted_auth_handler() {
    if (!class_exists('WC_Gateway_Flux')) return;
    (new WC_Gateway_Flux())->ajax_generate_auth_token();
}

add_action('wp_ajax_flux_hosted_pay', 'flux_hosted_pay_handler');
add_action('wp_ajax_nopriv_flux_hosted_pay', 'flux_hosted_pay_handler');
function flux_hosted_pay_handler() {
    if (!class_exists('WC_Gateway_Flux')) return;
    (new WC_Gateway_Flux())->ajax_process_hosted_payment();
}

// Re-issue all the nonces the front-end uses, tied to the current session/user
// cookie. Called by flux-hosted-checkout.js on a timer so a customer sitting
// on the checkout page doesn't see "your session has expired" when they
// finally hit Place Order. Unauthenticated by design — wp_create_nonce binds
// to the cookie identity, so no extra privilege is granted here.
add_action('wp_ajax_flux_refresh_nonces', 'flux_refresh_nonces_handler');
add_action('wp_ajax_nopriv_flux_refresh_nonces', 'flux_refresh_nonces_handler');
function flux_refresh_nonces_handler() {
    wp_send_json_success([
        'auth_nonce'     => wp_create_nonce('flux_hosted_auth'),
        'pay_nonce'      => wp_create_nonce('flux_hosted_pay'),
        'cart_nonce'     => wp_create_nonce('flux_cart_checkout'),
        'checkout_nonce' => wp_create_nonce('woocommerce-process_checkout'),
    ]);
}

function flux_handle_cart_checkout() {
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'], 'flux_cart_checkout')) {
        wp_send_json_error(['message' => 'Security check failed']);
        return;
    }
    
    // Check if cart is not empty
    if (WC()->cart->is_empty()) {
        wp_send_json_error(['message' => 'Cart is empty']);
        return;
    }
    
    try {
        // Create order from cart
        $checkout = WC()->checkout();
        
        // Set payment method to Flux
        $_POST['payment_method'] = 'flux_gateway';
        
        // Create the order
        $order_id = $checkout->create_order([
            'payment_method' => 'flux_gateway'
        ]);
        
        if (is_wp_error($order_id)) {
            wp_send_json_error(['message' => $order_id->get_error_message()]);
            return;
        }
        
        // Get the Flux gateway instance
        $gateways = WC()->payment_gateways->get_available_payment_gateways();
        $flux_gateway = $gateways['flux_gateway'];

        // Hosted Fields mode: create order only, modal handles payment
        if ($flux_gateway->get_option('checkout_experience') === 'hosted_fields') {
            wp_send_json_success([
                'message' => 'Order created',
                'order_id' => $order_id,
                'redirect_url' => null,
                'mode' => 'hosted_fields',
            ]);
            return;
        }

        // Redirect mode: process payment (creates Flux payment link)
        $result = $flux_gateway->process_payment($order_id);

        wp_send_json_success(['message' => 'Payment processed successfully', 'redirect_url' => $result['redirect'] ?? null, 'order_id' => $order_id ]);
    } catch (Exception $e) {
        wp_send_json_error(['message' => $e->getMessage()]);
    }
}
