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

/**
 * Free live shipping rates:
 * - Supports EasyPost + Shippo multi-carrier providers
 * - Applies to packages that contain auction listings only
 */

function stakmv_live_shipping_is_enabled() {
    return stakmv_get_option('live_shipping_enabled', 'no') === 'yes';
}

function stakmv_live_shipping_get_mode() {
    // Multi-carrier only.
    return 'multi';
}

function stakmv_live_shipping_get_api_mode() {
    $mode = stakmv_get_option('live_shipping_api_mode', 'test');
    return in_array($mode, array('test', 'live'), true) ? $mode : 'test';
}

function stakmv_live_shipping_get_provider() {
    $provider = stakmv_get_option('live_shipping_multi_provider', 'easypost');
    return in_array($provider, array('easypost', 'shippo'), true) ? $provider : 'easypost';
}

function stakmv_live_shipping_get_api_key($provider) {
    $api_mode = stakmv_live_shipping_get_api_mode();
    $suffix = $api_mode === 'live' ? 'live' : 'test';
    $option_key = $provider === 'shippo'
        ? 'stakmv_live_shipping_shippo_key_' . $suffix
        : 'stakmv_live_shipping_easypost_key_' . $suffix;

    return trim((string) get_option($option_key, ''));
}

function stakmv_live_shipping_debug_enabled() {
    return stakmv_get_option('live_shipping_debug', 'no') === 'yes';
}

function stakmv_live_shipping_log($message, $context = array()) {
    if (!stakmv_live_shipping_debug_enabled() || !function_exists('wc_get_logger')) {
        return;
    }

    $logger = wc_get_logger();
    $logger->debug($message . ' ' . wp_json_encode($context), array('source' => 'wcmv-live-shipping'));
}

function stakmv_live_shipping_first_non_empty($values) {
    if (!is_array($values)) {
        return '';
    }
    foreach ($values as $value) {
        $trimmed = trim((string) $value);
        if ($trimmed !== '') {
            return $trimmed;
        }
    }
    return '';
}

function stakmv_live_shipping_customer_field($shipping_getter, $billing_getter) {
    if (!function_exists('WC') || !WC() || !WC()->customer) {
        return array('value' => '', 'source' => '');
    }

    $customer = WC()->customer;

    if ($shipping_getter && is_callable(array($customer, $shipping_getter))) {
        $shipping_value = trim((string) $customer->{$shipping_getter}());
        if ($shipping_value !== '') {
            return array('value' => $shipping_value, 'source' => 'customer_shipping');
        }
    }

    if ($billing_getter && is_callable(array($customer, $billing_getter))) {
        $billing_value = trim((string) $customer->{$billing_getter}());
        if ($billing_value !== '') {
            return array('value' => $billing_value, 'source' => 'customer_billing');
        }
    }

    return array('value' => '', 'source' => '');
}

function stakmv_live_shipping_normalize_carrier($carrier) {
    $normalized = strtoupper(preg_replace('/[^A-Z0-9]/', '', (string) $carrier));

    if ($normalized === '') {
        return '';
    }
    if (strpos($normalized, 'USPS') !== false || strpos($normalized, 'UNITEDSTATESPOSTAL') !== false) {
        return 'USPS';
    }
    if (strpos($normalized, 'UPS') !== false) {
        return 'UPS';
    }
    if (strpos($normalized, 'FEDEX') !== false || strpos($normalized, 'FEDERAL') !== false) {
        return 'FedEx';
    }
    if (strpos($normalized, 'DHL') !== false) {
        return 'DHL';
    }
    if ($normalized === 'PICKUPONLY' || $normalized === 'LOCALPICKUP' || $normalized === 'PICKUP') {
        return 'PICKUP_ONLY';
    }
    return '';
}

