<?php
/**
 * Plugin Name: Aramex eCommCore
 * Description: A powerful custom plugin designed to seamlessly integrate Aramex Logistics & Shipping with eCommCore Portal for your WooCommerce store. 
 * Version: 1.0.6
 * Author: Aramex
 * Author URI: https://aramex.com
 * License: GPL v2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: aramex-ecommcore
 * Tags: woocommerce, shipping, aramex, logistics, fulfillment, api, webhooks
 */

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

// Define plugin directory constant safely
if (!defined('ARXEC_PLUGIN_DIR')) {
    define('ARXEC_PLUGIN_DIR', plugin_dir_path(__FILE__));
}

// Include files
$includes = [
    'plugin-unified-config.php',
    'plugin-unified-login.php',
    'plugin-unified-api.php',
    'plugin-unified-helper.php',
];

foreach ($includes as $file) {
    $file_path = ARXEC_PLUGIN_DIR . 'includes/' . $file;
    if (file_exists($file_path)) {
        require_once $file_path;
    }
}

// Plugin activation hook
register_activation_hook( __FILE__, 'aramex_unified_portal_plugin_unique_identifier' );
register_activation_hook(__FILE__, 'aramex_create_default_shipping_zone');

// Register Activation/Deactivation Hooks
register_deactivation_hook(__FILE__, 'aramex_unified_portal_plugin_deactivation');


/**
 * Trigger Aramex sync when order status becomes processing/on-hold
 */
add_action('woocommerce_order_status_processing', 'aramex_trigger_delayed_order_sync', 10, 1);
add_action('woocommerce_order_status_on-hold', 'aramex_trigger_delayed_order_sync', 10, 1);

function aramex_trigger_delayed_order_sync($order_id) {
    wc_get_logger()->info("Aramex Order Send Triigger: " . $order_id, ['source' => 'aramex_test']);
    if (get_transient("aramex_sync_lock_$order_id")) {
        return;
    }

    set_transient("aramex_sync_lock_$order_id", true, 60);

    add_action('shutdown', function () use ($order_id) {
        $nonce = wp_create_nonce('aramex_background_sync');
        $url = add_query_arg([
            'action'   => 'aramex_background_sync',
            'order_id' => $order_id,
            'security' => $nonce,
        ], admin_url('admin-ajax.php'));

        // Fire async background request (non-blocking)
        wp_remote_post($url, [
            'timeout' => 1,
            'blocking' => false,
            'sslverify' => false,
        ]);
    });

}

/**
 * Cancelled → Send Cancel API immediately (no delay)
 */
add_action('woocommerce_order_status_changed', function($order_id, $old_status, $new_status, $order) {
    if ($new_status === 'cancelled') {
        aramex_unified_send_cancel_or_update_to_wms($order_id, 0);
        aramex_unified_send_cancel_shipment($order_id, 0);
    }
}, 10, 4);


/**
 * Order updated if Address or status then Send update API
 */
add_action('woocommerce_update_order', function($order_id) {
    add_action('shutdown', function () use ($order_id) {
        $order = wc_get_order($order_id);
        if (!$order || $order->get_status() === 'cancelled') return;

        $created = strtotime($order->get_date_created());
        if ($created && (time() - $created < 60)) {
            return;
        }

        $last_updated = get_post_meta($order_id, '_aramex_last_update_api', true);
        if ($last_updated && time() - $last_updated < 30) {
            return;
        }

        update_post_meta($order_id, '_aramex_last_update_api', time());

        // If shipment already created, then only trigger update API. This is to avoid triggering update API before create API in case of new order.
        if ( get_post_meta($order_id, '_aramex_shipment_created', true) ) {

            // reset shipment flag so API can run again
            delete_post_meta($order_id, '_aramex_shipment_created');

            // re-create shipment
            aramex_unified_send_create_shipment( $order_id );
        }

        aramex_unified_send_cancel_or_update_to_wms($order_id, 1);
    });
});


// Handle background async Aramex sync
add_action('wp_ajax_nopriv_aramex_background_sync', 'aramex_background_sync_callback');
add_action('wp_ajax_aramex_background_sync', 'aramex_background_sync_callback');

