<?php
if ( ! defined( 'ABSPATH' ) ) exit;

/**
 * VMO Shipping Manager
 * 
 * Backend logic for the Shipping & Fulfillment tab.
 * Manages orders, carrier settings, tracking, and fulfillment operations.
 *
 * @package VMO_AI_Website_Builder
 * @since 1.0.0
 */

class VMO_Shipping_Manager {

    private static $instance = null;

    public static function get_instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function init() {
        // AJAX handlers
        add_action( 'wp_ajax_vmo_get_shipping_orders',    [ $this, 'ajax_get_orders' ] );
        add_action( 'wp_ajax_vmo_save_shipping_settings',  [ $this, 'ajax_save_settings' ] );
        add_action( 'wp_ajax_vmo_ship_order',              [ $this, 'ajax_ship_order' ] );
        add_action( 'wp_ajax_vmo_get_shipping_tracking',   [ $this, 'ajax_get_tracking' ] );
        add_action( 'wp_ajax_vmo_bulk_ship',               [ $this, 'ajax_bulk_ship' ] );
        add_action( 'wp_ajax_vmo_add_custom_carrier',      [ $this, 'ajax_add_custom_carrier' ] );
        add_action( 'wp_ajax_vmo_save_global_shipping',    [ $this, 'ajax_save_global_config' ] );
        add_action( 'wp_ajax_vmo_test_shipping',           [ $this, 'ajax_test_connection' ] );
        add_action( 'wp_ajax_vmo_discover_carriers',       [ $this, 'ajax_discover_carriers' ] );
        add_action( 'wp_ajax_vmo_mark_delivered',          [ $this, 'ajax_mark_delivered' ] );
        add_action( 'wp_ajax_vmo_update_delivery_status',  [ $this, 'ajax_update_delivery_status' ] );
        add_action( 'wp_ajax_vmo_get_carrier_onboarding',  [ $this, 'ajax_get_carrier_onboarding' ] );

        // Public tracking page (REST)
        add_action( 'rest_api_init', [ $this, 'register_tracking_routes' ] );

        // Ensure tables
        $this->ensure_tables();
    }

    /* ─── Database Setup ─── */

    private function ensure_tables() {
        global $wpdb;
        $charset        = $wpdb->get_charset_collate();
        $orders_table   = $wpdb->prefix . 'vmo_shipping_orders';
        $carriers_table = $wpdb->prefix . 'vmo_shipping_carriers';
        $log_table      = $wpdb->prefix . 'vmo_shipping_status_log';

        if ( $wpdb->get_var( "SHOW TABLES LIKE '{$orders_table}'" ) !== $orders_table ) {
            $wpdb->query( "CREATE TABLE {$orders_table} (
                id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                user_id BIGINT UNSIGNED NOT NULL,
                order_ref VARCHAR(100),
                customer_name VARCHAR(255),
                customer_email VARCHAR(255),
                address_line1 VARCHAR(500),
                address_line2 VARCHAR(500),
                city VARCHAR(100),
                state VARCHAR(100),
                postal_code VARCHAR(20),
                country VARCHAR(100),
                items TEXT,
                total DECIMAL(10,2) DEFAULT 0,
                currency VARCHAR(10) DEFAULT 'USD',
                carrier VARCHAR(50),
                tracking_number VARCHAR(200),
                status VARCHAR(30) DEFAULT 'pending',
                delivery_type VARCHAR(30) DEFAULT 'carrier',
                delivery_notes TEXT,
                shipped_at DATETIME NULL,
                delivered_at DATETIME NULL,
                created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                INDEX idx_user_status (user_id, status),
                INDEX idx_tracking (tracking_number)
            ) {$charset}" );
        }

        if ( $wpdb->get_var( "SHOW TABLES LIKE '{$carriers_table}'" ) !== $carriers_table ) {
            $wpdb->query( "CREATE TABLE {$carriers_table} (
                id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                user_id BIGINT UNSIGNED NOT NULL,
                carrier_slug VARCHAR(50) NOT NULL,
                carrier_name VARCHAR(200) NOT NULL,
                is_custom TINYINT(1) DEFAULT 0,
                is_enabled TINYINT(1) DEFAULT 0,
                config TEXT,
                created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                INDEX idx_user (user_id)
            ) {$charset}" );
        }

        if ( $wpdb->get_var( "SHOW TABLES LIKE '{$log_table}'" ) !== $log_table ) {
            $wpdb->query( "CREATE TABLE {$log_table} (
                id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                order_id BIGINT UNSIGNED NOT NULL,
                user_id BIGINT UNSIGNED NOT NULL,
                status VARCHAR(30) NOT NULL,
                notes TEXT,
                created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                INDEX idx_order (order_id),
                INDEX idx_status (status)
            ) {$charset}" );
        }
    }

    /* ─── AJAX: Get Orders ─── */

