<?php

// Exit if accessed directly
if (!defined('ABSPATH')) {
    exit;
}


/**
 * Send API request to Aramex Unified Portal and return decoded JSON response.
 *
 * @param string $method   HTTP method (GET, POST, etc.).
 * @param string $endpoint API URL.
 * @param string $token    JWT token.
 * @param array  $body     Request body.
 *
 * @return array|WP_Error
 */
function aramex_unified_api_request( $method, $endpoint, $token = '', $body = [] ) {
    // Prepare signature for authentication
	$plugin_key = 'WOOCOM';
	$api_secret = WOOCOM_API_SECRET;
	$timestamp  = time();

	$parsed_url = wp_parse_url( $endpoint );
    $path = $parsed_url['path'] ?? '/';

    // remove ws/rest from the beginning of the path if it exists.
    $cleaned_path = ( strpos( $path, '/ws/rest' ) === 0 )
        ? preg_replace( '#^/ws/rest#', '', $path )
        : $path;
    wc_get_logger()->info("Aramex API Call: Cleaned Path Value: $cleaned_path", ['source' => 'aramex_test']);

    
	$query = [];
	if ( ! empty( $parsed_url['query'] ) ) {
		parse_str( $parsed_url['query'], $query );
	}

	// Canonical data
	if ( in_array( strtoupper( $method ), [ 'GET', 'DELETE' ], true ) ) {
		if ( ! empty( $query ) ) {
			$canonical_data = http_build_query( $query, '', '&', PHP_QUERY_RFC3986 );
		} else {
			$canonical_data = '';
		}
	} else {
		$canonical_data = ! empty( $body )
			? wp_json_encode( $body, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE )
			: '';
	}
    
	$data_hash = hash( 'sha256', $canonical_data );

    wc_get_logger()->info("Aramex API Call: Canonical Data: $canonical_data", ['source' => 'aramex_test']);
    // log canonical data length
    wc_get_logger()->info("Aramex API Call: Canonical Data Length: " . strlen( $canonical_data ), ['source' => 'aramex_test']);
    
    wc_get_logger()->info("Aramex API Call: Data Hash: $data_hash", ['source' => 'aramex_test']);

    $string_to_sign = implode( '|', [
		$plugin_key,
		$timestamp,
		strtoupper( $method ),
		$cleaned_path,
		$data_hash,
	] );
    
    wc_get_logger()->info("Aramex API Call: String to Sign: $string_to_sign", ['source' => 'aramex_test']);

	$signature = hash_hmac( 'sha256', $string_to_sign, $api_secret );

    wc_get_logger()->info("Aramex API Call: Signature: $signature", ['source' => 'aramex_test']);

    // Build headers for the API request
	$args = [
		'method'  => $method,
		'headers' => [
			'Content-Type' => 'application/json',
            'x-plugin-key' => $plugin_key,
			'x-timestamp'  => (string) $timestamp,
			'x-signature'  => $signature,
		],
		'timeout' => 180,
	];

    // Log the response
    wc_get_logger()->info("Aramex API Header Call : " . wp_json_encode( $args ), ['source' => 'aramex_test']);

	if ( ! empty( $body ) ) {
		$args['body'] = wp_json_encode( $body );
	}

	if ( $token ) {
		$args['headers']['up-cred'] = 'Bearer ' . sanitize_text_field( $token );
	}

    $is_https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
    // Force disable SSL verify only for specific dev URL
	$current_url = ( is_ssl() ? 'https://' : 'http://' ) .
    ( isset($_SERVER['HTTP_HOST']) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '' ) .
    ( isset($_SERVER['REQUEST_URI']) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '' );

	if (strpos($current_url, 'ecommerceplugins.dev.aramex.com/wordpress672') !== false) {
		$args['sslverify'] = false;
	}

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

	if ( is_wp_error( $response ) ) {
		return $response; // Return WP_Error
	}

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

	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return new WP_Error( 'json_decode_error', 'Failed to decode JSON from API response.' );
	}

	return $decoded;
}


/**
 * Helper: Get Alpha-3 Country Mapping
 */
