<?php

/**
 * PeachPay NMI Card Gateway
 * @package PeachPay
 */

if (! defined('ABSPATH')) {
    exit;
}

require_once PEACHPAY_ABSPATH . 'core/abstract/class-peachpay-payment-gateway.php';

class PeachPay_NMI_Card_Gateway extends PeachPay_Payment_Gateway
{
    private $initialized = false;

    public function __construct()
    {
        $this->id = 'peachpay_nmi_card';
        $this->title = __('Credit / Debit Card', 'peachpay-for-woocommerce');
        $this->description = __(
            'Pay securely using your credit or debit card. Card details are safely tokenized and processed via NMI.',
            'peachpay-for-woocommerce'
        );
        $this->method_title = sprintf(__('%s (NMI via PeachPay)', 'peachpay-for-woocommerce'), 'Card');
        $this->method_description = __(
            'Accept credit and debit card payments through NMI using PeachPay. Supports secure tokenization via Collect.js and Direct Post processing.',
            'peachpay-for-woocommerce'
        );
        $this->has_fields = true;
        $this->supports = array('products', 'refunds');
        $this->icon = '';
        $this->icons = array();
        $this->payment_provider = 'NMI';
        $this->min_amount = 0.50;
        parent::__construct();

        add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
        add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
        add_action('admin_notices', array($this, 'admin_notices'));
        add_action('wp_head', array($this, 'add_order_overview_styles'));

        // Initialize form fields
        $this->init_form_fields();

        // Mark as initialized
        $this->initialized = true;
    }

    /**
     * Initialize gateway form fields.
     */
    public function init_form_fields()
    {
        parent::init_form_fields();

        // Add NMI-specific fields
        $this->form_fields = array_merge(
            $this->form_fields,
            array(
                'api_keys_section' => array(
                    'title' => __('API Keys', 'peachpay-for-woocommerce'),
                    'type'  => 'title',
                ),
                'private_key' => array(
                    'title'       => __('Private Key', 'peachpay-for-woocommerce'),
                    'type'        => 'password',
                    'description' => __(
                        'Required for all payment methods. This key is used for server-side authentication and is mandatory for both Direct Post and Collect.js.',
                        'peachpay-for-woocommerce'
                    ),
                    'default'     => '',
                    'desc_tip'    => true,
                ),
                'public_tokenization_key' => array(
                    'title'       => __('Public Tokenization Key', 'peachpay-for-woocommerce'),
                    'type'        => 'text',
                    'description' => __(
                        'Optional. Enables Collect.js (PCI-compliant tokenization). Requires a valid Private Key to be configured. If left empty, payments will fall back to Direct Post.',
                        'peachpay-for-woocommerce'
                    ),
                    'default'     => '',
                    'desc_tip'    => true,
                ),
            )
        );
    }
    
    /**
     * Gets the minimum charge with proper formatting
     * @return string
     */
    public function get_minimum_charge()
    {
        $min_charge = parent::get_minimum_charge();
        return number_format((float) $min_charge, 2, '.', '');
    }

    /**
     * Check if gateway needs setup.
     *
     * Private key is ALWAYS required (both Direct Post and Collect.js need it for API calls).
     * Collect.js additionally requires the public tokenization key for frontend tokenization.
     *
     * @return bool True if setup is needed, false if properly configured.
     */
    public function needs_setup()
    {
        // Private key is always required for NMI API authentication
        $private_key = $this->get_option('private_key', '');
        if (empty($private_key)) {
            return true;
        }

        // Collect.js mode also requires public tokenization key
        if ($this->get_active_api_tab() === 'collectjs') {
            $public_tokenization_key = $this->get_option('public_tokenization_key', '');
            return empty($public_tokenization_key);
        }

        return false;
    }

    /**
     * Check if the gateway is available for use.
     *
     * @param boolean $skip_cart_check Whether to skip cart validation.
     * @return boolean True if available, false otherwise.
     */
    public function is_available($skip_cart_check = false)
    {
        if (!$this->initialized) {
            return false;
        }

        // Let parent handle all standard WooCommerce checks
        return parent::is_available($skip_cart_check);
    }

    /**
     * Get NMI configuration.
     * @return array
     */
    protected function get_nmi_config()
    {
        $config = PeachPay_NMI_Integration::config();

        // IMPORTANT: Always load the private key (security_key)
        // Both Collect.js AND Direct Post need it to process payments via NMI API
        // - Direct Post: uses it to send card data directly
        // - Collect.js: uses it to charge the tokenized card
        $private_key = $this->get_option('private_key', '');
        if (!empty($private_key)) {
            $config['api_key'] = $private_key;
        }

        // Load public tokenization key (only needed for Collect.js frontend)
        $public_tokenization_key = $this->get_option('public_tokenization_key', '');
        if (!empty($public_tokenization_key)) {
            $config['public_tokenization_key'] = $public_tokenization_key;
        }

        return $config;
    }

    /**
     * Get gateway setting value
     * @param string $key Setting key
     * @param mixed $default Default value
     * @return mixed
     */
    protected function get_gateway_setting($key, $default = '')
    {
        return $this->get_option($key, $default);
    }