function aramex_background_sync_callback() {
    wc_get_logger()->info("Aramex Background Sync Callback Triggered", ['source' => 'aramex_test']);

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce already validated earlier via AJAX trigger.
    $order_id_raw = isset($_GET['order_id']) ? sanitize_text_field( wp_unslash( $_GET['order_id'] ) ) : 0;

    // phpcs:ignore WordPress.Input.Validation.NotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated -- Input sanitized and cast to integer.
    $order_id = intval( sanitize_text_field( $order_id_raw ) );


    if ( ! $order_id ) {
        wp_die('Missing order_id');
    }

    try {
        aramex_send_order_to_unified_api($order_id);
        aramex_send_all_unsynced_orders_to_unified($order_id);
    } catch (Exception $e) {
    } finally {
        delete_transient("aramex_sync_lock_$order_id");
    }

    wp_die();
}

/**
 * Enqueue Styles and Scripts.
 *
 * Loads necessary CSS and JavaScript files on the admin pages.
 *
 * @param string $hook The current admin page hook.
 */
function aramex_unified_portal_enqueue_assets($hook) {
    if ($hook === 'toplevel_page_ecommcore-login') {

        // Enqueue CSS
        wp_enqueue_style(
            'aramex-style',
            plugins_url('assets/css/style.css', __FILE__),
            array(),
            '1.0.0'
        );

        //For Open in new tab after success login using option
        $redirect_url = get_option('aramex_post_login_redirect_url');
		if ($redirect_url) {
			delete_option('aramex_post_login_redirect_url');
			wp_localize_script('aramex-login-script', 'aramexUP', [
                'redirectUrl' => esc_url_raw($redirect_url),
            ]);
		}
    }
}

add_action('admin_enqueue_scripts', 'aramex_unified_portal_enqueue_assets');

// Enqueue Rate Calculator assets on Cart and Product pages
add_action('wp_enqueue_scripts', 'aramex_enqueue_rate_calc_assets');
function aramex_enqueue_rate_calc_assets() {
    if (is_cart() || is_product()) {

        wp_enqueue_style(
            'aramex-rate-style',
            plugin_dir_url(__FILE__) . 'assets/css/aramex-rate.css',
            array(),
            '1.0.0'
        );
        
        wp_enqueue_script(
            'aramex-rate-calc',
            plugins_url('assets/js/rates-calculator.js', __FILE__),
            ['jquery'],
            '1.0.0',
            true
        );

        wp_localize_script('aramex-rate-calc', 'aramexRateCalc', [
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce'    => wp_create_nonce('aramex_rate_calc_nonce')
        ]);
    }
}

// Add body class for plugin page screen background image.
/* phpcs:disable WordPress.Security.NonceVerification.Recommended */
add_filter( 'admin_body_class', 'aramex_add_unified_login_body_class' );
function aramex_add_unified_login_body_class( $classes ) {

	$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';

	if ( $page === 'ecommcore-login' ) {
		$classes .= ' ecommcore-login-page';
	}

	return $classes;
}


// Add Aramex shipping method programmatically based on Rate Calculation API.
add_filter('woocommerce_package_rates', 'arxec_add_aramex_shipping_programmatically', 10, 2);
function arxec_add_aramex_shipping_programmatically($rates, $package) {
    // Check if rate calculator is globally enabled
    $enable_global   = get_option('arxec_enable_plugin_rate_calculator');
    $enable_checkout = get_option('arxec_enable_rate_calculator_on_checkout');

    // Disable API call if global or checkout flag is off
    if (!$enable_global || (is_checkout() && !$enable_checkout)) {
        return $rates;
    }

    //Build items from package (cart/checkout)
    $items = [];
    if (!empty($package['contents'])) {
        foreach ($package['contents'] as $cart_item) {
            $product = $cart_item['data'];
            $items[] = [
                'weight' => (float) $product->get_weight(),
                'qty'    => (int) $cart_item['quantity'],
            ];
        }
    }

    // Call Aramex API to get shipping rates
    $aramex_rates = arxec_calculate_aramex_shipping_rate($package, $items);

    // Add each Aramex rate as a shipping method
    if (!empty($aramex_rates)) {
        foreach ($aramex_rates as $rate) {
            if (is_array($rate) && isset($rate['Amount'], $rate['ProductGroup'], $rate['ProductType'])) {
                $rate_id = sanitize_title('aramex_' . ($rate['ProductGroup'] ?? '') . '_' . ($rate['ProductType'] ?? ''));
                $rates[$rate_id] = new WC_Shipping_Rate(
                    $rate_id,
                    'Aramex ' . ($rate['ProductGroup'] ?? '') . '/' . ($rate['ProductType'] ?? ''),
                    floatval($rate['Amount']),
                    [],
                    'aramex'
                );
            }
        }
    }

    return $rates;
}