function aramex_unified_get_alpha3_country_codes() {
    return [
        'AF' => 'AFG', 'AL' => 'ALB', 'DZ' => 'DZA', 'AD' => 'AND', 'AO' => 'AGO', 
        'AR' => 'ARG', 'AM' => 'ARM', 'AU' => 'AUS', 'AT' => 'AUT', 'AZ' => 'AZE', 
        'BH' => 'BHR', 'BD' => 'BGD', 'BB' => 'BRB', 'BY' => 'BLR', 'BE' => 'BEL',
        'BZ' => 'BLZ', 'BJ' => 'BEN', 'BO' => 'BOL', 'BA' => 'BIH', 'BW' => 'BWA',
        'BR' => 'BRA', 'BN' => 'BRN', 'BG' => 'BGR', 'BF' => 'BFA', 'BI' => 'BDI',
        'KH' => 'KHM', 'CM' => 'CMR', 'CA' => 'CAN', 'CF' => 'CAF', 'TD' => 'TCD',
        'CL' => 'CHL', 'CN' => 'CHN', 'CO' => 'COL', 'KM' => 'COM', 'CG' => 'COG',
        'CR' => 'CRI', 'HR' => 'HRV', 'CU' => 'CUB', 'CY' => 'CYP', 'CZ' => 'CZE',
        'DK' => 'DNK', 'DJ' => 'DJI', 'DM' => 'DMA', 'DO' => 'DOM', 'EC' => 'ECU',
        'EG' => 'EGY', 'SV' => 'SLV', 'GQ' => 'GNQ', 'ER' => 'ERI', 'EE' => 'EST',
        'ET' => 'ETH', 'FJ' => 'FJI', 'FI' => 'FIN', 'FR' => 'FRA', 'GA' => 'GAB',
        'GM' => 'GMB', 'GE' => 'GEO', 'DE' => 'DEU', 'GH' => 'GHA', 'GR' => 'GRC',
        'GT' => 'GTM', 'GN' => 'GIN', 'GY' => 'GUY', 'HT' => 'HTI', 'HN' => 'HND',
        'HU' => 'HUN', 'IS' => 'ISL', 'IN' => 'IND', 'ID' => 'IDN', 'IR' => 'IRN',
        'IQ' => 'IRQ', 'IE' => 'IRL', 'IL' => 'ISR', 'IT' => 'ITA', 'JM' => 'JAM',
        'JP' => 'JPN', 'JO' => 'JOR', 'KZ' => 'KAZ', 'KE' => 'KEN', 'KW' => 'KWT',
        'KG' => 'KGZ', 'LA' => 'LAO', 'LV' => 'LVA', 'LB' => 'LBN', 'LS' => 'LSO',
        'LR' => 'LBR', 'LY' => 'LBY', 'LT' => 'LTU', 'LU' => 'LUX', 'MG' => 'MDG',
        'MW' => 'MWI', 'MY' => 'MYS', 'MV' => 'MDV', 'ML' => 'MLI', 'MT' => 'MLT',
        'MX' => 'MEX', 'MD' => 'MDA', 'MC' => 'MCO', 'MN' => 'MNG', 'MA' => 'MAR',
        'MZ' => 'MOZ', 'MM' => 'MMR', 'NA' => 'NAM', 'NP' => 'NPL', 'NL' => 'NLD',
        'NZ' => 'NZL', 'NI' => 'NIC', 'NE' => 'NER', 'NG' => 'NGA', 'NO' => 'NOR',
        'OM' => 'OMN', 'PK' => 'PAK', 'PA' => 'PAN', 'PY' => 'PRY', 'PE' => 'PER',
        'PH' => 'PHL', 'PL' => 'POL', 'PT' => 'PRT', 'QA' => 'QAT', 'RO' => 'ROU',
        'RU' => 'RUS', 'RW' => 'RWA', 'SA' => 'SAU', 'SN' => 'SEN', 'RS' => 'SRB',
        'SG' => 'SGP', 'SK' => 'SVK', 'SI' => 'SVN', 'ZA' => 'ZAF', 'ES' => 'ESP',
        'LK' => 'LKA', 'SD' => 'SDN', 'SE' => 'SWE', 'CH' => 'CHE', 'SY' => 'SYR',
        'TJ' => 'TJK', 'TH' => 'THA', 'TG' => 'TGO', 'TN' => 'TUN', 'TR' => 'TUR',
        'TM' => 'TKM', 'UA' => 'UKR', 'AE' => 'ARE', 'GB' => 'GBR', 'US' => 'USA',
        'UZ' => 'UZB', 'VE' => 'VEN', 'VN' => 'VNM', 'YE' => 'YEM', 'ZW' => 'ZWE'
    ];
}