    /**
     * Check if test mode is enabled
     * @return bool
     */
    protected function is_test_mode()
    {
        return $this->get_option('test_mode', 'no') === 'yes';
    }

    /**
     * Override the checkout title shown for this gateway.
     */
    public function get_title_filter($title, $id)
    {
        if ($id === $this->id) {
            return $this->get_option('title', $title);
        }

        return $title;
    }

    /**
     * Get transaction ID from request
     */
    private function get_transaction_id_from_request()
    {
        // Method 1: Classic checkout - check POST data
        if (isset($_POST['peachpay_transaction_id']) && !empty($_POST['peachpay_transaction_id'])) {
            return sanitize_text_field($_POST['peachpay_transaction_id']);
        }

        // Method 2: WooCommerce Blocks
        $payment_method = $_POST['payment_method'] ?? '';
        if ($payment_method === 'peachpay_nmi_card') {
            $possible_locations = [
                'payment_method_data',
                'wc-peachpay_nmi_card-transaction-id',
                'peachpay_nmi_card_transaction_id',
                'meta',
                'paymentMethodData'
            ];

            foreach ($possible_locations as $location) {
                if (isset($_POST[$location])) {
                    $data = $_POST[$location];

                    if (is_string($data)) {
                        $decoded = json_decode(stripslashes($data), true);
                        if ($decoded && isset($decoded['peachpay_transaction_id'])) {
                            return sanitize_text_field($decoded['peachpay_transaction_id']);
                        }
                    } elseif (is_array($data) && isset($data['peachpay_transaction_id'])) {
                        return sanitize_text_field($data['peachpay_transaction_id']);
                    }
                }
            }
        }

        // Method 3: Session fallback
        if (function_exists('WC') && WC()->session) {
            $wc_transaction_id = WC()->session->get('peachpay_transaction_id');
            if (!empty($wc_transaction_id)) {
                return sanitize_text_field($wc_transaction_id);
            }
        }

        return '';
    }

    /**
     * Create fallback transaction ID if missing
     * Following ConvesioPay pattern - allows server-side transaction creation
     *
     * @return string Transaction ID
     */
    private function create_fallback_transaction_id()
    {
        // Generate a transaction ID based on current time and random number
        $timestamp = time();
        $random = wp_rand(1000, 9999);
        $transaction_id = 'nmi_tx_' . $timestamp . '_' . $random;

        return $transaction_id;
    }

    /**
     * Get payment token from request
     */
    private function get_payment_token_from_request()
    {
        // Method 1: Classic checkout
        if (isset($_POST['nmi_payment_token']) && !empty($_POST['nmi_payment_token'])) {
            return sanitize_text_field($_POST['nmi_payment_token']);
        }

        // Method 2: WooCommerce Blocks
        $payment_method = $_POST['payment_method'] ?? '';
        if ($payment_method === 'peachpay_nmi_card') {
            $possible_locations = [
                'payment_method_data',
                'wc-peachpay_nmi_card-payment-token',
                'nmi_payment_token',
                'paymentMethodData'
            ];

            foreach ($possible_locations as $location) {
                if (isset($_POST[$location])) {
                    $data = $_POST[$location];

                    if (is_string($data)) {
                        $decoded = json_decode(stripslashes($data), true);
                        if ($decoded && isset($decoded['nmi_payment_token'])) {
                            return sanitize_text_field($decoded['nmi_payment_token']);
                        }
                    } elseif (is_array($data) && isset($data['nmi_payment_token'])) {
                        return sanitize_text_field($data['nmi_payment_token']);
                    }
                }
            }
        }

        return '';
    }