function stakmv_live_shipping_get_allowed_carriers_for_package($profile) {
    $supported_carriers = array('USPS', 'UPS', 'FedEx', 'DHL');
    $allowed = stakmv_get_option('live_shipping_allowed_carriers', $supported_carriers);
    if (!is_array($allowed)) {
        $allowed = $supported_carriers;
    }

    $normalized_allowed = array();
    foreach ($allowed as $carrier) {
        $normalized = stakmv_live_shipping_normalize_carrier($carrier);
        if (in_array($normalized, $supported_carriers, true)) {
            $normalized_allowed[] = $normalized;
        }
    }
    $normalized_allowed = array_values(array_unique($normalized_allowed));

    // If listing preferences exist, enforce them.
    if (!empty($profile['preferred_carriers'])) {
        $preferred = array_values(array_unique(array_map('stakmv_live_shipping_normalize_carrier', (array) $profile['preferred_carriers'])));
        $preferred = array_values(array_filter($preferred, function ($carrier) use ($supported_carriers) {
            return in_array($carrier, $supported_carriers, true);
        }));

        if (empty($preferred)) {
            return $normalized_allowed;
        }
        if (empty($normalized_allowed)) {
            return $preferred;
        }
        $matched = array_values(array_intersect($normalized_allowed, $preferred));
        if (empty($matched)) {
            return array('__no_match__');
        }
        return $matched;
    }

    return $normalized_allowed;
}

function stakmv_live_shipping_build_package_profile($package) {
    $supported_carriers = array('USPS', 'UPS', 'FedEx', 'DHL');
    $profile = array(
        'eligible'           => false,
        'has_non_auction'    => false,
        'auction_item_count' => 0,
        'has_calculated'     => false,
        'has_flat'           => false,
        'flat_total'         => 0.0,
        'pickup_only'        => false,
        'preferred_carriers' => array(),
    );

    if (empty($package['contents']) || !is_array($package['contents'])) {
        return $profile;
    }

    $preferred = array();
    $pickup_only_count = 0;

    foreach ($package['contents'] as $item) {
        if (empty($item['product_id'])) {
            continue;
        }

        $product_id = (int) $item['product_id'];
        $listing_type = (string) get_post_meta($product_id, '_stakmv_auction_listing_type', true);

        if ($listing_type === '') {
            $profile['has_non_auction'] = true;
            continue;
        }

        $profile['auction_item_count']++;

        $shipping_mode = function_exists('stakmv_get_listing_shipping_mode')
            ? stakmv_get_listing_shipping_mode($product_id)
            : 'calculated';

        if ($shipping_mode === 'flat') {
            $profile['has_flat'] = true;
            $flat_cost = (float) get_post_meta($product_id, '_stakmv_auction_shipping_cost', true);
            $qty = isset($item['quantity']) ? (int) $item['quantity'] : 1;
            if ($flat_cost > 0) {
                $profile['flat_total'] += ($flat_cost * max(1, $qty));
            }
            continue;
        }

        if ($shipping_mode === 'free') {
            // Treat free shipping as a flat shipping mode with zero amount.
            $profile['has_flat'] = true;
            continue;
        }

        if ($shipping_mode === 'pickup_only') {
            $pickup_only_count++;
            continue;
        }

        $profile['has_calculated'] = true;

        $item_carriers = array();
        $saved_carriers = get_post_meta($product_id, '_stakmv_auction_shipping_carriers', true);
        if (is_array($saved_carriers)) {
            foreach ($saved_carriers as $saved_carrier) {
                $normalized = stakmv_live_shipping_normalize_carrier($saved_carrier);
                if (in_array($normalized, $supported_carriers, true)) {
                    $item_carriers[] = $normalized;
                }
            }
        }

        // Fall back to the listing primary carrier when no carrier list is stored.
        if (empty($item_carriers)) {
            $raw_carrier = (string) get_post_meta($product_id, '_stakmv_auction_shipping_carrier', true);
            $normalized = stakmv_live_shipping_normalize_carrier($raw_carrier);
            if (in_array($normalized, $supported_carriers, true)) {
                $item_carriers[] = $normalized;
            }
        }

        // No explicit listing preference = all supported carriers.
        if (empty($item_carriers)) {
            $item_carriers = $supported_carriers;
        }

        $item_carriers = array_values(array_unique($item_carriers));

        if (empty($preferred)) {
            foreach ($item_carriers as $carrier) {
                $preferred[$carrier] = $carrier;
            }
        } else {
            $item_map = array_fill_keys($item_carriers, true);
            $preferred = array_intersect_key($preferred, $item_map);
        }
    }

    if ($profile['auction_item_count'] > 0 && !$profile['has_non_auction'] && $profile['has_calculated'] && $pickup_only_count === 0) {
        $profile['eligible'] = true;
    }

    if ($profile['auction_item_count'] > 0 && !$profile['has_non_auction'] && !$profile['has_calculated'] && $profile['has_flat'] && $pickup_only_count === 0) {
        $profile['eligible'] = true;
    }

    if ($pickup_only_count > 0 && !$profile['has_flat'] && !$profile['has_calculated']) {
        $profile['eligible'] = true;
        $profile['pickup_only'] = true;
    }

    $profile['preferred_carriers'] = array_values($preferred);
    return $profile;
}