/**
 * Helper: Prepare Aramex Unified Portal Order Line Items
 */
function aramex_unified_prepare_order_items_data( $order ) {
    $data_lines = [];
    $extern_line_no = 1;
    $removed_sku_total = 0;
    $removed_sku_total_tax = 0;

    foreach ( $order->get_items() as $item ) {
        $product = $item->get_product();
        $product_qty = $item->get_quantity();
        $parent_product_id = $item->get_product_id();
        $product_tags = wp_get_post_terms( $parent_product_id, 'product_tag', [ 'fields' => 'names' ] );

        $product_sku = $product->get_sku();
        $product_price = $product->get_price();
        $line_total_tax = $item->get_total_tax();

        if ( in_array( ARXEC_STOCK_TAG, $product_tags ) ) {
            $data_lines[] = [
                "extern_line_no" => $extern_line_no++,
                "qty"            => $product_qty,
                "sku"            => $product_sku,
                "unit_price"     => $product_price,
                "title"          => $product->get_name(),
                "tax_rate"       => number_format( $line_total_tax, 2, '.', '' ),
                "product_tags"   => $product_tags,
            ];
        } else {
            $removed_sku_total += ( $product_price * $product_qty );
            $removed_sku_total_tax += $line_total_tax;
        }
    }

    return [
        'order_items'          => $data_lines,
        'removed_sku_total'    => $removed_sku_total,
        'removed_sku_tax_total'=> $removed_sku_total_tax,
    ];
}


/**
 * Helper: Prepare Plugin to Aramex Unified Portal Order Creation Payload
 */
function aramex_unified_build_order_create_payload( $order, $order_items_data ) {
    $alpha3 = aramex_unified_get_alpha3_country_codes();

    $billing_country = $order->get_billing_country();
    $shipping_country = $order->get_shipping_country();

    $billing_country_alpha3 = $alpha3[$billing_country] ?? $billing_country;
    $shipping_country_alpha3 = $alpha3[$shipping_country] ?? $shipping_country;

    $order_total = $order->get_total();
    $removed_total = $order_items_data['removed_sku_total'] + $order_items_data['removed_sku_tax_total'];
    $final_order_total = $order_total - $removed_total;

    $payment_method = $order->get_payment_method();
    $cts_service = ( $payment_method === 'cod' ) ? 'CODS' : '';

    $common_shipping_address = [
        'Address1' => $order->get_shipping_address_1(),
        'Address2' => $order->get_shipping_address_2(),
        'City'     => $order->get_shipping_city(),
        'Company'  => $order->get_shipping_company(),
        'Contact'  => $order->get_shipping_first_name() . ' ' . $order->get_shipping_last_name(),
        'Country'  => $shipping_country_alpha3,
        'Email'    => $order->get_billing_email(),
        'Phone1'   => $order->get_shipping_phone() ? $order->get_shipping_phone() : $order->get_billing_phone(),
        'State'    => $order->get_shipping_state(),
        'ZipCode'  => $order->get_shipping_postcode(),
    ];

    // Get shipping method name
    $shipping_methods = $order->get_shipping_methods();
    $shipping_method_name = '';

    if (!empty($shipping_methods)) {
        // Get the first shipping method object
        $shipping = reset($shipping_methods);
        $shipping_method_name = $shipping->get_name(); // Get only the shipping method name
    }

    // Use the proper WordPress function to get the plugin file path
    $plugin_file = ARXEC_PLUGIN_DIR . 'aramex-ecommcore.php';
    if (file_exists($plugin_file)) {
        $plugin_data = get_plugin_data($plugin_file);
        $plugin_version = $plugin_data['Version'];
    }

    // Get unique identifier from settings
    $unique_identifier = get_option('aramex_unified_identifier');

    return [
        'orderNumber'         => (string) $order->get_id(),
        'dateTime'            => gmdate( 'c', strtotime( $order->get_date_created() ) ),
        'FreightChargeAmount' => $order->get_shipping_total(),
        "transportation_mode" => $shipping_method_name,
        'currency'          => $order->get_currency(),

        'b_address' => [
            'Address1' => $order->get_billing_address_1(),
            'Address2' => $order->get_billing_address_2(),
            'City'     => $order->get_billing_city(),
            'Company'  => $order->get_billing_company(),
            'Contact'  => $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(),
            'Country'  => $billing_country_alpha3,
            'Email'    => $order->get_billing_email(),
            'Phone1'   => $order->get_billing_phone() ? $order->get_billing_phone() : $order->get_shipping_phone(),
            'State'    => $order->get_billing_state(),
            'ZipCode'  => $order->get_billing_postcode(),
        ],
        'c_address'          => $common_shipping_address,
        'd_address'          => $common_shipping_address,
        "plugin_store_id"    => $unique_identifier,
        'plugin_key'         => 'WOOCOM',
        'plugin_version'     => $plugin_version,
        'cts_service'        => $cts_service,
        'cts_value'          => ( $payment_method === 'cod' ) ? number_format( $final_order_total, 2, '.', '' ) : null,
        'country'            => $billing_country_alpha3,
        'store_notes'        => $order->get_customer_note(),
        'orderItems'         => $order_items_data['order_items'],
        'plugin_store_name'  => aramex_get_clean_blogname(),
        'plugin_domain'      =>  esc_url_raw( untrailingslashit( rest_url() ) ),
    ];
}