    /**
     * Add scripts for NMI integration
     */
    public function enqueue_scripts()
    {
        // Only load on checkout page and if gateway is enabled
        if (!is_checkout() || $this->enabled !== 'yes') {
            return;
        }

        // Determine active mode
        $active_api_tab = $this->get_active_api_tab();
        $is_collectjs_mode = ($active_api_tab === 'collectjs');
        $is_direct_post_mode = ($active_api_tab === 'directapi');

        // Get keys
        $public_tokenization_key = $this->get_option('public_tokenization_key', '');
        $private_key = $this->get_option('private_key', '');

        // For Direct Post mode, we don't need any JavaScript - the form fields are plain HTML
        // and processed server-side. Only load scripts for Collect.js mode.
        if ($is_direct_post_mode) {
            // Direct Post mode: Only enqueue CSS for styling the form fields
            $css_path = PEACHPAY_ABSPATH . 'core/payments/nmi/assets/css/checkout.css';
            if (file_exists($css_path)) {
                wp_enqueue_style(
                    'peachpay-nmi-checkout',
                    plugins_url('peachpay-for-woocommerce/core/payments/nmi/assets/css/checkout.css'),
                    array(),
                    filemtime($css_path)
                );
            }
            return;
        }

        // Collect.js mode - load all scripts
        // Get configuration
        $config = $this->get_nmi_config();
        if (empty($config)) {
            return;
        }

        // Load Collect.js for secure tokenization (PCI SAQ-A compliant)
        if (! empty($public_tokenization_key)) {
            $collect_js_url = PeachPay_NMI_Integration::get_collect_js_url();
            wp_register_script(
                'nmi-collect-js',
                $collect_js_url,
                array(),
                '1.0.0',
                true
            );

            // Add data-tokenization-key and data-variant="inline" attributes to Collect.js script tag
            // data-variant="inline" enables automatic field rendering
            $GLOBALS['nmi_collect_js_tokenization_key'] = trim($public_tokenization_key);

            // Add filter only once
            if (! has_filter('script_loader_tag', 'nmi_add_collect_js_tokenization_key')) {
                add_filter('script_loader_tag', 'nmi_add_collect_js_tokenization_key', 10, 2);
            }

            // Store public key globally for JavaScript access (as fallback if data attribute doesn't work)
            wp_add_inline_script(
                'nmi-collect-js',
                "window.NMI_PUBLIC_KEY = " . wp_json_encode(trim($public_tokenization_key)) . ";",
                'before'
            );

            // Enqueue Collect.js
            wp_enqueue_script('nmi-collect-js');

            // Enqueue NMI checkout CSS for Collect.js field styling
            $css_path = PEACHPAY_ABSPATH . 'core/payments/nmi/assets/css/checkout.css';
            if (file_exists($css_path)) {
                wp_enqueue_style(
                    'peachpay-nmi-checkout',
                    plugins_url('peachpay-for-woocommerce/core/payments/nmi/assets/css/checkout.css'),
                    array(),
                    filemtime($css_path)
                );
            }
        }

        // Load checkout script if it exists
        $script_path = PEACHPAY_ABSPATH . 'core/payments/nmi/assets/js/checkout.js';
        if (file_exists($script_path)) {
            $script_url = plugins_url('peachpay-for-woocommerce/core/payments/nmi/assets/js/checkout.js');
            $dependencies = array('jquery');

            // Add Collect.js as dependency if it was enqueued
            if (! empty($public_tokenization_key)) {
                $dependencies[] = 'nmi-collect-js';
            }

            wp_enqueue_script(
                'peachpay-nmi-checkout',
                $script_url,
                $dependencies,
                '1.0.7',
                true
            );

            // Add AJAX configuration for transaction creation
            $ajax_config = array(
                'ajax_url' => admin_url('admin-ajax.php'),
                'create_transaction_url' => WC_AJAX::get_endpoint('pp-create-transaction'),
                'nonce' => wp_create_nonce('peachpay_nmi_nonce'),
            );

            // Localize script with configuration
            wp_localize_script('peachpay-nmi-checkout', 'peachpayNMIConfig', array(
                'environment' => $this->is_test_mode() || peachpay_is_test_mode() ? 'test' : 'live',
                'ajax_config' => $ajax_config,
                'isCollectJs' => true, // This code path only runs for Collect.js mode
                'publicTokenizationKey' => $public_tokenization_key,
            ));

            // Also add AJAX config separately for easier access
            wp_localize_script('peachpay-nmi-checkout', 'peachpayNMIAjax', $ajax_config);
        }
    }