    public function ajax_get_orders() {
        if ( ! current_user_can( 'read' ) ) wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );
        $user_id = get_current_user_id();
        $status  = isset( $_POST['status'] ) ? sanitize_text_field( $_POST['status'] ) : 'pending';
        global $wpdb;
        $table = $wpdb->prefix . 'vmo_shipping_orders';

        $orders = $wpdb->get_results( $wpdb->prepare(
            "SELECT * FROM {$table} WHERE user_id = %d AND status = %s ORDER BY created_at DESC LIMIT 50",
            $user_id, $status
        ) );

        $formatted = [];
        if ( $orders ) {
            foreach ( $orders as $o ) {
                $formatted[] = [
                    'id'              => $o->id,
                    'order_ref'       => $o->order_ref,
                    'customer'        => $o->customer_name,
                    'address'         => trim( $o->address_line1 . ' ' . $o->city . ' ' . $o->state . ' ' . $o->postal_code . ' ' . $o->country ),
                    'items'           => json_decode( $o->items, true ) ?: [],
                    'total'           => $o->total,
                    'currency'        => $o->currency,
                    'carrier'         => $o->carrier,
                    'tracking_number' => $o->tracking_number,
                    'status'          => $o->status,
                    'created_at'      => $o->created_at,
                    'shipped_at'      => $o->shipped_at,
                ];
            }
        }

        $count = (int) $wpdb->get_var( $wpdb->prepare(
            "SELECT COUNT(*) FROM {$table} WHERE user_id = %d AND status = 'pending'",
            $user_id
        ) );