/**
 * Helper: Prepare Plugin to Aramex WMS Order Cancellation Payload
 */
function aramex_unified_build_order_cancel_payload( $order, $order_items_data, $create_after_cancelling = 0 ) {
    $alpha3 = aramex_unified_get_alpha3_country_codes();

    $billing_country = $order->get_billing_country();
    $shipping_country = $order->get_shipping_country();

    $billing_country_alpha3 = $alpha3[$billing_country] ?? $billing_country;
    $shipping_country_alpha3 = $alpha3[$shipping_country] ?? $shipping_country;

    $client_ref = $order->get_id();

    $payment_method = $order->get_payment_method();
    $cts_service = ( $payment_method === 'cod' ) ? 'CODS' : '';
    
    $order_total = $order->get_total();
    $removed_total = $order_items_data['removed_sku_total'] + $order_items_data['removed_sku_tax_total'];
    $final_order_total = $order_total - $removed_total;

    $common_shipping_address = [
        'Address1' => $order->get_shipping_address_1(),
        'Address2' => $order->get_shipping_address_2(),
        'City'     => $order->get_shipping_city(),
        'Company'  => $order->get_shipping_company(),
        'Contact'  => $order->get_shipping_first_name() . ' ' . $order->get_shipping_last_name(),
        'Country'  => $shipping_country_alpha3,
        'Email'    => $order->get_billing_email(),
        'Phone1'   => $order->get_shipping_phone() ? $order->get_shipping_phone() : $order->get_billing_phone(),
        'State'    => $order->get_shipping_state(),
        'ZipCode'  => $order->get_shipping_postcode(),
    ];

    // Use the proper WordPress function to get the plugin file path
    $plugin_file = ARXEC_PLUGIN_DIR . 'aramex-ecommcore.php';
    if (file_exists($plugin_file)) {
        $plugin_data = get_plugin_data($plugin_file);
        $plugin_version = $plugin_data['Version'];
    }

    // Get unique identifier from settings
    $unique_identifier = get_option('aramex_unified_identifier');
    
    // Build DataHeader
    $data_header = [
        'B_Address' => [
            'Address1' => $order->get_billing_address_1(),
            'Address2' => $order->get_billing_address_2(),
            'Address3' => null,
            'City'     => $order->get_billing_city(),
            'Company'  => $order->get_billing_company(),
            'Contact'  => $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(),
            'Country'  => $billing_country_alpha3,
            'Email'    => $order->get_billing_email(),
            'Phone1'   => $order->get_billing_phone(),
            'Phone1'   => $order->get_billing_phone() ? $order->get_billing_phone() : $order->get_shipping_phone(),
            'ZipCode'  => $order->get_billing_postcode(),
        ],
        'CTSService'   => $cts_service,
        'CTSValue'     => ( $payment_method === 'cod' ) ? number_format( $final_order_total, 2, '.', '' ) : null,
        'C_Address'    => $common_shipping_address,
        'D_Address'    => $common_shipping_address,
        'ClinetSystemRef'   => (string) $client_ref,
        'plugin_version'    => $plugin_version,
        "orderNumber"       => (string) $client_ref,
        "plugin_store_id"   => $unique_identifier,
        'plugin_key'    => 'WOOCOM',
        'Currency'      => $order->get_currency()
    ];

    // Build DataLines
    $data_lines = [];
    $line_no = 1;
    foreach ( $order_items_data['order_items'] as $item ) {
        $data_lines[] = [
            'ExternLineNo' => (string) $line_no++,
            'Qty'          => (int) $item['qty'],
            'SKU'          => $item['sku'],
            'UnitPrice'    => $item['unit_price'],
            'title'        => $item['title'],
        ];
    }

    return [
        'SO' => [
            'DataHeader' => $data_header,
            'DataLines'  => $data_lines
        ],
        'CreateAfterCancelling' => $create_after_cancelling
    ];
}