function stakmv_live_shipping_get_origin_vendor_id($package) {
    if (empty($package['contents']) || !is_array($package['contents'])) {
        return 0;
    }

    $vendor_ids = array();
    foreach ($package['contents'] as $item) {
        if (empty($item['product_id'])) {
            continue;
        }
        $vendor_id = (int) get_post_field('post_author', (int) $item['product_id']);
        if ($vendor_id > 0) {
            $vendor_ids[$vendor_id] = $vendor_id;
        }
    }

    if (count($vendor_ids) === 1) {
        $values = array_values($vendor_ids);
        return (int) $values[0];
    }

    return 0;
}

function stakmv_live_shipping_get_vendor_origin($vendor_id) {
    $vendor_id = (int) $vendor_id;
    if ($vendor_id <= 0) {
        return array();
    }

    $origin = array(
        'name'    => get_the_author_meta('display_name', $vendor_id),
        'street1' => (string) get_user_meta($vendor_id, 'stakmv_ship_origin_address_1', true),
        'street2' => (string) get_user_meta($vendor_id, 'stakmv_ship_origin_address_2', true),
        'city'    => (string) get_user_meta($vendor_id, 'stakmv_ship_origin_city', true),
        'state'   => (string) get_user_meta($vendor_id, 'stakmv_ship_origin_state', true),
        'zip'     => (string) get_user_meta($vendor_id, 'stakmv_ship_origin_postcode', true),
        'country' => (string) get_user_meta($vendor_id, 'stakmv_ship_origin_country', true),
    );

    if ($origin['name'] === '') {
        $origin['name'] = 'Vendor';
    }

    // Minimum fields for carrier rating.
    if ($origin['city'] === '' || $origin['zip'] === '' || $origin['country'] === '') {
        return array();
    }

    return $origin;
}

function stakmv_live_shipping_get_from_address($package = array()) {
    $base = function_exists('wc_get_base_location') ? wc_get_base_location() : array('country' => '', 'state' => '');

    $store_origin = array(
        'name'     => wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES),
        'street1'  => (string) get_option('woocommerce_store_address', ''),
        'street2'  => (string) get_option('woocommerce_store_address_2', ''),
        'city'     => (string) get_option('woocommerce_store_city', ''),
        'state'    => isset($base['state']) ? (string) $base['state'] : '',
        'zip'      => (string) get_option('woocommerce_store_postcode', ''),
        'country'  => isset($base['country']) ? (string) $base['country'] : '',
    );

    $vendor_id = stakmv_live_shipping_get_origin_vendor_id($package);
    if ($vendor_id > 0) {
        $vendor_origin = stakmv_live_shipping_get_vendor_origin($vendor_id);
        if (!empty($vendor_origin)) {
            return $vendor_origin;
        }
    }

    return $store_origin;
}