// Add Rate Calculator button on product detail page
add_action('woocommerce_after_add_to_cart_button', 'aramex_rate_calc_button_product');
function aramex_rate_calc_button_product() {
    $enable_global  = get_option('arxec_enable_plugin_rate_calculator');
    $enable_product = get_option('arxec_enable_rate_calculator_on_product_detail');

    // Global disable or product page disable
    if (!$enable_global || !$enable_product) return;

    global $product;
    if (!$product) return;

    $product_id = $product->get_id();

    echo '<button type="button"
                 class="button aramex-rate-calc-btn"
                 data-context="product"
                 data-product_id="' . esc_attr($product_id) . '"
                 style="width:115px;display:inline-block;margin-top:10px;">
                 Rate Calculator
          </button>';
}


// Show Rate Calculator button on cart page Only
add_action('wp_footer', function() {

    if (!is_cart()) return;

    // Disable Rate Calc Button if cart empty 
    if (WC()->cart && WC()->cart->is_empty()) return;

    $enable_global = get_option('arxec_enable_plugin_rate_calculator');
    $enable_cart   = get_option('arxec_enable_rate_calculator_on_cart');
    if (!$enable_global || !$enable_cart) return;
    ?>
    <div id="aramex-rate-calc-template">
        <div class="aramex-rate-calc-wrapper" style="margin:15px 0;">
            <button type="button" class="button aramex-rate-calc-btn" data-context="cart">Rate Calculator</button>
        </div>
    </div>
    <?php
});

// Show Rate Calculator Popup
add_action('wp_footer', 'aramex_rate_calc_popup');
function aramex_rate_calc_popup() {
    $enable_global  = get_option('arxec_enable_plugin_rate_calculator');
    $enable_product = get_option('arxec_enable_rate_calculator_on_product_detail');
    $enable_cart    = get_option('arxec_enable_rate_calculator_on_cart');

    if (!$enable_global) return;
    if (is_product() && !$enable_product) return;
    if (is_cart() && !$enable_cart) return;
    if (!is_product() && !is_cart()) return;
    ?>
    <div id="aramex-rate-popup">
        <div class="aramex-rate-box">

            <button type="button" id="aramex-rate-close">&times;</button>

            <h2>Rate Calculator</h2>
            <p>Enter your shipment destination to view shipping rates</p>

            <form id="aramex-rate-form">
                <input type="text" name="aramex_city" placeholder="City" required>

                <input type="text" name="aramex_postcode" placeholder="Zip Code" required>

                <?php 
                $countries_obj = new WC_Countries();
                $countries = $countries_obj->get_countries();
                ?>
                <select name="aramex_country" required>
                    <option value="">Select Country</option>
                    <?php foreach ($countries as $code => $name) : ?>
                        <option value="<?php echo esc_attr($code); ?>"><?php echo esc_html($name); ?></option>
                    <?php endforeach; ?>
                </select>

                <button type="submit" class="button button-primary">Calculate</button>
            </form>

            <div id="aramex-rate-result"></div>
        </div>
    </div>

    <?php
}