/**
 * Helper: Prepare Shipment Items Data for Aramex Unified Shipment API
 */
function aramex_unified_order_shipment_items_data( $order ) {
    $items_data = [];

    foreach ( $order->get_items() as $item_id => $item ) {
        $product   = $item->get_product();
        $quantity  = $item->get_quantity();

        $product_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();

        // Skip if product has Aramex-Stock tag
        if ( has_term( 'Aramex-Stock', 'product_tag', $product_id ) ) {
            continue;
        }

        $weight    = $product && $product->has_weight() ? (float) $product->get_weight() : 0.1;
        $length    = $product ? (float) $product->get_length() : 0;
        $width     = $product ? (float) $product->get_width() : 0;
        $height    = $product ? (float) $product->get_height() : 0;
        $sku       = $product ? $product->get_sku() : '';
        $name      = $item->get_name();

        // AFTER discount line total
        $line_total_after_discount = (float) $item->get_total();

        // Per-unit price AFTER discount
        $unit_price_after_discount = round(
            $line_total_after_discount / $quantity,
            2
        );

        //Get HS Code Value of Product
        if ( $product->is_type( 'variation' ) ) {
            $parent_id = $product->get_parent_id();
            $parent_product = wc_get_product( $parent_id );
        } else {
            $parent_product = $product;
        }

        $hs_code = $parent_product->get_meta( '_hscode' );

        if ( empty( $hs_code ) ) {
            $hs_code = $parent_product->get_attribute( 'hscode' );
        }

        if ( empty( $hs_code ) ) {
            $hs_code = '';
        }
        
        $items_data[] = [
            "description"    => $name,
            "sku_number"     => $sku,
            "quantity"       => $quantity,
            "weight"         => [
                "value" => $weight * $quantity,
                "unit"  => "KG",
            ],
            "comments"       => null,
            "dimensions"     => [
                "length" => $length,
                "width"  => $width,
                "height" => $height,
                "unit"   => "CM"
            ],
            "commodity_code"       => $hs_code ?: '',
            "goods_description"    => null,
            "country_of_origin"    => $order->get_shipping_country(),
            "customs_value" => [
                "value" => $unit_price_after_discount,
                "currency_code" => $order->get_currency()
            ],
            "container_number"     => null,
        ];
    }

    return $items_data;
}


/**
 * Build Create Shipment Payload for Aramex Unified Portal
 */