    /**
     * Process payment
     */
    public function process_payment($order_id)
    {
        try {
            // Get PeachPay session and transaction data
            $session_id = PeachPay_Payment::get_session();
            $transaction_id = $this->get_transaction_id_from_request();
            $payment_token = $this->get_payment_token_from_request();

            peachpay_log('debug', 'NMI Gateway: [STEP 5.1] Session ID: ' . ($session_id ?: 'EMPTY'));
            peachpay_log('debug', 'NMI Gateway: [STEP 5.1] Transaction ID: ' . ($transaction_id ?: 'EMPTY'));
            peachpay_log('debug', 'NMI Gateway: [STEP 5.1] Payment Token: ' . (empty($payment_token) ? 'EMPTY' : substr($payment_token, 0, 20) . '...'));

            // Check if we have the required transaction ID
            // If not, create one automatically (following ConvesioPay pattern)
            if (empty($transaction_id)) {
                peachpay_log('debug', 'NMI Gateway: [STEP 5.1] No transaction ID found, creating fallback...');
                $transaction_id = $this->create_fallback_transaction_id();
                peachpay_log('debug', 'NMI Gateway: [STEP 5.1] Fallback transaction ID created: ' . $transaction_id);
            }

            // IMPORTANT: Inject transaction_id into $_POST for parent validation
            // The parent class requires this field to be present in $_POST
            if (!empty($transaction_id) && empty($_POST['peachpay_transaction_id'])) {
                $_POST['peachpay_transaction_id'] = $transaction_id;
            }

            // Call parent process_payment to handle PeachPay transaction creation
            peachpay_log('debug', 'NMI Gateway: [STEP 5.2] Calling parent::process_payment()...');
            $order = parent::process_payment($order_id);

            if (! $order) {
                return array(
                    'result'   => 'failure',
                    'redirect' => '',
                );
            }

            // Set PeachPay details on the order
            $this->set_peachpay_order_details($order, $session_id, $transaction_id);

            // Get NMI configuration
            peachpay_log('debug', 'NMI Gateway: [STEP 5.3] Getting NMI configuration...');
            $config = $this->get_nmi_config();
            if (empty($config)) {
                peachpay_log('error', 'NMI Gateway: [STEP 5.3] NMI configuration is empty');
                wc_add_notice(__('NMI is not properly configured.', 'peachpay-for-woocommerce'), 'error');
                return array(
                    'result'   => 'failure',
                    'redirect' => '',
                );
            }
            peachpay_log('debug', 'NMI Gateway: [STEP 5.3] NMI configuration loaded successfully');

            // Get order details
            $order_currency = $order->get_currency();
            $order_amount = $order->get_total();
            peachpay_log('debug', 'NMI Gateway: [STEP 5.3] Order Amount: ' . $order_amount . ' ' . $order_currency);

            // Determine transaction type based on capture setting
            $capture_immediately = $this->get_option('capture_immediately', 'yes') === 'yes';
            $transaction_type = $capture_immediately ? 'sale' : 'auth';

            // Store capture setting for later use
            $order->update_meta_data('_nmi_capture_immediately', $capture_immediately ? 'yes' : 'no');

            // STEP 5.4: Detect payment method (Direct Post vs Collect.js)
            $response_data = null;

            if (isset($_POST['nmi_cc_number'])) {
                // Direct Post - process card data directly
                peachpay_log('debug', 'NMI Gateway: [STEP 5.4] Direct Post mode detected');

                // Sanitize card data (never store or log)
                $card_data = array(
                    'number' => sanitize_text_field($_POST['nmi_cc_number'] ?? ''),
                    'exp'    => sanitize_text_field($_POST['nmi_cc_exp'] ?? ''),
                    'cvv'    => sanitize_text_field($_POST['nmi_cc_cvv'] ?? '')
                );

                // Remove spaces from card number (formatting may add spaces)
                $card_data['number'] = str_replace(' ', '', $card_data['number']);

                // Basic validation
                if (empty($card_data['number']) || empty($card_data['exp']) || empty($card_data['cvv'])) {
                    peachpay_log('error', 'NMI Gateway: [STEP 5.4] Card validation failed - missing required fields');
                    throw new Exception(__('Please enter all required card details.', 'peachpay-for-woocommerce'));
                }

                // Validate expiration format (MM/YY)
                if (!preg_match('/^\d{2}\/\d{2}$/', $card_data['exp'])) {
                    throw new Exception(__('Please enter a valid expiration date (MM/YY).', 'peachpay-for-woocommerce'));
                }

                // Use Direct Post helper
                require_once PEACHPAY_ABSPATH . 'core/payments/nmi/includes/class-peachpay-nmi-direct-post.php';
                $direct_post = new PeachPay_NMI_Direct_Post($config['api_key'] ?? '');

                $response = $direct_post->charge($order, $card_data, $transaction_type);

                if (is_wp_error($response)) {
                    throw new Exception($response->get_error_message());
                }

                $response_data = $response;
                $order->update_meta_data( '_nmi_payment_mode', 'directpost' );
                peachpay_log('debug', 'NMI Gateway: [STEP 5.4] Direct Post transaction processed');
            } elseif (isset($_POST['nmi_payment_token']) && !empty($_POST['nmi_payment_token'])) {
                // ============================================================
                // COLLECT.JS MODE
                // Collect.js ONLY tokenizes the card - we must call NMI API
                // to actually charge the card using the payment_token
                // ============================================================
                peachpay_log('debug', 'NMI Gateway: [STEP 5.4] Collect.js mode detected');

                $collectjs_token = sanitize_text_field($_POST['nmi_payment_token']);
                peachpay_log('debug', 'NMI Gateway: [STEP 5.4] Collect.js token received');

                // Save token metadata
                $order->update_meta_data('_nmi_payment_token', $collectjs_token);
                $order->update_meta_data('_nmi_payment_method', 'collectjs');
                $order->update_meta_data('_nmi_payment_mode', 'collectjs');

                // Get the security_key (private key) for NMI API
                $security_key = $config['api_key'] ?? '';
                if (empty($security_key)) {
                    peachpay_log('error', 'NMI Gateway: [STEP 5.4] Missing security_key (private_key)');
                    throw new Exception(__('NMI configuration error: Private Security Key is required for Collect.js payments.', 'peachpay-for-woocommerce'));
                }

                // Build NMI API request using payment_token (Collect.js: use nmi_gateway_domain)
                $api_endpoint = PeachPay_NMI_Integration::get_api_endpoint();
                $nmi_request = array(
                    'security_key'  => $security_key,
                    'type'          => $transaction_type,
                    'payment_token' => $collectjs_token,
                    'amount'        => number_format($order_amount, 2, '.', ''),
                    'orderid'       => $order->get_order_number(),
                    'email'         => $order->get_billing_email(),
                    'firstname'     => $order->get_billing_first_name(),
                    'lastname'      => $order->get_billing_last_name(),
                    'address1'      => $order->get_billing_address_1(),
                    'address2'      => $order->get_billing_address_2(),
                    'city'          => $order->get_billing_city(),
                    'state'         => $order->get_billing_state(),
                    'zip'           => $order->get_billing_postcode(),
                    'country'       => $order->get_billing_country(),
                    'phone'         => $order->get_billing_phone(),
                );

                // Add shipping info if available
                if ($order->has_shipping_address()) {
                    $nmi_request['shipping_firstname'] = $order->get_shipping_first_name();
                    $nmi_request['shipping_lastname']  = $order->get_shipping_last_name();
                    $nmi_request['shipping_address1']  = $order->get_shipping_address_1();
                    $nmi_request['shipping_city']      = $order->get_shipping_city();
                    $nmi_request['shipping_state']     = $order->get_shipping_state();
                    $nmi_request['shipping_zip']       = $order->get_shipping_postcode();
                    $nmi_request['shipping_country']   = $order->get_shipping_country();
                }

                peachpay_log('debug', 'NMI Gateway: [STEP 5.4] Calling NMI API with payment_token...');

                // Call NMI API
                $api_response = wp_remote_post($api_endpoint, array(
                    'body'    => $nmi_request,
                    'timeout' => 45,
                    'headers' => array('Content-Type' => 'application/x-www-form-urlencoded')
                ));

                if (is_wp_error($api_response)) {
                    peachpay_log('error', 'NMI Gateway: [STEP 5.4] API Error: ' . $api_response->get_error_message());
                    throw new Exception(__('Payment processing failed. Please try again.', 'peachpay-for-woocommerce'));
                }

                // Parse NMI response
                parse_str(wp_remote_retrieve_body($api_response), $response_data);
                peachpay_log('debug', 'NMI Gateway: [STEP 5.4] NMI API response received');

                // Continue to common response handling below...

            } else {
                // No payment method detected
                peachpay_log('error', 'NMI Gateway: [STEP 5.4] No payment data found');
                throw new Exception(__('Payment information is missing. Please try again.', 'peachpay-for-woocommerce'));
            }

            // ============================================================
            // NMI API RESPONSE HANDLING (Both Direct Post AND Collect.js)
            // ============================================================

            // STEP 5.6: Process NMI API response
            $nmi_response = $response_data['response'] ?? '';
            $nmi_transaction_id = $response_data['transactionid'] ?? '';
            $nmi_response_text = $response_data['responsetext'] ?? '';

            peachpay_log('debug', 'NMI Gateway: [STEP 5.6] Response Code: ' . $nmi_response . ', Text: ' . $nmi_response_text . ', Transaction ID: ' . ($nmi_transaction_id ?: 'NONE'));

            // STEP 5.7: Handle payment status
            if ($nmi_response == '1') {
                peachpay_log('info', 'NMI Gateway: [STEP 5.7] Payment SUCCESS');
                // Payment successful
                $order->update_meta_data('_nmi_payment_id', $nmi_transaction_id);

                // Determine status based on capture setting
                if ($capture_immediately) {
                    $order->add_order_note(sprintf(__('NMI payment succeeded. Transaction ID: %s', 'peachpay-for-woocommerce'), $nmi_transaction_id));
                    $order->payment_complete($nmi_transaction_id);
                } else {
                    // Authorization only - keep as pending for manual capture
                    $order->add_order_note(sprintf(__('NMI payment authorized. Transaction ID: %s. Ready for manual capture.', 'peachpay-for-woocommerce'), $nmi_transaction_id));
                    $order->set_transaction_id($nmi_transaction_id);
                    $order->update_status('pending', __('Payment authorized via NMI. Ready for manual capture.', 'peachpay-for-woocommerce'));
                }

                $order->save();

                // Empty the cart after successful payment
                WC()->cart->empty_cart();

                peachpay_log('info', 'NMI Gateway: [STEP 5.7] Order completed, redirecting to: ' . $this->get_return_url($order));

                return array(
                    'result'   => 'success',
                    'redirect' => $this->get_return_url($order),
                );
            } else {
                // Payment failed
                error_log("NMI Gateway: [STEP 5.7] Payment FAILED");
                error_log("NMI Gateway: [STEP 5.7] Error: " . $nmi_response_text);
                error_log("NMI Gateway: [STEP 5] ======================================== FAILED");
                throw new Exception($nmi_response_text ?: __('Payment failed.', 'peachpay-for-woocommerce'));
            }
        } catch (Exception $e) {
            error_log("NMI Gateway: [STEP 5] EXCEPTION: " . $e->getMessage());
            error_log("NMI Gateway: [STEP 5] ======================================== EXCEPTION");
            if (isset($order)) {
                $order->add_order_note(sprintf(__('NMI payment failed: %s', 'peachpay-for-woocommerce'), $e->getMessage()));
            }
            wc_add_notice(__('Payment failed: ', 'peachpay-for-woocommerce') . $e->getMessage(), 'error');

            return array(
                'result'   => 'failure',
                'redirect' => '',
            );
        }
    }