function stakmv_live_shipping_get_to_address($package) {
    $destination = isset($package['destination']) && is_array($package['destination']) ? $package['destination'] : array();

    $address_1_package = stakmv_live_shipping_first_non_empty(array(
        $destination['address_1'] ?? '',
        $destination['address'] ?? '',
    ));
    $address_2_package = stakmv_live_shipping_first_non_empty(array(
        $destination['address_2'] ?? '',
    ));
    $city_package = stakmv_live_shipping_first_non_empty(array(
        $destination['city'] ?? '',
    ));
    $state_package = stakmv_live_shipping_first_non_empty(array(
        $destination['state'] ?? '',
    ));
    $zip_package = stakmv_live_shipping_first_non_empty(array(
        $destination['postcode'] ?? '',
        $destination['postal_code'] ?? '',
    ));
    $country_package = stakmv_live_shipping_first_non_empty(array(
        $destination['country'] ?? '',
        $destination['country_code'] ?? '',
    ));

    $address_1_customer = stakmv_live_shipping_customer_field('get_shipping_address_1', 'get_billing_address_1');
    $address_2_customer = stakmv_live_shipping_customer_field('get_shipping_address_2', 'get_billing_address_2');
    $city_customer = stakmv_live_shipping_customer_field('get_shipping_city', 'get_billing_city');
    $state_customer = stakmv_live_shipping_customer_field('get_shipping_state', 'get_billing_state');
    $zip_customer = stakmv_live_shipping_customer_field('get_shipping_postcode', 'get_billing_postcode');
    $country_customer = stakmv_live_shipping_customer_field('get_shipping_country', 'get_billing_country');

    $street1 = $address_1_package !== '' ? $address_1_package : $address_1_customer['value'];
    $street2 = $address_2_package !== '' ? $address_2_package : $address_2_customer['value'];
    $city = $city_package !== '' ? $city_package : $city_customer['value'];
    $state = $state_package !== '' ? $state_package : $state_customer['value'];
    $zip = $zip_package !== '' ? $zip_package : $zip_customer['value'];
    $country = $country_package !== '' ? $country_package : $country_customer['value'];

    $to_address = array(
        'name'     => 'Customer',
        'street1'  => (string) $street1,
        'street2'  => (string) $street2,
        'city'     => (string) $city,
        'state'    => (string) $state,
        'zip'      => (string) $zip,
        'country'  => strtoupper((string) $country),
    );

    stakmv_live_shipping_log('Resolved destination address.', array(
        'zip'            => $to_address['zip'] !== '' ? 'set' : 'missing',
        'country'        => $to_address['country'] !== '' ? 'set' : 'missing',
        'city'           => $to_address['city'] !== '' ? 'set' : 'missing',
        'street1'        => $to_address['street1'] !== '' ? 'set' : 'missing',
        'zip_source'     => $zip_package !== '' ? 'package' : ($zip_customer['source'] ?: 'none'),
        'country_source' => $country_package !== '' ? 'package' : ($country_customer['source'] ?: 'none'),
    ));

    return $to_address;
}

function stakmv_live_shipping_build_parcel($package, $allowed_modes = array()) {
    $weight_oz = 0.0;
    $max_length_in = 0.0;
    $max_width_in = 0.0;
    $stacked_height_in = 0.0;

    foreach ($package['contents'] as $item) {
        if (empty($item['data']) || !is_a($item['data'], 'WC_Product')) {
            continue;
        }

        if (!empty($allowed_modes) && !empty($item['product_id'])) {
            $item_mode = function_exists('stakmv_get_listing_shipping_mode')
                ? stakmv_get_listing_shipping_mode((int) $item['product_id'])
                : 'calculated';
            if (!in_array($item_mode, $allowed_modes, true)) {
                continue;
            }
        }

        /** @var WC_Product $product */
        $product = $item['data'];
        $qty = max(1, (int) ($item['quantity'] ?? 1));

        $raw_weight = (float) $product->get_weight();
        if ($raw_weight <= 0) {
            $raw_weight = 1.0;
        }
        $item_weight_oz = function_exists('wc_get_weight')
            ? (float) wc_get_weight($raw_weight, 'oz')
            : $raw_weight;
        $weight_oz += ($item_weight_oz * $qty);

        $raw_length = (float) $product->get_length();
        $raw_width  = (float) $product->get_width();
        $raw_height = (float) $product->get_height();

        if ($raw_length <= 0) $raw_length = 1;
        if ($raw_width <= 0) $raw_width = 1;
        if ($raw_height <= 0) $raw_height = 1;

        $length_in = function_exists('wc_get_dimension')
            ? (float) wc_get_dimension($raw_length, 'in')
            : $raw_length;
        $width_in = function_exists('wc_get_dimension')
            ? (float) wc_get_dimension($raw_width, 'in')
            : $raw_width;
        $height_in = function_exists('wc_get_dimension')
            ? (float) wc_get_dimension($raw_height, 'in')
            : $raw_height;

        $max_length_in = max($max_length_in, $length_in);
        $max_width_in = max($max_width_in, $width_in);
        $stacked_height_in += ($height_in * $qty);
    }

    if ($weight_oz <= 0) {
        $weight_oz = 16.0;
    }
    if ($max_length_in <= 0) {
        $max_length_in = 1.0;
    }
    if ($max_width_in <= 0) {
        $max_width_in = 1.0;
    }
    if ($stacked_height_in <= 0) {
        $stacked_height_in = 1.0;
    }

    return array(
        'weight_oz' => round($weight_oz, 2),
        'length_in' => round($max_length_in, 2),
        'width_in'  => round($max_width_in, 2),
        'height_in' => round($stacked_height_in, 2),
    );
}