// AJAX: Calculate Aramex Rate
add_action('wp_ajax_aramex_rate_calc', 'aramex_rate_calc_ajax');
add_action('wp_ajax_nopriv_aramex_rate_calc', 'aramex_rate_calc_ajax');
function aramex_rate_calc_ajax() {

    check_ajax_referer('aramex_rate_calc_nonce', 'security');

    if (!get_option('arxec_enable_plugin_rate_calculator')) {
        wp_send_json_error(['message' => 'Rate Calculator disabled']);
    }

    $city     = isset($_POST['city']) ? sanitize_text_field( wp_unslash( $_POST['city'] ) ) : '';
    $postcode = isset($_POST['postcode']) ? sanitize_text_field( wp_unslash( $_POST['postcode'] ) ) : '';
    $country  = isset($_POST['country']) ? strtoupper( sanitize_text_field( wp_unslash( $_POST['country'] ) ) ) : '';
    $product_id = intval($_POST['product_id'] ?? 0);
    $qty        = intval($_POST['qty'] ?? 1);

    if (!$city || !$postcode || !$country) {
        wp_send_json_error(['message' => 'Missing destination fields']);
    }

    $package = ['destination' => compact('city', 'postcode', 'country')];
    $items   = [];

    // Product Page (simple & variable products)
    $variation_id = intval($_POST['variation_id'] ?? 0);

    if ($product_id > 0) {
        if ($variation_id > 0) {
            $product = wc_get_product($variation_id);
        } else {
            $product = wc_get_product($product_id);
        }

        if ($product) {
            // If base product is variable and no variation selected -> ask to select
            if ($product->is_type('variable') && $variation_id === 0) {
                wp_send_json_error(['message' => 'Please select a product variation to calculate shipping']);
            }

            $weight = (float) $product->get_weight();
            if ($weight > 0) {
                $items[] = ['weight' => $weight, 'qty' => $qty];
            }
        }
    }

    // Cart Page
    elseif (WC()->cart && !empty(WC()->cart->get_cart())) {
        foreach (WC()->cart->get_cart() as $cart_item) {
            $p_weight = (float) $cart_item['data']->get_weight();
            if ($p_weight > 0) {
                $items[] = ['weight' => $p_weight, 'qty' => $cart_item['quantity']];
            }
        }
    }

    if (empty($items)) {
        wp_send_json_error(['message' => 'No products with weight found']);
    }

    $rates = arxec_calculate_aramex_shipping_rate($package, $items, $product_id, $qty);

    if (!empty($rates)) {
        wp_send_json_success(['rates' => $rates]);
    } else {
        wp_send_json_error(['message' => 'No rates found']);
    }

}


/**
 * Ensure HS Code attribute exists
 */
add_action( 'admin_init', function () {

    if ( ! function_exists( 'wc_create_attribute' ) ) {
        return;
    }

    $attribute_slug = 'hscode';

    foreach ( wc_get_attribute_taxonomies() as $attribute ) {
        if ( $attribute->attribute_name === $attribute_slug ) {
            return;
        }
    }

    wc_create_attribute( [
        'name' => 'HS Code',
        'slug' => $attribute_slug,
        'type' => 'text',
    ] );

    delete_transient( 'wc_attribute_taxonomies' );
});



/**
 * Add HS Code attribute field in Inventory tab
 */
add_action( 'woocommerce_product_options_inventory_product_data', function () {

    global $product_object;

    woocommerce_wp_text_input( [
        'id'          => '_hscode',
        'label'       => __( 'HS Code', 'aramex-ecommcore' ),
        'description' => __( 'Harmonized System code for customs & shipping.', 'aramex-ecommcore' ),
        'desc_tip'    => true,
        'value'       => $product_object ? $product_object->get_meta('_hscode') : '',
    ] );

});


/**
 * Save HS Code as product attribute
 */
add_action( 'woocommerce_admin_process_product_object', function ( $product ) {

    // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce already verified by WooCommerce before this hook runs
    if ( ! isset( $_POST['_hscode'] ) ) {
        return;
    }

    // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce already verified by WooCommerce before this hook runs
    $hs_code = sanitize_text_field( wp_unslash( $_POST['_hscode'] ) );
    $product->update_meta_data( '_hscode', $hs_code );

    if ( $hs_code ) {

        $attributes = $product->get_attributes();

        $attribute = new WC_Product_Attribute();
        $attribute->set_id( wc_attribute_taxonomy_id_by_name( 'hscode' ) );
        $attribute->set_name( 'pa_hscode' );
        $attribute->set_options( [ $hs_code ] );
        $attribute->set_visible( false );
        $attribute->set_variation( false );

        $attributes['pa_hscode'] = $attribute;

        $product->set_attributes( $attributes );
        $product->save();
    }

});