function aramex_unified_build_create_shipment_payload( $order, $order_items_data, $context = 'create' ) {
    // Shipping & Billing addresses
    $shipping = $order->get_address( 'shipping' );
    $billing  = $order->get_address( 'billing' );

    // If shipping address is empty, fallback to billing
    if ( empty($shipping['address_1']) ) {
        $shipping = $billing;
    }

    // Convert country codes to alpha-3
    $alpha3 = aramex_unified_get_alpha3_country_codes();
    $store_country = get_option('woocommerce_default_country'); 
    $store_country_parts = explode(":", $store_country)[0];
    $store_country_code    = isset($store_country_parts[0]) ? $store_country_parts[0] : '';
    $store_state_code      = isset($store_country_parts[1]) ? $store_country_parts[1] : '';

    $store_state_name = '';
    if ( $store_state_code ) {
        // Get WooCommerce country states list
        $states = WC()->countries->get_states( $store_country_code );
        if ( isset( $states[ $store_state_code ] ) ) {
            $store_state_name = $states[ $store_state_code ];
        }
    }

    // Fallback if state name not found in country like Dubai
    if (empty($store_state_name)) {
        $store_state_name = get_option('woocommerce_store_city');
    }
    // Prepare parties
    $parties = [
        [
            "party_type"            => "shipper",
            "line1"                 => get_option('woocommerce_store_address'),
            "line2"                 => get_option('woocommerce_store_address_2'),
            "line3"                 => null,
            "city"                  => get_option('woocommerce_store_city'),
            "state_or_province_code"=> $store_state_name,
            "post_code"             => get_option('woocommerce_store_postcode'),
            "country_code"          => $store_country_parts,
            "department"            => null,
            "person_name"           => aramex_get_clean_blogname(),
            "title"                 => null,
            "company_name"          => aramex_get_clean_blogname(),
            "phone_number1"         => get_option('woocommerce_store_phone') ?: '0000000000',
            "phone_number1_ext"     => null,
            "cell_phone"            => null,
            "email_address"         => get_option('admin_email', get_bloginfo('admin_email')),
            "tax_id"                => null,
        ],
        [
            "party_type"            => "consignee",
            "line1"                 => $shipping['address_1'],
            "line2"                 => $shipping['address_2'],
            "line3"                 => null,
            "city"                  => $shipping['city'],
            "state_or_province_code"=> $shipping['state'],
            "post_code"             => $shipping['postcode'],
            "country_code"          => $shipping['country'],
            "department"            => null,
            "person_name"           => trim($shipping['first_name'] . ' ' . $shipping['last_name']),
            "title"                 => null,
            "company_name"          => !empty($shipping['company']) ? $shipping['company'] : trim($shipping['first_name'].' '.$shipping['last_name']),
            "phone_number1"         => !empty($shipping['phone']) ? $shipping['phone'] : $billing['phone'],
            "phone_number1_ext"     => null,
            "cell_phone"            => null,
            "email_address"         => $shipping['email'] ?? $billing['email'] ?? '',
            "tax_id"                => null,
        ]
    ];

    // Calculate total weight and dimensions
    $total_weight = 0;
    $total_length = 0;
    $total_width  = 0;
    $total_height = 0;

    foreach ( $order_items_data as $item ) {
        $total_weight += $item['weight']['value'];
        $total_length += $item['dimensions']['length'];
        $total_width  += $item['dimensions']['width'];
        $total_height += $item['dimensions']['height'];
    }

    // Parcel information
    $parcel = [
        "number_of_pieces" => 1,
        "length"           => round(max($total_length, 1), 2),
        "width"            => round(max($total_width, 1), 2),
        "height"           => round(max($total_height, 1), 2),
        "length_unit"      => "CM",
        "weight"           => round(max($total_weight, 0.1), 2),
        "weight_unit"      => "KG"
    ];

    // Payment method 
    $payment_method = $order->get_payment_method();

    // Calculate subtotal and total for NON-Aramex items only
    $non_aramex_subtotal = 0;
    foreach ( $order_items_data as $item ) {
        if ( isset( $item['customs_value']['value'] ) ) {
            $non_aramex_subtotal += (float) $item['customs_value']['value'] * (int) ($item['quantity'] ?? 1);
        }
    }

    // If COD, we wll assume total = subtotal + shipping + fees for non-Aramex products
    $non_aramex_total = $non_aramex_subtotal;

    // Add only non-Aramex related shipping cost if any
    foreach ( $order->get_shipping_methods() as $shipping_item ) {
        $non_aramex_total += (float) $shipping_item->get_total();
    }
    
    // Shipment details
    $shipment_details = [
        "parcels"                       => [ $parcel ],
        "actual_weight"                 => [
                                                "value" => max($total_weight, 0.1),
                                                "unit"  => "KG"
                                            ],
        "chargeable_weight"            => null,
        "description_of_goods"         => null,
        "goods_origin_country"         => $shipping['country'],
        "product_group"                => null,
        "payment_type"                 => ($payment_method === 'cod') ? 'C' : 'P',
        "customs_value_amount"         => [
                                                "value"=> (float) $non_aramex_subtotal,
                                                "currency_code"=> $order->get_currency()
                                          ],
        "cash_on_delivery_amount"      => ($payment_method === 'cod') ? [
                        "value"        => (float) $non_aramex_total,
                        "currency_code"=> $order->get_currency(),
                    ] : null,
        "insurance_amount"             => null,
        "cash_additional_amount"       => null,
        "product_type"                 => null,
        "cash_additional_amount_description" => null,
        "collect_amount"               => null,
        "services"                     => null,
        "delivery_instructions"        => null,
        "additional_properties"        => null,
        "contains_dangerous_goods"     => false
    ];

    //create product type based on shipping method or fallback
    $product_type = null;

    // Get plugin option for rate calculator
    $enable_rate_calc = (int) get_option('arxec_enable_plugin_rate_calculator', 0);

    // Get order shipping method title (e.g. "Aramex EXP/DPX")
    $shipping_method_title = $order->get_shipping_method();

    if ( $enable_rate_calc === 0 ) {
        // Fallback mode
        $store_country   = explode(':', get_option('woocommerce_default_country'))[0];
        $store_country   = strtoupper($store_country);
        $dest_country    = strtoupper($shipping['country']);

        if ( $store_country === $dest_country ) {
            $product_type = 'OND'; // Domestic
        } else {
            $product_type = 'PPX'; // International
        }
    } else {
        // User-selected shipping method
        if ( !empty($shipping_method_title) && stripos($shipping_method_title, 'Aramex') !== false ) {
            // Extract last part after "/" or space (like DPX, EXP, etc.)
            if (preg_match('/([A-Z]{2,3})$/i', $shipping_method_title, $matches)) {
                $product_type = strtoupper($matches[1]);
            }
        }
    }

    // Assign product_type key to shipment details
    $shipment_details['product_type'] = $product_type ?: null;

    //Get Shiiping User ID from JWT token
    $loggedin_usertoken = get_option('aramex_unified_jwt_token');

    $shipping_id = 0; //default to 0
    if ($loggedin_usertoken) {
        $decoded_token = array_change_key_case(array_map('trim', aramex_decode_jwt_token($loggedin_usertoken)), CASE_LOWER);

        if (is_array($decoded_token) && isset($decoded_token['shipping_user_id'])) {
            $shipping_id = $decoded_token['shipping_user_id'];
        } 
    }

    $unique_identifier = get_option('aramex_unified_identifier');

    // Use the proper WordPress function to get the plugin file path
    $plugin_file = ARXEC_PLUGIN_DIR . 'aramex-ecommcore.php';
    if (file_exists($plugin_file)) {
        $plugin_data = get_plugin_data($plugin_file);
        $plugin_version = $plugin_data['Version'];
    }

    $payload = [
        "shipping_user_id"        => $shipping_id,
        "plugin_store_id"         => $unique_identifier,
        "plugin_key"              => "WOOCOM",
        // 'plugin_version'          => $plugin_version,
        "order_id"                => (string) $order->get_id(),
        "foreign_hawb"            => null,
        "transport_type"          => null,
        "date_time"               => $order->get_date_created() ? $order->get_date_created()->setTimezone(new DateTimeZone('UTC'))->format('c') : null,
        "due_date"                => null,
        "comments"                => $order->get_customer_note(),
        "pickup_location"         => null,
        "operations_instructions" => null,
        "accounts_instructions"   => null,
        "pickup_guid"             => null,
        "number"                  => null,
        "parties"                 => $parties,
        "shipment_details"        => $shipment_details,
        "shipment_items"          => $order_items_data
    ];

    // Add cancelled status if order is being cancelled for Shipment
    if ( $context === 'cancel' ) {
        $payload['shipment_status'] = 'cancelled';
    }

    return $payload;
}