function stakmv_live_shipping_cache_key($provider, $package, $allowed_carriers) {
    $payload = array(
        'provider' => $provider,
        'api_mode' => stakmv_live_shipping_get_api_mode(),
        'dest'     => stakmv_live_shipping_get_to_address($package),
        'parcel'   => stakmv_live_shipping_build_parcel($package, array('calculated')),
        'allowed'  => $allowed_carriers,
    );

    return 'stakmv_live_ship_' . md5(wp_json_encode($payload));
}

function stakmv_live_shipping_fetch_rates($provider, $package, $allowed_carriers) {
    $cache_minutes = max(1, (int) stakmv_get_option('live_shipping_cache_minutes', 10));
    $cache_key = stakmv_live_shipping_cache_key($provider, $package, $allowed_carriers);
    $cached = get_transient($cache_key);

    if (is_array($cached)) {
        stakmv_live_shipping_log('Using cached provider rates.', array(
            'provider' => $provider,
            'count'    => count($cached),
        ));
        return $cached;
    }

    $api_key = stakmv_live_shipping_get_api_key($provider);
    if ($api_key === '') {
        return new WP_Error('missing_api_key', 'Missing shipping API key for selected provider.');
    }

    $rates = $provider === 'shippo'
        ? stakmv_live_shipping_request_shippo_rates($api_key, $package, $allowed_carriers)
        : stakmv_live_shipping_request_easypost_rates($api_key, $package, $allowed_carriers);

    if (is_wp_error($rates)) {
        return $rates;
    }

    set_transient($cache_key, $rates, $cache_minutes * MINUTE_IN_SECONDS);
    stakmv_live_shipping_log('Fetched provider rates from API.', array(
        'provider' => $provider,
        'count'    => count($rates),
    ));
    return $rates;
}