    /**
     * Get return URL for the order
     */
    public function get_return_url($order = null)
    {
        if ($order) {
            $return_url = $order->get_checkout_order_received_url();
        } else {
            $return_url = wc_get_endpoint_url('order-received', '', wc_get_page_permalink('checkout'));
        }

        return apply_filters('woocommerce_get_return_url', $return_url, $order);
    }

    /**
     * Get transaction URL for viewing payment in NMI dashboard
     *
     * @param WC_Order $order Order object.
     * @return string Transaction URL.
     */
    public function get_transaction_url($order)
    {
        $payment_id = $order->get_meta('_nmi_payment_id');
        if (empty($payment_id)) {
            $payment_id = $order->get_transaction_id();
        }

        if (! empty($payment_id)) {
            // NMI doesn't have a public transaction URL, but we can return the transaction ID
            $this->view_transaction_url = '';
            return '';
        }

        return '';
    }

    /**
     * Process refund
     */
    public function process_refund($order_id, $amount = null, $reason = '')
    {
        $order = wc_get_order($order_id);

        if (! $order) {
            return new WP_Error('nmi_refund_error', __('Order not found.', 'peachpay-for-woocommerce'));
        }

        // Get NMI configuration
        $config = $this->get_nmi_config();
        if (empty($config)) {
            return new WP_Error('nmi_refund_error', __('NMI is not properly configured.', 'peachpay-for-woocommerce'));
        }

        try {
            // Get payment ID from order meta
            $payment_id = $order->get_meta('_nmi_payment_id');
            if (empty($payment_id)) {
                $payment_id = $order->get_transaction_id();
            }

            if (! $payment_id) {
                return new WP_Error('nmi_refund_error', __('Payment ID not found for this order.', 'peachpay-for-woocommerce'));
            }

            // If no amount specified, refund the full order total
            if (is_null($amount) || $amount <= 0) {
                $amount = $order->get_total();
            }

            // NMI current API uses security_key (not username/password)
            $security_key = $config['api_key'] ?? '';
            if ( empty( $security_key ) ) {
                return new WP_Error( 'nmi_refund_error', __( 'NMI Security Key is not configured. Cannot process refund.', 'peachpay-for-woocommerce' ) );
            }

            $refund_data = array(
                'type'           => 'refund',
                'security_key'   => $security_key,
                'transactionid'  => $payment_id,
                'amount'         => number_format( (float) $amount, 2, '.', '' ),
            );

            $api_url = PeachPay_NMI_Integration::get_api_endpoint();

            // Make API call to NMI
            $response = wp_remote_post($api_url, array(
                'method' => 'POST',
                'timeout' => 30,
                'headers' => array(
                    'Content-Type' => 'application/x-www-form-urlencoded'
                ),
                'body' => http_build_query($refund_data)
            ));

            if (is_wp_error($response)) {
                return new WP_Error('nmi_refund_error', 'Network error: ' . $response->get_error_message());
            }

            $response_code = wp_remote_retrieve_response_code($response);
            $response_body = wp_remote_retrieve_body($response);

            // Parse NMI response
            parse_str($response_body, $response_data);

            if ($response_code !== 200) {
                $error_message = $response_data['responsetext'] ?? 'Refund failed (HTTP ' . $response_code . ')';
                return new WP_Error('nmi_refund_error', $error_message);
            }

            // Check NMI response
            $nmi_response = $response_data['response'] ?? '';
            $nmi_refund_id = $response_data['transactionid'] ?? '';

            if ($nmi_response == '1') {
                // Refund successful
                $note = sprintf(
                    __('NMI refund processed. Amount: %s', 'peachpay-for-woocommerce'),
                    wc_price($amount)
                );

                if ($nmi_refund_id) {
                    $note .= sprintf(__('. Refund ID: %s', 'peachpay-for-woocommerce'), $nmi_refund_id);
                }

                if ($reason) {
                    $note .= sprintf(__('. Reason: %s', 'peachpay-for-woocommerce'), $reason);
                }

                $order->add_order_note($note);

                if ($nmi_refund_id) {
                    $order->update_meta_data('_nmi_last_refund_id', $nmi_refund_id);
                    $order->save();
                }

                return true;
            } else {
                $error_message = $response_data['responsetext'] ?? 'Refund failed';
                return new WP_Error('nmi_refund_error', $error_message);
            }
        } catch (Exception $e) {
            return new WP_Error('nmi_refund_error', $e->getMessage());
        }
    }