// Helper: Get Clean Blog Name without multilingual tags and limit to 50 chars
function aramex_get_clean_blogname() {

    $name = get_bloginfo('name');

    // Detect multilingual string
    if (preg_match('/\[:[a-z]{2}\]/', $name)) {

        // Get current WP language
        $current_lang = substr(get_locale(), 0, 2);

        if (preg_match('/\[:' . $current_lang . '\](.*?)\[:/', $name, $match)) {
            $name = $match[1];
        } else {
            // remove tags and keep first text
            $name = preg_replace('/\[:.*?\]/', '', $name);
        }
    }

    return mb_substr(trim($name), 0, 50);
}

// Helper: Calculate Shipping Rate with transient caching per user + destination + weight
function arxec_calculate_aramex_shipping_rate($package, $items = [], $product_id = 0, $quantity = 1) {

    if (!get_option('arxec_enable_plugin_rate_calculator')) {
        return [];
    }

    // Prevent direct API call on product/cart page load
    if (!defined('DOING_AJAX') || !DOING_AJAX) {
        if (is_product() || is_cart()) {
            return [];
        }
    }

    $token = sanitize_text_field(get_option('aramex_unified_jwt_token'));
    if (empty($token)) {
        return [];
    }

    $decoded = array_change_key_case(
        array_map(fn($v) => is_string($v) ? trim($v) : $v, aramex_decode_jwt_token($token)),
        CASE_LOWER
    );

    if (empty($decoded['is_shipping']) || $decoded['is_shipping'] != 1) {
        return [];
    }

    $origin_country = explode(':', get_option('woocommerce_default_country'))[0];
    $total_weight   = 0;

    foreach ($items as $i) {
        $w = (float)($i['weight'] ?? 0);
        $q = (int)($i['qty'] ?? 1);
        $total_weight += $w * $q;
    }

    if ($total_weight <= 0) {
        return [];
    }

    // TRANSIENT CACHE
    $cache_key = 'aramex_rate_' . md5(
        serialize([
            'user_id'        => get_current_user_id(),
            'dest_city'      => $package['destination']['city'],
            'dest_postcode'  => $package['destination']['postcode'],
            'dest_country'   => $package['destination']['country'],
            'weight'         => $total_weight,
        ])
    );

    $cached_rates = get_transient($cache_key);
    if ($cached_rates !== false) {
        return $cached_rates;
    }

    // Build payload
    $payload = [
        "origin_address" => [
            "city"         => get_option('woocommerce_store_city'),
            "post_code"    => get_option('woocommerce_store_postcode'),
            "country_code" => $origin_country,
        ],
        "destination_address" => [
            "city"         => $package['destination']['city'],
            "post_code"    => $package['destination']['postcode'],
            "country_code" => $package['destination']['country'],
        ],
        "weight" => ["value" => $total_weight, "unit" => "KG"],
        "product_group_code" => ($origin_country === $package['destination']['country']) ? 'DOM' : 'EXP',
		"preferred_currency_code" => get_woocommerce_currency(),
        "shipping_user_id"   => $decoded['shipping_user_id'] ?? 0,
    ];
    
    // Payload log
    wc_get_logger()->info('[Aramex RateCalc] Payload: ' . wp_json_encode($payload), ['source' => 'aramex-ecommcore']);

    
    // Api Request
    $response = aramex_unified_api_request('POST', ARXEC_ORDER_RATE_CALCULATOR, $token, $payload);

    // Response log
    wc_get_logger()->info('[Aramex RateCalc] API Raw Response: ' . wp_json_encode($response), ['source' => 'aramex-ecommcore']);

    if (is_wp_error($response)) {
        wc_get_logger()->info('[Aramex RateCalc] API Error: '.$response->get_error_message(), ['source'=>'aramex-ecommcore']);
        return [];
    }

    if (isset($response['error'])) {
        wc_get_logger()->info('[Aramex RateCalc] API Error Array: '.wp_json_encode($response), ['source'=>'aramex-ecommcore']);
        return [];
    }

    $raw_body = is_array($response) ? ($response['body'] ?? json_encode($response)) : wp_remote_retrieve_body($response);
    $data = json_decode($raw_body, true);
    $valid = [];
    foreach ($data['RateResults'] ?? [] as $r) {
        if (isset($r['Amount'])) {
            $valid[] = [
                'Amount'       => (float)$r['Amount'],
                'Currency'     => $r['Currency'] ?? '',
                'ProductGroup' => $r['ProductGroup'] ?? '',
                'ProductType'  => $r['ProductType'] ?? '',
            ];
        }
    }

    // Save to transient
    set_transient($cache_key, $valid, 5);

    return $valid;
}