function stakmv_live_shipping_request_easypost_rates($api_key, $package, $allowed_carriers) {
    $parcel = stakmv_live_shipping_build_parcel($package, array('calculated'));
    $from = stakmv_live_shipping_get_from_address($package);
    $to = stakmv_live_shipping_get_to_address($package);

    if (empty($to['zip']) || empty($to['country'])) {
        stakmv_live_shipping_log('Destination missing required fields for EasyPost rate request.', array(
            'zip'     => $to['zip'] !== '' ? 'set' : 'missing',
            'country' => $to['country'] !== '' ? 'set' : 'missing',
        ));
        return new WP_Error('missing_destination', 'Destination address is incomplete for live shipping.');
    }

    $body = array(
        'shipment' => array(
            'from_address' => $from,
            'to_address'   => $to,
            'parcel'       => array(
                'length' => $parcel['length_in'],
                'width'  => $parcel['width_in'],
                'height' => $parcel['height_in'],
                'weight' => $parcel['weight_oz'],
            ),
        ),
    );

    $response = wp_remote_post('https://api.easypost.com/v2/shipments', array(
        'timeout' => 25,
        'headers' => array(
            'Authorization' => 'Basic ' . base64_encode($api_key . ':'),
            'Content-Type'  => 'application/json',
        ),
        'body' => wp_json_encode($body),
    ));

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

    $code = (int) wp_remote_retrieve_response_code($response);
    $json = json_decode((string) wp_remote_retrieve_body($response), true);

    if ($code < 200 || $code >= 300 || !is_array($json)) {
        return new WP_Error('easypost_http_error', 'EasyPost request failed.', array('status' => $code, 'body' => $json));
    }

    $raw_rates = isset($json['rates']) && is_array($json['rates']) ? $json['rates'] : array();
    $store_currency = strtoupper(get_woocommerce_currency());
    $rates = array();
    $debug_counts = array(
        'raw'             => count($raw_rates),
        'kept'            => 0,
        'skip_unknown'    => 0,
        'skip_disallowed' => 0,
        'skip_amount'     => 0,
        'skip_currency'   => 0,
    );

    foreach ($raw_rates as $rate) {
        $carrier = stakmv_live_shipping_normalize_carrier($rate['carrier'] ?? '');
        if ($carrier === '' || $carrier === 'PICKUP_ONLY') {
            $debug_counts['skip_unknown']++;
            continue;
        }
        if (!empty($allowed_carriers) && !in_array($carrier, $allowed_carriers, true)) {
            $debug_counts['skip_disallowed']++;
            continue;
        }

        $amount = isset($rate['rate']) ? (float) $rate['rate'] : -1;
        if ($amount < 0) {
            $debug_counts['skip_amount']++;
            continue;
        }

        $currency = strtoupper((string) ($rate['currency'] ?? $store_currency));
        if ($currency !== $store_currency) {
            $debug_counts['skip_currency']++;
            continue;
        }

        $rates[] = array(
            'carrier'       => $carrier,
            'service'       => (string) ($rate['service'] ?? 'Standard'),
            'amount'        => $amount,
            'currency'      => $currency,
            'delivery_days' => isset($rate['delivery_days']) ? (int) $rate['delivery_days'] : null,
        );
        $debug_counts['kept']++;
    }

    stakmv_live_shipping_log('EasyPost rate filtering summary.', array(
        'store_currency'   => $store_currency,
        'allowed_carriers' => $allowed_carriers,
        'counts'           => $debug_counts,
    ));

    return $rates;
}