    /**
     * Check if public tokenization key exists
     *
     * @return bool
     */
    private function has_public_tokenization_key()
    {
        $public_key = $this->get_option('public_tokenization_key', '');
        return !empty($public_key);
    }

    /**
     * Check if private key exists
     *
     * @return bool
     */
    private function has_private_key()
    {
        $private_key = $this->get_option('private_key', '');
        return !empty($private_key);
    }

    /**
     * Get active API tab for checkout rendering.
     *
     * @return string 'collectjs' or 'directapi'
     */
    private function get_active_api_tab()
    {
        $tab = $this->get_option('active_api_tab', 'collectjs');
        return in_array($tab, array('collectjs', 'directapi'), true) ? $tab : 'collectjs';
    }

    /**
     * Render Collect.js payment fields
     */
    private function render_collect_js_fields()
    {
        $config = $this->get_nmi_config();

        if (empty($config)) {
            echo '<div style="background: #f8d7da; border: 1px solid #f5c6cb; border-radius: 4px; padding: 15px; margin: 10px 0;">';
            echo '<p style="margin: 0; color: #721c24;"><strong>' . __('Configuration Error', 'peachpay-for-woocommerce') . '</strong></p>';
            echo '<p style="margin: 5px 0 0 0; color: #721c24;">' . __('NMI is not properly configured. Please check your settings.', 'peachpay-for-woocommerce') . '</p>';
            echo '</div>';
            return;
        }

        // Display description
        $description = $this->get_option('description', '');
        if (!empty($description)) {
            echo '<p>' . wp_kses_post($description) . '</p>';
        }

        // Generate transaction ID for Collect.js (required by PeachPay validation)
        $transaction_id = $this->create_fallback_transaction_id();

        // NMI payment form container for Collect.js
?>
        <div id="nmi-payment-form" class="wc-payment-form">
            <fieldset id="nmi-fieldset">
                <!-- Hidden field for PeachPay transaction ID (required for validation) -->
                <input type="hidden" id="peachpay-transaction-id" name="peachpay_transaction_id" value="<?php echo esc_attr($transaction_id); ?>" />

                <div id="nmi-component-container">
                    <p><?php _e('Please enter your payment details below.', 'peachpay-for-woocommerce'); ?></p>
                </div>

                <!-- Error Display Container -->
                <div id="nmi-error-message" style="display: none; color: #e74c3c; background: #fdf2f2; border: 1px solid #e74c3c; border-radius: 5px; padding: 10px; margin: 10px 0;">
                </div>

                <input type="hidden" id="nmi-payment-token" name="nmi_payment_token" value="" />
            </fieldset>
        </div>
    <?php
    }