        wp_send_json_success( [ 'orders' => $formatted, 'pending_count' => $count ] );
    }

    /* ─── AJAX: Ship an Order ─── */

    public function ajax_ship_order() {
        if ( ! current_user_can( 'read' ) ) wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );
        $user_id  = get_current_user_id();
        $order_id = isset( $_POST['order_id'] ) ? (int) $_POST['order_id'] : 0;
        $carrier  = isset( $_POST['carrier'] ) ? sanitize_text_field( $_POST['carrier'] ) : '';
        $tracking = isset( $_POST['tracking_number'] ) ? sanitize_text_field( $_POST['tracking_number'] ) : '';

        if ( $order_id <= 0 ) wp_send_json_error( [ 'message' => 'Invalid order' ] );

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

        $updated = $wpdb->update( $table, [
            'status'          => 'shipped',
            'carrier'         => $carrier,
            'tracking_number' => $tracking,
            'shipped_at'      => current_time( 'mysql' ),
        ], [ 'id' => $order_id, 'user_id' => $user_id ] );

        if ( $updated === false ) {
            wp_send_json_error( [ 'message' => 'Failed to update order' ] );
        }

        // Send tracking notification email if customer email exists
        $order = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE id = %d", $order_id ) );
        if ( $order && ! empty( $order->customer_email ) && ! empty( $tracking ) ) {
            wp_mail(
                $order->customer_email,
                'Your order has shipped! - Tracking: ' . $tracking,
                "Hi {$order->customer_name},\n\nYour order ({$order->order_ref}) has been shipped via {$carrier}.\nTracking number: {$tracking}\n\nThank you for your purchase!"
            );
        }

        if ( function_exists( 'vmo_business_flow_mark_from_shipping_order' ) ) {
            vmo_business_flow_mark_from_shipping_order( $order_id, $user_id, 'shipped', 'Tracking information saved from the Shipping Manager.' );
        }

        wp_send_json_success( [ 'message' => 'Order shipped', 'order_id' => $order_id ] );
    }

    /* ─── AJAX: Bulk Ship ─── */

    public function ajax_bulk_ship() {
        if ( ! current_user_can( 'read' ) ) wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );
        $user_id   = get_current_user_id();
        $order_ids = isset( $_POST['order_ids'] ) ? array_map( 'intval', (array) $_POST['order_ids'] ) : [];
        $carrier   = isset( $_POST['carrier'] ) ? sanitize_text_field( $_POST['carrier'] ) : '';

        if ( empty( $order_ids ) ) wp_send_json_error( [ 'message' => 'No orders selected' ] );

        global $wpdb;
        $table   = $wpdb->prefix . 'vmo_shipping_orders';
        $shipped = 0;

        foreach ( $order_ids as $oid ) {
            $result = $wpdb->update( $table, [
                'status'    => 'shipped',
                'carrier'   => $carrier,
                'shipped_at' => current_time( 'mysql' ),
            ], [ 'id' => $oid, 'user_id' => $user_id, 'status' => 'pending' ] );
            if ( $result ) {
                $shipped++;
                if ( function_exists( 'vmo_business_flow_mark_from_shipping_order' ) ) {
                    vmo_business_flow_mark_from_shipping_order( $oid, $user_id, 'shipped', 'Bulk shipped from the Shipping Manager.' );
                }
            }
        }

        wp_send_json_success( [ 'shipped' => $shipped, 'total' => count( $order_ids ) ] );
    }

    /* ─── AJAX: Get Tracking ─── */

    public function ajax_get_tracking() {
        if ( ! current_user_can( 'read' ) ) wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );
        $order_id = isset( $_POST['order_id'] ) ? (int) $_POST['order_id'] : 0;
        if ( $order_id <= 0 ) wp_send_json_error( [ 'message' => 'Invalid order' ] );

        global $wpdb;
        $table = $wpdb->prefix . 'vmo_shipping_orders';
        $order = $wpdb->get_row( $wpdb->prepare(
            "SELECT tracking_number, carrier, status, shipped_at, delivered_at FROM {$table} WHERE id = %d AND user_id = %d",
            $order_id, get_current_user_id()
        ) );

        if ( ! $order ) wp_send_json_error( [ 'message' => 'Order not found' ] );

        wp_send_json_success( [
            'tracking_number' => $order->tracking_number,
            'carrier'         => $order->carrier,
            'status'          => $order->status,
            'shipped_at'      => $order->shipped_at,
            'delivered_at'    => $order->delivered_at,
        ] );
    }

    /* ─── AJAX: Save Settings ─── */

    public function ajax_save_settings() {
        if ( ! current_user_can( 'read' ) ) wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );
        $user_id  = get_current_user_id();
        $carriers = isset( $_POST['carriers'] ) ? (array) $_POST['carriers'] : [];

        // Sanitize and store
        $clean = [];
        foreach ( $carriers as $slug => $enabled ) {
            $clean[ sanitize_key( $slug ) ] = (bool) $enabled;
        }
        update_user_meta( $user_id, 'vmo_shipping_carriers_config', wp_json_encode( $clean ) );

        wp_send_json_success( [ 'message' => 'Shipping settings saved', 'carriers_enabled' => count( array_filter( $clean ) ) ] );
    }

    /* ─── AJAX: Add Custom Carrier ─── */

    public function ajax_add_custom_carrier() {
        if ( ! current_user_can( 'read' ) ) wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );
        $user_id = get_current_user_id();
        $name    = isset( $_POST['name'] ) ? sanitize_text_field( $_POST['name'] ) : '';
        if ( empty( $name ) ) wp_send_json_error( [ 'message' => 'Carrier name required' ] );

        global $wpdb;
        $table = $wpdb->prefix . 'vmo_shipping_carriers';
        $slug  = sanitize_title( $name );

        $wpdb->insert( $table, [
            'user_id'      => $user_id,
            'carrier_slug' => $slug,
            'carrier_name' => $name,
            'is_custom'    => 1,
            'is_enabled'   => 1,
            'config'       => '{}',
            'created_at'   => current_time( 'mysql' ),
        ] );

        wp_send_json_success( [ 'message' => 'Custom carrier added', 'id' => $wpdb->insert_id, 'slug' => $slug ] );
    }

    /* ─── AJAX: Save Global Config ─── */

    public function ajax_save_global_config() {
        if ( ! current_user_can( 'read' ) ) wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );
        $user_id = get_current_user_id();
        $config  = isset( $_POST['config'] ) ? $_POST['config'] : [];

        // Sanitize region configs
        $clean = [];
        if ( is_array( $config ) ) {
            foreach ( $config as $region => $carriers ) {
                $r = sanitize_key( $region );
                $clean[ $r ] = [];
                if ( is_array( $carriers ) ) {
                    foreach ( $carriers as $c => $enabled ) {
                        $clean[ $r ][ sanitize_key( $c ) ] = (bool) $enabled;
                    }
                }
            }
        }
        update_user_meta( $user_id, 'vmo_global_shipping_config', wp_json_encode( $clean ) );

        wp_send_json_success( [ 'message' => 'Global shipping configuration saved' ] );
    }

    /* ─── AJAX: Test Connection ─── */

    public function ajax_test_connection() {
        if ( ! current_user_can( 'read' ) ) wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );

        // Basic connectivity check — actual API ping would require carrier credentials
        $results = [
            'status'  => 'ok',
            'message' => 'Shipping module is operational. Carrier API connectivity requires valid API credentials for each enabled carrier.',
            'checks'  => [
                'database'  => 'ok',
                'settings'  => get_user_meta( get_current_user_id(), 'vmo_shipping_carriers_config', true ) ? 'configured' : 'not_configured',
            ],
        ];

        wp_send_json_success( $results );
    }

    /**
     * Create a shipping order from a Stripe payment
     */
    public function create_order_from_payment( $user_id, $payment_data ) {
        global $wpdb;
        $table = $wpdb->prefix . 'vmo_shipping_orders';

        $wpdb->insert( $table, [
            'user_id'        => $user_id,
            'order_ref'      => sanitize_text_field( $payment_data['order_ref'] ?? ( 'ORD-' . strtoupper( wp_generate_password( 8, false ) ) ) ),
            'customer_name'  => sanitize_text_field( $payment_data['customer_name'] ?? '' ),
            'customer_email' => sanitize_email( $payment_data['customer_email'] ?? '' ),
            'address_line1'  => sanitize_text_field( $payment_data['address_line1'] ?? '' ),
            'address_line2'  => sanitize_text_field( $payment_data['address_line2'] ?? '' ),
            'city'           => sanitize_text_field( $payment_data['city'] ?? '' ),
            'state'          => sanitize_text_field( $payment_data['state'] ?? '' ),
            'postal_code'    => sanitize_text_field( $payment_data['postal_code'] ?? '' ),
            'country'        => sanitize_text_field( $payment_data['country'] ?? '' ),
            'items'          => wp_json_encode( $payment_data['items'] ?? [] ),
            'total'          => (float) ( $payment_data['total'] ?? 0 ),
            'currency'       => sanitize_text_field( $payment_data['currency'] ?? 'USD' ),
            'status'         => 'pending',
            'created_at'     => current_time( 'mysql' ),
        ] );

        return $wpdb->insert_id;
    }

    /* ─── Carrier Discovery Registry ─── */

    private function get_carrier_registry(): array {
        return [
            // ─── Global ───
            'fedex' => [
                'name' => 'FedEx', 'region' => 'global', 'coverage' => '220+ countries',
                'signup_url' => 'https://www.fedex.com/en-us/developer/web-services.html',
                'docs_url' => 'https://developer.fedex.com/',
                'needs_api' => true,
                'steps' => [ 'Create a FedEx Developer Portal account', 'Request API credentials (Client ID + Secret)', 'Copy the Client ID and Client Secret into VMO', 'Run the connection test' ],
                'tracking_url' => 'https://www.fedex.com/fedextrack/?trknbr=',
            ],
            'ups' => [
                'name' => 'UPS', 'region' => 'global', 'coverage' => '220+ countries',
                'signup_url' => 'https://developer.ups.com/',
                'docs_url' => 'https://developer.ups.com/api/reference',
                'needs_api' => true,
                'steps' => [ 'Create a UPS Developer account', 'Generate an Access Key and API credentials', 'Paste your Client ID and Client Secret into VMO', 'Run the connection test' ],
                'tracking_url' => 'https://www.ups.com/track?tracknum=',
            ],
            'dhl' => [
                'name' => 'DHL Express', 'region' => 'global', 'coverage' => '220+ countries',
                'signup_url' => 'https://developer.dhl.com/api-reference/dhl-express-mydhl-api',
                'docs_url' => 'https://developer.dhl.com/',
                'needs_api' => true,
                'steps' => [ 'Create a DHL Developer Portal account', 'Subscribe to the Express API', 'Copy your API Key and Secret into VMO', 'Run the connection test' ],
                'tracking_url' => 'https://www.dhl.com/en/express/tracking.html?AWB=',
            ],
            'usps' => [
                'name' => 'USPS', 'region' => 'north_america', 'coverage' => 'US + 190 countries',
                'signup_url' => 'https://developer.usps.com/',
                'docs_url' => 'https://developer.usps.com/apis',
                'needs_api' => true,
                'steps' => [ 'Create a USPS Developer account', 'Register your application for Web Tools API access', 'Copy the Consumer Key into VMO', 'Run the connection test' ],
                'tracking_url' => 'https://tools.usps.com/go/TrackConfirmAction?tLabels=',
            ],
            // ─── Regional ───
            'aramex' => [
                'name' => 'Aramex', 'region' => 'middle_east_africa', 'coverage' => 'Middle East & Africa',
                'signup_url' => 'https://www.aramex.com/developers/apis',
                'docs_url' => 'https://www.aramex.com/developers',
                'needs_api' => true,
                'steps' => [ 'Create an Aramex Developer account', 'Request API credentials from your Aramex representative', 'Enter your Username, Password, Account Number into VMO', 'Run the connection test' ],
                'tracking_url' => 'https://www.aramex.com/track/results?ShipmentNumber=',
            ],
            'canada_post' => [
                'name' => 'Canada Post', 'region' => 'north_america', 'coverage' => 'Canada nationwide',
                'signup_url' => 'https://www.canadapost-postescanada.ca/cpc/en/business/shipping/find-rates-shipping-tools/developer-program.page',
                'docs_url' => 'https://www.canadapost-postescanada.ca/cpc/en/business/shipping/find-rates-shipping-tools.page',
                'needs_api' => true,
                'steps' => [ 'Register for the Canada Post Developer Program', 'Generate your API keys', 'Enter the API Key and Customer Number into VMO', 'Run the connection test' ],
                'tracking_url' => 'https://www.canadapost-postescanada.ca/track-reperage/en#/search?searchFor=',
            ],
            'royal_mail' => [
                'name' => 'Royal Mail', 'region' => 'europe', 'coverage' => 'UK & international',
                'signup_url' => 'https://developer.royalmail.net/',
                'docs_url' => 'https://developer.royalmail.net/',
                'needs_api' => true,
                'steps' => [ 'Register at Royal Mail Developer Portal', 'Create an application and obtain your API key', 'Enter the API Key into VMO', 'Run the connection test' ],
                'tracking_url' => 'https://www.royalmail.com/track-your-item#/tracking-results/',
            ],
            'sf_express' => [
                'name' => 'SF Express', 'region' => 'asia_pacific', 'coverage' => 'China & Asia-Pacific',
                'signup_url' => 'https://open.sf-express.com/',
                'docs_url' => 'https://open.sf-express.com/',
                'needs_api' => true,
                'steps' => [ 'Register at SF Express Open Platform', 'Apply for API access', 'Enter your App ID and App Key into VMO', 'Run the connection test' ],
                'tracking_url' => 'https://www.sf-express.com/us/en/dynamic_function/waybill/#search/bill-number/',
            ],
            'correios' => [
                'name' => 'Correios', 'region' => 'south_america', 'coverage' => 'Brazil & South America',
                'signup_url' => 'https://www.correios.com.br/atendimento/developers',
                'docs_url' => 'https://www.correios.com.br/',
                'needs_api' => true,
                'steps' => [ 'Create a Correios developer account', 'Request API access through your postal contract', 'Enter credentials into VMO', 'Run the connection test' ],
                'tracking_url' => 'https://rastreamento.correios.com.br/app/index.php?objetos=',
            ],
            'australia_post' => [
                'name' => 'Australia Post', 'region' => 'asia_pacific', 'coverage' => 'Australia & Oceania',
                'signup_url' => 'https://developers.auspost.com.au/',
                'docs_url' => 'https://developers.auspost.com.au/',
                'needs_api' => true,
                'steps' => [ 'Register at Australia Post Developers', 'Get your API key', 'Enter the API Key into VMO', 'Run the connection test' ],
                'tracking_url' => 'https://auspost.com.au/mypost/track/#/search?tracking=',
            ],
            // ─── Manual / Self-Delivery ───
            'manual_delivery' => [
                'name' => 'Manual / Self-Delivery', 'region' => 'local', 'coverage' => 'Your delivery area',
                'signup_url' => '',
                'docs_url' => '',
                'needs_api' => false,
                'steps' => [ 'No API setup needed', 'You or your team will handle delivery personally', 'VMO generates a tracking number automatically', 'Update delivery status manually as you fulfill' ],
                'tracking_url' => '',
            ],
        ];
    }

    /* ─── AJAX: Discover Carriers by Location ─── */

    public function ajax_discover_carriers() {
        if ( ! current_user_can( 'read' ) ) wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );
        $country = sanitize_text_field( wp_unslash( $_POST['country'] ?? '' ) );

        $registry = $this->get_carrier_registry();
        $region_map = [
            'US' => 'north_america', 'CA' => 'north_america', 'MX' => 'north_america',
            'GB' => 'europe', 'UK' => 'europe', 'DE' => 'europe', 'FR' => 'europe', 'IT' => 'europe', 'ES' => 'europe', 'NL' => 'europe', 'SE' => 'europe', 'NO' => 'europe', 'DK' => 'europe', 'FI' => 'europe', 'PL' => 'europe', 'AT' => 'europe', 'BE' => 'europe', 'CH' => 'europe', 'IE' => 'europe', 'PT' => 'europe',
            'AU' => 'asia_pacific', 'NZ' => 'asia_pacific', 'JP' => 'asia_pacific', 'CN' => 'asia_pacific', 'SG' => 'asia_pacific', 'MY' => 'asia_pacific', 'TH' => 'asia_pacific', 'KR' => 'asia_pacific', 'IN' => 'asia_pacific', 'PH' => 'asia_pacific', 'HK' => 'asia_pacific', 'TW' => 'asia_pacific',
            'AE' => 'middle_east_africa', 'SA' => 'middle_east_africa', 'EG' => 'middle_east_africa', 'KE' => 'middle_east_africa', 'NG' => 'middle_east_africa', 'ZA' => 'middle_east_africa', 'GH' => 'middle_east_africa', 'IL' => 'middle_east_africa', 'QA' => 'middle_east_africa', 'KW' => 'middle_east_africa',
            'BR' => 'south_america', 'AR' => 'south_america', 'CL' => 'south_america', 'CO' => 'south_america', 'PE' => 'south_america',
        ];

        $user_region = $region_map[ strtoupper( $country ) ] ?? '';
        $recommended = [];
        $available = [];

        foreach ( $registry as $slug => $data ) {
            $entry = array_merge( [ 'slug' => $slug ], $data );
            unset( $entry['steps'] ); // Don't send onboarding steps in discovery
            if ( $data['region'] === 'global' || $data['region'] === $user_region || $slug === 'manual_delivery' ) {
                $entry['recommended'] = ( $data['region'] === $user_region || $data['region'] === 'global' );
                $recommended[] = $entry;
            } else {
                $entry['recommended'] = false;
                $available[] = $entry;
            }
        }

        wp_send_json_success( [
            'detected_region' => $user_region ?: 'unknown',
            'recommended'     => $recommended,
            'other_available' => $available,
        ] );
    }

    /* ─── AJAX: Get Carrier Onboarding Steps ─── */

    public function ajax_get_carrier_onboarding() {
        if ( ! current_user_can( 'read' ) ) wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );
        $slug = sanitize_key( wp_unslash( $_POST['carrier_slug'] ?? '' ) );
        $registry = $this->get_carrier_registry();

        if ( ! isset( $registry[ $slug ] ) ) {
            wp_send_json_error( [ 'message' => 'Unknown carrier' ] );
        }

        $carrier = $registry[ $slug ];
        wp_send_json_success( [
            'slug'       => $slug,
            'name'       => $carrier['name'],
            'signup_url' => $carrier['signup_url'],
            'docs_url'   => $carrier['docs_url'],
            'needs_api'  => $carrier['needs_api'],
            'steps'      => $carrier['steps'],
        ] );
    }

    /* ─── AJAX: Mark Order as Delivered ─── */

    public function ajax_mark_delivered() {
        if ( ! current_user_can( 'read' ) ) wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );
        $order_id = (int) ( $_POST['order_id'] ?? 0 );
        $notes    = sanitize_textarea_field( wp_unslash( $_POST['delivery_notes'] ?? '' ) );

        if ( $order_id <= 0 ) wp_send_json_error( [ 'message' => 'Invalid order' ] );

        global $wpdb;
        $table   = $wpdb->prefix . 'vmo_shipping_orders';
        $user_id = get_current_user_id();

        $updated = $wpdb->update( $table, [
            'status'       => 'delivered',
            'delivered_at' => current_time( 'mysql' ),
            'updated_at'   => current_time( 'mysql' ),
        ], [ 'id' => $order_id, 'user_id' => $user_id ] );

        if ( $updated === false ) {
            wp_send_json_error( [ 'message' => 'Failed to update order' ] );
        }

        // Log delivery note in the shipping_status_log
        $log_table = $wpdb->prefix . 'vmo_shipping_status_log';
        if ( vmo_table_exists( $log_table ) ) {
            $wpdb->insert( $log_table, [
                'order_id'   => $order_id,
                'user_id'    => $user_id,
                'status'     => 'delivered',
                'notes'      => $notes ?: 'Marked as delivered',
                'created_at' => current_time( 'mysql' ),
            ] );
        }

        // Send delivery confirmation email
        $order = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE id = %d", $order_id ) );
        if ( $order && ! empty( $order->customer_email ) ) {
            $site_name = get_bloginfo( 'name' );
            wp_mail(
                $order->customer_email,
                "Your order has been delivered! - {$site_name}",
                "Hi {$order->customer_name},\n\nGreat news! Your order ({$order->order_ref}) has been delivered.\n\nThank you for shopping with {$site_name}!"
            );
        }

        if ( function_exists( 'vmo_business_flow_mark_from_shipping_order' ) ) {
            vmo_business_flow_mark_from_shipping_order( $order_id, $user_id, 'delivered', $notes ?: 'Marked delivered from the Shipping Manager.' );
        }

        wp_send_json_success( [ 'message' => 'Order marked as delivered', 'order_id' => $order_id ] );
    }

    /* ─── AJAX: Update Delivery Status (manual delivery pipeline) ─── */

    public function ajax_update_delivery_status() {
        if ( ! current_user_can( 'read' ) ) wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );
        $order_id = (int) ( $_POST['order_id'] ?? 0 );
        $status   = sanitize_key( wp_unslash( $_POST['new_status'] ?? '' ) );
        $notes    = sanitize_textarea_field( wp_unslash( $_POST['notes'] ?? '' ) );

        $allowed = [ 'pending', 'processing', 'picked_up', 'in_transit', 'out_for_delivery', 'shipped', 'delivered', 'returned', 'cancelled' ];
        if ( ! in_array( $status, $allowed, true ) ) {
            wp_send_json_error( [ 'message' => 'Invalid status. Allowed: ' . implode( ', ', $allowed ) ] );
        }

        global $wpdb;
        $table   = $wpdb->prefix . 'vmo_shipping_orders';
        $user_id = get_current_user_id();

        $update_data = [
            'status'     => $status,
            'updated_at' => current_time( 'mysql' ),
        ];
        if ( $status === 'shipped' || $status === 'in_transit' ) {
            $update_data['shipped_at'] = current_time( 'mysql' );
        }
        if ( $status === 'delivered' ) {
            $update_data['delivered_at'] = current_time( 'mysql' );
        }

        $wpdb->update( $table, $update_data, [ 'id' => $order_id, 'user_id' => $user_id ] );

        // Log the status change
        $log_table = $wpdb->prefix . 'vmo_shipping_status_log';
        if ( vmo_table_exists( $log_table ) ) {
            $wpdb->insert( $log_table, [
                'order_id'   => $order_id,
                'user_id'    => $user_id,
                'status'     => $status,
                'notes'      => $notes ?: 'Status updated to ' . $status,
                'created_at' => current_time( 'mysql' ),
            ] );
        }

        // Auto-generate VMO tracking number for manual delivery if none exists
        if ( in_array( $status, [ 'processing', 'picked_up', 'in_transit' ], true ) ) {
            $order = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE id = %d", $order_id ) );
            if ( $order && empty( $order->tracking_number ) ) {
                $vmo_tracking = 'VMO-' . strtoupper( wp_generate_password( 10, false ) );
                $wpdb->update( $table, [
                    'tracking_number' => $vmo_tracking,
                    'carrier'         => $order->carrier ?: 'manual_delivery',
                ], [ 'id' => $order_id ] );
            }
        }

        if ( function_exists( 'vmo_business_flow_mark_from_shipping_order' ) ) {
            vmo_business_flow_mark_from_shipping_order( $order_id, $user_id, $status, $notes ?: 'Delivery status updated from the Shipping Manager.' );
        }

        wp_send_json_success( [ 'message' => 'Status updated to ' . $status, 'order_id' => $order_id ] );
    }

    /* ─── REST: Public Tracking Page ─── */

    public function register_tracking_routes() {
        register_rest_route( 'vmo/v1', '/track/(?P<ref>[A-Za-z0-9\-]+)', [
            'methods'             => 'GET',
            'callback'            => [ $this, 'handle_public_tracking' ],
            'permission_callback' => '__return_true',
        ] );
    }

    public function handle_public_tracking( \WP_REST_Request $request ) {
        $ref = sanitize_text_field( $request->get_param( 'ref' ) );
        if ( ! $ref ) {
            return new \WP_REST_Response( [ 'error' => 'Tracking reference required' ], 400 );
        }

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

        // Look up by tracking_number or order_ref
        $order = $wpdb->get_row( $wpdb->prepare(
            "SELECT order_ref, customer_name, carrier, tracking_number, status, shipped_at, delivered_at, city, state, country, created_at FROM {$table} WHERE tracking_number = %s OR order_ref = %s LIMIT 1",
            $ref, $ref
        ) );

        if ( ! $order ) {
            return new \WP_REST_Response( [ 'error' => 'Order not found' ], 404 );
        }

        // Get status history
        $log_table = $wpdb->prefix . 'vmo_shipping_status_log';
        $history = [];
        if ( vmo_table_exists( $log_table ) ) {
            $rows = $wpdb->get_results( $wpdb->prepare(
                "SELECT status, notes, created_at FROM {$log_table} WHERE order_id = (SELECT id FROM {$table} WHERE tracking_number = %s OR order_ref = %s LIMIT 1) ORDER BY created_at ASC",
                $ref, $ref
            ), ARRAY_A );
            $history = $rows ?: [];
        }

        // Build carrier tracking URL if available
        $registry = $this->get_carrier_registry();
        $carrier_slug = sanitize_key( $order->carrier );
        $tracking_url = '';
        if ( isset( $registry[ $carrier_slug ]['tracking_url'] ) && $order->tracking_number ) {
            $tracking_url = $registry[ $carrier_slug ]['tracking_url'] . urlencode( $order->tracking_number );
        }

        $status_labels = [
            'pending'          => 'Order Received',
            'processing'       => 'Processing',
            'picked_up'        => 'Picked Up',
            'in_transit'       => 'In Transit',
            'out_for_delivery' => 'Out for Delivery',
            'shipped'          => 'Shipped',
            'delivered'        => 'Delivered',
            'returned'         => 'Returned',
            'cancelled'        => 'Cancelled',
        ];

        // Return HTML tracking page
        $site_name = get_bloginfo( 'name' );
        $status_label = $status_labels[ $order->status ] ?? ucfirst( $order->status );
        $is_delivered = ( $order->status === 'delivered' );
        $progress = array_search( $order->status, array_keys( $status_labels ) );
        $max_progress = 6; // delivered index

        ob_start();
        ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Track Your Order - <?php echo esc_html( $site_name ); ?></title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:#0a0f16;color:#e6f3ff;min-height:100vh;display:flex;align-items:center;justify-content:center;
background:radial-gradient(1200px 700px at 20% -10%,rgba(15,225,255,.06),transparent 60%),radial-gradient(1100px 650px at 100% 0%,rgba(124,92,255,.06),transparent 60%),linear-gradient(#07121a,#09131b 35%,#070d14)}
.track-container{width:min(600px,94vw);background:linear-gradient(135deg,rgba(14,29,41,.95),rgba(18,46,63,.95));border:1px solid rgba(15,225,255,.28);border-radius:22px;padding:32px;box-shadow:0 24px 60px rgba(0,0,0,.55)}
.track-header{text-align:center;margin-bottom:24px}
.track-header h1{font-size:20px;color:#0fe1ff;margin-bottom:4px;text-shadow:0 0 10px rgba(15,225,255,.3)}
.track-header p{color:#9fb2c8;font-size:13px}
.status-badge{display:inline-block;padding:6px 16px;border-radius:20px;font-size:13px;font-weight:600;margin:12px 0;
background:<?php echo $is_delivered ? 'rgba(16,185,129,.2)' : 'rgba(15,225,255,.15)'; ?>;
color:<?php echo $is_delivered ? '#10b981' : '#0fe1ff'; ?>;
border:1px solid <?php echo $is_delivered ? 'rgba(16,185,129,.4)' : 'rgba(15,225,255,.4)'; ?>}
.track-info{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:16px 0;font-size:13px}
.track-info div{padding:8px 12px;background:rgba(255,255,255,.03);border-radius:8px;border:1px solid rgba(255,255,255,.05)}
.track-info span{color:#9fb2c8;display:block;font-size:11px;margin-bottom:2px}
.progress-bar{display:flex;gap:4px;margin:20px 0}
.progress-step{flex:1;height:4px;border-radius:4px;background:rgba(255,255,255,.08)}
.progress-step.active{background:linear-gradient(90deg,#0fe1ff,#7c5cff)}
.progress-step.done{background:#0fe1ff}
.timeline{margin-top:20px}
.timeline h3{font-size:14px;color:#65f1ff;margin-bottom:12px}
.tl-item{display:flex;gap:12px;padding:8px 0;border-bottom:1px solid rgba(255,255,255,.05);font-size:12px}
.tl-dot{width:8px;height:8px;border-radius:50%;background:#0fe1ff;margin-top:4px;flex-shrink:0}
.tl-time{color:#9fb2c8;min-width:120px}
.carrier-link{display:inline-block;margin-top:16px;padding:10px 20px;border-radius:12px;background:linear-gradient(180deg,rgba(15,225,255,.15),rgba(15,225,255,.05));border:1px solid #0fe1ff;color:#0fe1ff;text-decoration:none;font-weight:600;font-size:13px}
.carrier-link:hover{background:linear-gradient(180deg,rgba(15,225,255,.25),rgba(15,225,255,.1));box-shadow:0 0 20px rgba(15,225,255,.3)}
</style>
</head>
<body>
<div class="track-container">
<div class="track-header">
<h1>📦 <?php echo esc_html( $site_name ); ?></h1>
<p>Order Tracking</p>
</div>
<div style="text-align:center">
<div class="status-badge"><?php echo esc_html( $status_label ); ?></div>
</div>
<div class="track-info">
<div><span>Order</span><strong><?php echo esc_html( $order->order_ref ); ?></strong></div>
<div><span>Carrier</span><strong><?php echo esc_html( ucfirst( str_replace( '_', ' ', $order->carrier ?: 'Pending' ) ) ); ?></strong></div>
<div><span>Tracking #</span><strong><?php echo esc_html( $order->tracking_number ?: '—' ); ?></strong></div>
<div><span>Destination</span><strong><?php echo esc_html( trim( $order->city . ', ' . $order->state . ' ' . $order->country, ', ' ) ); ?></strong></div>
<?php if ( $order->shipped_at ) : ?><div><span>Shipped</span><strong><?php echo esc_html( $order->shipped_at ); ?></strong></div><?php endif; ?>
<?php if ( $order->delivered_at ) : ?><div><span>Delivered</span><strong><?php echo esc_html( $order->delivered_at ); ?></strong></div><?php endif; ?>
</div>
<div class="progress-bar">
<?php for ( $i = 0; $i <= $max_progress; $i++ ) : ?>
<div class="progress-step <?php echo $i < $progress ? 'done' : ( $i === $progress ? 'active' : '' ); ?>"></div>
<?php endfor; ?>
</div>
<?php if ( $history ) : ?>
<div class="timeline">
<h3>Status History</h3>
<?php foreach ( $history as $h ) : ?>
<div class="tl-item">
<div class="tl-dot"></div>
<div class="tl-time"><?php echo esc_html( $h['created_at'] ); ?></div>
<div><?php echo esc_html( ( $status_labels[ $h['status'] ] ?? ucfirst( $h['status'] ) ) . ( $h['notes'] ? ' — ' . $h['notes'] : '' ) ); ?></div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if ( $tracking_url ) : ?>
<div style="text-align:center"><a href="<?php echo esc_url( $tracking_url ); ?>" target="_blank" rel="noopener" class="carrier-link">🔗 Track on <?php echo esc_html( ucfirst( $carrier_slug ) ); ?></a></div>
<?php endif; ?>
</div>
</body>
</html>
        <?php
        $html = ob_get_clean();
        echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        exit;
    }
}