function stakmv_live_shipping_request_shippo_rates($api_key, $package, $allowed_carriers) {
    $parcel = stakmv_live_shipping_build_parcel($package, array('calculated'));
    $from = stakmv_live_shipping_get_from_address($package);
    $to = stakmv_live_shipping_get_to_address($package);

    if (empty($to['zip']) || empty($to['country'])) {
        stakmv_live_shipping_log('Destination missing required fields for Shippo rate request.', array(
            'zip'     => $to['zip'] !== '' ? 'set' : 'missing',
            'country' => $to['country'] !== '' ? 'set' : 'missing',
        ));
        return new WP_Error('missing_destination', 'Destination address is incomplete for live shipping.');
    }

    $body = array(
        'address_from' => $from,
        'address_to'   => $to,
        'parcels'      => array(
            array(
                'length'        => (string) $parcel['length_in'],
                'width'         => (string) $parcel['width_in'],
                'height'        => (string) $parcel['height_in'],
                'distance_unit' => 'in',
                'weight'        => (string) $parcel['weight_oz'],
                'mass_unit'     => 'oz',
            ),
        ),
        'async' => false,
    );

    $response = wp_remote_post('https://api.goshippo.com/shipments/', array(
        'timeout' => 25,
        'headers' => array(
            'Authorization' => 'ShippoToken ' . $api_key,
            'Content-Type'  => 'application/json',
        ),
        'body' => wp_json_encode($body),
    ));

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

    $code = (int) wp_remote_retrieve_response_code($response);
    $json = json_decode((string) wp_remote_retrieve_body($response), true);

    if ($code < 200 || $code >= 300 || !is_array($json)) {
        return new WP_Error('shippo_http_error', 'Shippo request failed.', array('status' => $code, 'body' => $json));
    }

    $raw_rates = isset($json['rates']) && is_array($json['rates']) ? $json['rates'] : array();
    $store_currency = strtoupper(get_woocommerce_currency());
    $rates = array();
    $debug_counts = array(
        'raw'             => count($raw_rates),
        'kept'            => 0,
        'skip_unknown'    => 0,
        'skip_disallowed' => 0,
        'skip_amount'     => 0,
        'skip_currency'   => 0,
    );

    foreach ($raw_rates as $rate) {
        $carrier_name = (string) ($rate['provider'] ?? ($rate['provider_image_200'] ?? ''));
        $carrier = stakmv_live_shipping_normalize_carrier($carrier_name);
        if ($carrier === '' || $carrier === 'PICKUP_ONLY') {
            $debug_counts['skip_unknown']++;
            continue;
        }
        if (!empty($allowed_carriers) && !in_array($carrier, $allowed_carriers, true)) {
            $debug_counts['skip_disallowed']++;
            continue;
        }

        $amount = isset($rate['amount']) ? (float) $rate['amount'] : -1;
        if ($amount < 0) {
            $debug_counts['skip_amount']++;
            continue;
        }

        $currency = strtoupper((string) ($rate['currency'] ?? $store_currency));
        if ($currency !== $store_currency) {
            $debug_counts['skip_currency']++;
            continue;
        }

        $service = '';
        if (isset($rate['servicelevel']) && is_array($rate['servicelevel'])) {
            $service = (string) ($rate['servicelevel']['name'] ?? '');
        }
        if ($service === '') {
            $service = 'Standard';
        }

        $rates[] = array(
            'carrier'       => $carrier,
            'service'       => $service,
            'amount'        => $amount,
            'currency'      => $currency,
            'delivery_days' => isset($rate['estimated_days']) ? (int) $rate['estimated_days'] : null,
        );
        $debug_counts['kept']++;
    }

    stakmv_live_shipping_log('Shippo rate filtering summary.', array(
        'store_currency'   => $store_currency,
        'allowed_carriers' => $allowed_carriers,
        'counts'           => $debug_counts,
    ));

    return $rates;
}

function stakmv_live_shipping_build_wc_rates($provider_rates, $provider_slug) {
    if (empty($provider_rates)) {
        return array();
    }

    usort($provider_rates, function ($a, $b) {
        return ($a['amount'] <=> $b['amount']);
    });

    $wc_rates = array();
    $index = 0;

    foreach ($provider_rates as $rate) {
        $index++;
        $carrier = (string) ($rate['carrier'] ?? 'Carrier');
        $service = trim((string) ($rate['service'] ?? 'Standard'));
        $amount = (float) ($rate['amount'] ?? 0);
        $days = isset($rate['delivery_days']) ? (int) $rate['delivery_days'] : 0;

        $label = trim($carrier . ' ' . $service);
        if ($days > 0) {
            $label .= sprintf(' (%d day%s)', $days, $days === 1 ? '' : 's');
        }

        $rate_id = 'stakmv_live_' . sanitize_title($provider_slug . '_' . $carrier . '_' . $service . '_' . $index);
        $wc_rates[$rate_id] = new WC_Shipping_Rate($rate_id, $label, $amount, array(), 'stakmv_live');
    }

    return $wc_rates;
}

function stakmv_live_shipping_pickup_rate() {
    $rate_id = 'stakmv_pickup_only';
    return array(
        $rate_id => new WC_Shipping_Rate($rate_id, 'Pickup Only', 0, array(), 'local_pickup'),
    );
}

function stakmv_live_shipping_flat_rate($amount) {
    $rate_id = 'stakmv_listing_flat_shipping';
    return array(
        $rate_id => new WC_Shipping_Rate($rate_id, 'Shipping', max(0, (float) $amount), array(), 'stakmv_flat'),
    );
}

function stakmv_live_shipping_get_restricted_items($package, $destination_country) {
    $restricted = array();
    $country = strtoupper(trim((string) $destination_country));
    if ($country === '' || empty($package['contents']) || !is_array($package['contents'])) {
        return $restricted;
    }

    foreach ($package['contents'] as $item) {
        $product_id = isset($item['product_id']) ? (int) $item['product_id'] : 0;
        if ($product_id <= 0) {
            continue;
        }
        $listing_type = (string) get_post_meta($product_id, '_stakmv_auction_listing_type', true);
        if ($listing_type === '') {
            continue;
        }
        if (function_exists('stakmv_listing_ships_to_country') && !stakmv_listing_ships_to_country($product_id, $country)) {
            $restricted[$product_id] = get_the_title($product_id);
        }
    }

    return $restricted;
}