    /**
     * Render Direct Post payment fields
     */
    private function render_direct_post_fields()
    {
        // Display description
        $description = $this->get_option('description', '');
        if (!empty($description)) {
            echo '<p>' . wp_kses_post($description) . '</p>';
        }

        // Generate transaction ID for Direct Post (required by PeachPay validation)
        $transaction_id = $this->create_fallback_transaction_id();

        // Direct Post form - using WooCommerce standard structure
    ?>
        <div id="nmi-direct-post-form" class="wc-payment-form">
            <fieldset id="nmi-direct-post-fieldset">
                <!-- Hidden field for PeachPay transaction ID (required for validation) -->
                <input type="hidden" name="peachpay_transaction_id" value="<?php echo esc_attr($transaction_id); ?>" />

                <p class="form-row form-row-wide">
                    <label for="nmi_cc_number" class="nmi-form-label"><?php _e('Card Number', 'peachpay-for-woocommerce'); ?> <span class="required">*</span></label>
                    <input type="text" id="nmi_cc_number" name="nmi_cc_number" class="input-text wc-credit-card-form-card-number"
                        style="background-repeat: unset; background-position: unset; background-size: unset; background-image: unset;"
                        autocomplete="cc-number" placeholder="•••• •••• •••• ••••" maxlength="19" />
                </p>
                <p class="form-row form-row-first">
                    <label for="nmi_cc_exp" class="nmi-form-label"><?php _e('Expiry (MM/YY)', 'peachpay-for-woocommerce'); ?> <span class="required">*</span></label>
                    <input type="text" id="nmi_cc_exp" name="nmi_cc_exp" class="input-text wc-credit-card-form-card-expiry" autocomplete="cc-exp" placeholder="MM / YY" maxlength="5" />
                </p>
                <p class="form-row form-row-last">
                    <label for="nmi_cc_cvv" class="nmi-form-label"><?php _e('Card Code (CVV)', 'peachpay-for-woocommerce'); ?> <span class="required">*</span></label>
                    <input type="text" id="nmi_cc_cvv" name="nmi_cc_cvv" class="input-text wc-credit-card-form-card-cvc" autocomplete="cc-csc" placeholder="CVV" maxlength="4" />
                </p>
            </fieldset>
        </div>
        <script>
            (function($) {
                $(document).ready(function() {
                    // Format expiry date input (MM/YY)
                    $('#nmi_cc_exp').on('input', function(e) {
                        var value = $(this).val().replace(/\D/g, ''); // Remove non-digits
                        if (value.length >= 2) {
                            value = value.substring(0, 2) + '/' + value.substring(2, 4);
                        }

                        $(this).val(value);
                    });

                    // Format card number with spaces
                    $('#nmi_cc_number').on('input', function(e) {
                        var value = $(this).val().replace(/\s/g, '').replace(/\D/g, '');
                        var formattedValue = value.match(/.{1,4}/g);

                        if (formattedValue) {
                            $(this).val(formattedValue.join(' '));
                        }
                    });

                    // Only allow numbers for CVV
                    $('#nmi_cc_cvv').on('input', function(e) {
                        $(this).val($(this).val().replace(/\D/g, ''));
                    });
                });
            })(jQuery);
        </script>
    <?php
    }