add_filter('woocommerce_package_rates', function ($rates, $package) {
    if (!stakmv_live_shipping_is_enabled()) {
        return $rates;
    }

    if (is_admin() && !wp_doing_ajax()) {
        return $rates;
    }

    $profile = stakmv_live_shipping_build_package_profile($package);
    if (!$profile['eligible']) {
        return $rates;
    }

    $destination = stakmv_live_shipping_get_to_address($package);
    $destination_country = strtoupper(trim((string) ($destination['country'] ?? '')));
    $restricted_items = stakmv_live_shipping_get_restricted_items($package, $destination_country);
    if (!empty($restricted_items)) {
        static $stakmv_shipping_country_restriction_notice = false;
        if (!$stakmv_shipping_country_restriction_notice) {
            wc_add_notice(
                __('One or more listings in your cart do not ship to your destination country.', 'stak-multivendor'),
                'error'
            );
            $stakmv_shipping_country_restriction_notice = true;
        }
        stakmv_live_shipping_log('Destination country blocked for listing shipping scope.', array(
            'country'  => $destination_country,
            'listings' => array_keys($restricted_items),
        ));
        return array();
    }

    if ($profile['pickup_only']) {
        return stakmv_live_shipping_pickup_rate();
    }

    if (!empty($profile['has_flat']) && empty($profile['has_calculated'])) {
        return stakmv_live_shipping_flat_rate((float) $profile['flat_total']);
    }

    $provider = stakmv_live_shipping_get_provider();
    $allowed_carriers = stakmv_live_shipping_get_allowed_carriers_for_package($profile);
    stakmv_live_shipping_log('Checkout package shipping profile.', array(
        'provider'           => $provider,
        'allowed_carriers'   => $allowed_carriers,
        'preferred_carriers' => array_values($profile['preferred_carriers']),
        'has_calculated'     => !empty($profile['has_calculated']),
        'has_flat'           => !empty($profile['has_flat']),
        'pickup_only'        => !empty($profile['pickup_only']),
    ));

    $provider_rates = stakmv_live_shipping_fetch_rates($provider, $package, $allowed_carriers);
    if (is_wp_error($provider_rates)) {
        stakmv_live_shipping_log('Provider rate request failed.', array(
            'error'    => $provider_rates->get_error_message(),
            'provider' => $provider,
        ));

        $fallback_mode = stakmv_get_option('live_shipping_fallback_mode', 'hide');
        if ($fallback_mode === 'flat') {
            $cost = (float) stakmv_get_option('live_shipping_fallback_cost', 0);
            $rate_id = 'stakmv_live_fallback_flat';
            return array(
                $rate_id => new WC_Shipping_Rate($rate_id, 'Shipping', max(0, $cost), array(), 'stakmv_live'),
            );
        }

        return $rates;
    }

    $live_rates = stakmv_live_shipping_build_wc_rates($provider_rates, $provider);
    if (!empty($live_rates)) {
        return $live_rates;
    }

    stakmv_live_shipping_log('No usable live rates for package after provider filtering.', array(
        'provider'       => $provider,
        'provider_count' => is_array($provider_rates) ? count($provider_rates) : 0,
        'fallback_mode'  => stakmv_get_option('live_shipping_fallback_mode', 'hide'),
    ));

    $fallback_mode = stakmv_get_option('live_shipping_fallback_mode', 'hide');
    if ($fallback_mode === 'flat') {
        $cost = (float) stakmv_get_option('live_shipping_fallback_cost', 0);
        $rate_id = 'stakmv_live_fallback_flat';
        return array(
            $rate_id => new WC_Shipping_Rate($rate_id, 'Shipping', max(0, $cost), array(), 'stakmv_live'),
        );
    }

    return $rates;
}, 999, 2);