    /**
     * Payment fields for NMI
     */
    public function payment_fields()
    {
        $active_api_tab = $this->get_active_api_tab();

        if ($active_api_tab === 'collectjs') {
            if ($this->has_public_tokenization_key()) {
                $this->render_collect_js_fields();
                return;
            }

            echo '<div class="woocommerce-error">';
            echo '<p><strong>' . __('NMI Configuration Required', 'peachpay-for-woocommerce') . '</strong></p>';
            echo '<p>' . __('Collect.js is selected, but the Public Tokenization Key is missing. Please review your NMI settings in PeachPay and add your key to continue.', 'peachpay-for-woocommerce') . '</p>';
            echo '</div>';
            return;
        }

        if ($this->has_private_key()) {
            $this->render_direct_post_fields();
            return;
        }

        echo '<div class="woocommerce-error">';
        echo '<p><strong>' . __('NMI Configuration Required', 'peachpay-for-woocommerce') . '</strong></p>';
        echo '<p>' . __('Direct API is selected, but the Private Security Key is missing. Please review your NMI settings in PeachPay and add your key to continue.', 'peachpay-for-woocommerce') . '</p>';
        echo '</div>';
    }

    /**
     * Set PeachPay order details
     * 
     * @param WC_Order $order The order object
     * @param string $session_id PeachPay session ID
     * @param string $transaction_id PeachPay transaction ID
     */
    private function set_peachpay_order_details($order, $session_id, $transaction_id)
    {
        $peachpay_details = array(
            'session_id'             => $session_id,
            'transaction_id'         => $transaction_id,
            'peachpay_mode'          => peachpay_is_test_mode() ? 'test' : 'live',
            'nmi_mode'               => peachpay_is_test_mode() ? 'test' : 'live',
            'service_fee_percentage' => 0,
        );

        foreach ($peachpay_details as $key => $value) {
            $order->update_meta_data('_peachpay_' . $key, $value);
        }

        $order->save();
    }

    /**
     * Display admin notices
     */
    public function admin_notices()
    {
        // Only show on admin pages
        if (!is_admin()) {
            return;
        }

        // Only show on relevant pages
        $screen = get_current_screen();
        if (!$screen || (strpos($screen->id, 'woocommerce') === false && strpos($screen->id, 'peachpay') === false)) {
            return;
        }

        // Check if gateway is enabled
        if ($this->enabled !== 'yes') {
            return;
        }

        $active_api_tab = $this->get_active_api_tab();
        $public_key = $this->get_option('public_tokenization_key', '');
        $private_key = $this->get_option('private_key', '');

        // Check gateway domain (required for multi-merchant)
        $gateway_domain = get_option( 'nmi_gateway_domain', '' );
        if ( empty( trim( $gateway_domain ) ) ) {
            echo '<div class="notice notice-warning">';
            echo '<p><strong>' . esc_html__( 'NMI Configuration', 'peachpay-for-woocommerce' ) . '</strong></p>';
            echo '<p>' . esc_html__( 'NMI Gateway Domain is not configured. Using default (secure.networkmerchants.com). For multi-merchant setups, please add your gateway domain in', 'peachpay-for-woocommerce' ) . ' <a href="' . esc_url( admin_url( 'admin.php?page=peachpay&tab=payment#nmi' ) ) . '">' . esc_html__( 'PeachPay Settings', 'peachpay-for-woocommerce' ) . '</a>.</p>';
            echo '</div>';
        }

        // Check configuration based on active mode
        if ($active_api_tab === 'collectjs' && empty($public_key)) {
            echo '<div class="notice notice-error">';
            echo '<p><strong>' . __('NMI Configuration Required', 'peachpay-for-woocommerce') . '</strong></p>';
            echo '<p>' . __('Collect.js mode is enabled but the Public Tokenization Key is missing. Please add your key in', 'peachpay-for-woocommerce') . ' <a href="' . esc_url(admin_url('admin.php?page=peachpay&tab=payment')) . '">' . __('PeachPay Settings', 'peachpay-for-woocommerce') . '</a>.</p>';
            echo '</div>';
        } elseif ($active_api_tab === 'directapi' && empty($private_key)) {
            echo '<div class="notice notice-error">';
            echo '<p><strong>' . __('NMI Configuration Required', 'peachpay-for-woocommerce') . '</strong></p>';
            echo '<p>' . __('Direct Post API mode is enabled but the Private Security Key is missing. Please add your key in', 'peachpay-for-woocommerce') . ' <a href="' . esc_url(admin_url('admin.php?page=peachpay&tab=payment')) . '">' . __('PeachPay Settings', 'peachpay-for-woocommerce') . '</a>.</p>';
            echo '</div>';
        }
    }

    /**
     * Add CSS styles for order overview payment method display
     * Works in both admin and frontend (order received page)
     */
    public function add_order_overview_styles()
    {
        // Only add on order pages (admin order view, frontend order received/view)
        if (!is_admin() && !is_wc_endpoint_url('order-received') && !is_wc_endpoint_url('view-order')) {
            return;
        }
    ?>
        <style>
            /* Order overview payment method - horizontal card icons */
            .woocommerce-order-overview__payment-method.method strong {
                display: inline-flex;
                align-items: center;
                flex-wrap: wrap;
                gap: 4px;
            }

            .woocommerce-order-overview__payment-method.method strong img {
                display: inline-block;
                vertical-align: middle;
                margin-left: 4px;
                height: 20px;
                width: auto;
            }
        </style>
<?php
    }
}
