/**
 * Plugin Name:  Peptio – Multi-Warehouse Dispatch Board Bridge
 * Description:  Shared dispatch-board routing foundation for Dispatch Darian, Dispatch Darian and Shipping Señorita. Reads the warehouse assignment already stored on WooCommerce orders.
 * Version:      1.0.0
 * Author:       Peptio
 *
 * CODE SNIPPETS VERSION:
 * Paste into a PHP snippet WITHOUT adding <?php.
 * Set the snippet to run everywhere.
 *
 * PURPOSE:
 * - Dispatch Darian remains the master / emergency dispatch board and can see ALL orders.
 * - Dispatch Darian is restricted to HQ fulfilment orders.
 * - Shipping Señorita is restricted to Europe fulfilment orders.
 * - Uses the existing `_pepti_fulfilment_warehouse` order meta written by
 *   the Peptio multi-warehouse routing system.
 * - Does NOT modify stock.
 * - Does NOT modify tracking.
 * - Does NOT mark orders completed.
 * - Does NOT modify QR dispatch.
 * - Does NOT modify Dispatch Darian yet.
 */

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

/* ==========================================================================
   LOAD GUARD
   ========================================================================== */

if (defined('PEPTI_DISPATCH_BOARD_BRIDGE_LOADED')) {
    return;
}

define(
    'PEPTI_DISPATCH_BOARD_BRIDGE_LOADED',
    true
);

define(
    'PEPTI_DISPATCH_BOARD_BRIDGE_VERSION',
    '1.0.0'
);


/* ==========================================================================
   EXISTING WAREHOUSE ORDER META
   ========================================================================== */

/**
 * This is the fulfilment decision already written by the
 * Peptio multi-warehouse routing system.
 *
 * Expected values:
 *
 * hq = HQ / UK / Rest of World fulfilment
 * eu = Europe fulfilment
 */
if (!defined('PEPTI_DISPATCH_META_WAREHOUSE')) {
    define(
        'PEPTI_DISPATCH_META_WAREHOUSE',
        '_pepti_fulfilment_warehouse'
    );
}

if (!defined('PEPTI_DISPATCH_META_WAREHOUSE_NAME')) {
    define(
        'PEPTI_DISPATCH_META_WAREHOUSE_NAME',
        '_pepti_fulfilment_warehouse_name'
    );
}

if (!defined('PEPTI_DISPATCH_META_ROUTING_COUNTRY')) {
    define(
        'PEPTI_DISPATCH_META_ROUTING_COUNTRY',
        '_pepti_routing_country'
    );
}

if (!defined('PEPTI_DISPATCH_META_FALLBACK')) {
    define(
        'PEPTI_DISPATCH_META_FALLBACK',
        '_pepti_warehouse_fallback_used'
    );
}

if (!defined('PEPTI_DISPATCH_META_ERROR')) {
    define(
        'PEPTI_DISPATCH_META_ERROR',
        '_pepti_warehouse_routing_error'
    );
}


/* ==========================================================================
   BOARD IDENTITIES
   ========================================================================== */

/**
 * Board keys are intentionally short and fixed.
 *
 * kate      = master board
 * darian    = HQ warehouse
 * senorita  = Europe warehouse
 */
function pepti_dispatch_board_profiles() {

    $profiles = [

        'kate' => [
            'key'            => 'kate',
            'name'           => 'Dispatch Darian',
            'icon'           => '👩🏽',
            'subtitle'       => 'Master Dispatch System',
            'warehouse'      => 'all',
            'master'         => true,
            'allow_unassigned' => true,
        ],

        'darian' => [
            'key'            => 'darian',
            'name'           => 'Dispatch Darian',
            'icon'           => '📦',
            'subtitle'       => 'HQ Dispatch System',
            'warehouse'      => 'hq',
            'master'         => false,
            'allow_unassigned' => false,
        ],

        'senorita' => [
            'key'            => 'senorita',
            'name'           => 'Shipping Señorita',
            'icon'           => '💃🏻',
            'subtitle'       => 'Europe Dispatch System',
            'warehouse'      => 'eu',
            'master'         => false,
            'allow_unassigned' => false,
        ],
    ];

    return apply_filters(
        'pepti_dispatch_board_profiles',
        $profiles
    );
}


/* ==========================================================================
   BOARD PROFILE
   ========================================================================== */

function pepti_dispatch_get_board_profile($board_key) {

    $board_key = sanitize_key(
        (string) $board_key
    );

    $profiles =
        pepti_dispatch_board_profiles();

    if (!isset($profiles[$board_key])) {
        return null;
    }

    return $profiles[$board_key];
}


/* ==========================================================================
   VALID WAREHOUSE
   ========================================================================== */

function pepti_dispatch_valid_warehouse($warehouse) {

    $warehouse = sanitize_key(
        (string) $warehouse
    );

    return in_array(
        $warehouse,
        ['hq', 'eu'],
        true
    );
}


/* ==========================================================================
   READ ORDER WAREHOUSE
   ========================================================================== */

/**
 * Returns:
 *
 * 'hq'
 * 'eu'
 * ''
 *
 * Empty string means the order has not been assigned correctly.
 */
function pepti_dispatch_order_warehouse($order_or_id) {

    $order = $order_or_id instanceof WC_Order
        ? $order_or_id
        : wc_get_order(
            absint($order_or_id)
        );

    if (!$order instanceof WC_Order) {
        return '';
    }

    $warehouse = sanitize_key(
        (string) $order->get_meta(
            PEPTI_DISPATCH_META_WAREHOUSE,
            true
        )
    );

    if (!pepti_dispatch_valid_warehouse($warehouse)) {
        return '';
    }

    return $warehouse;
}


/* ==========================================================================
   WAREHOUSE DISPLAY NAME
   ========================================================================== */

function pepti_dispatch_warehouse_name($warehouse) {

    $warehouse = sanitize_key(
        (string) $warehouse
    );

    /**
     * Prefer the Multi-Warehouse Core names so renaming
     * "HQ Warehouse" or "Europe Warehouse" automatically
     * propagates through the dispatch system.
     */
    if (function_exists('pepti_mw_get_warehouses')) {

        $warehouses =
            pepti_mw_get_warehouses();

        if (
            is_array($warehouses)
            && !empty(
                $warehouses[$warehouse]['name']
            )
        ) {
            return sanitize_text_field(
                $warehouses[$warehouse]['name']
            );
        }
    }

    if ($warehouse === 'hq') {
        return 'HQ Warehouse';
    }

    if ($warehouse === 'eu') {
        return 'Europe Warehouse';
    }

    return 'Unassigned';
}


/* ==========================================================================
   COMPLETE ORDER ROUTING INFORMATION
   ========================================================================== */

function pepti_dispatch_order_routing_info(
    $order_or_id
) {

    $order = $order_or_id instanceof WC_Order
        ? $order_or_id
        : wc_get_order(
            absint($order_or_id)
        );

    if (!$order instanceof WC_Order) {
        return [
            'valid'          => false,
            'order_id'       => 0,
            'warehouse'      => '',
            'warehouse_name' => 'Unassigned',
            'country'        => '',
            'fallback'       => false,
            'error'          => '',
        ];
    }

    $warehouse =
        pepti_dispatch_order_warehouse(
            $order
        );

    $saved_name = trim(
        (string) $order->get_meta(
            PEPTI_DISPATCH_META_WAREHOUSE_NAME,
            true
        )
    );

    $country = strtoupper(
        sanitize_text_field(
            (string) $order->get_meta(
                PEPTI_DISPATCH_META_ROUTING_COUNTRY,
                true
            )
        )
    );

    /**
     * Fallback for older orders whose routing-country
     * meta may not have been stored.
     */
    if ($country === '') {

        $country = strtoupper(
            sanitize_text_field(
                (string) (
                    $order->get_shipping_country()
                    ?: $order->get_billing_country()
                )
            )
        );
    }

    $fallback_raw =
        strtolower(
            trim(
                (string) $order->get_meta(
                    PEPTI_DISPATCH_META_FALLBACK,
                    true
                )
            )
        );

    $fallback = in_array(
        $fallback_raw,
        [
            '1',
            'yes',
            'true',
            'on',
        ],
        true
    );

    $error = trim(
        (string) $order->get_meta(
            PEPTI_DISPATCH_META_ERROR,
            true
        )
    );

    return [
        'valid' =>
            pepti_dispatch_valid_warehouse(
                $warehouse
            ),

        'order_id' =>
            (int) $order->get_id(),

        'warehouse' =>
            $warehouse,

        'warehouse_name' =>
            $saved_name !== ''
                ? $saved_name
                : pepti_dispatch_warehouse_name(
                    $warehouse
                ),

        'country' =>
            $country,

        'fallback' =>
            $fallback,

        'error' =>
            $error,
    ];
}


/* ==========================================================================
   CAN A BOARD SEE AN ORDER?
   ========================================================================== */

/**
 * This is the most important function in the bridge.
 *
 * KATE:
 * - Sees HQ
 * - Sees EU
 * - Sees legacy/unassigned orders
 *
 * DARIAN:
 * - Sees HQ only
 *
 * SEÑORITA:
 * - Sees EU only
 */
function pepti_dispatch_board_can_see_order(
    $board_key,
    $order_or_id
) {

    $profile =
        pepti_dispatch_get_board_profile(
            $board_key
        );

    if (!$profile) {
        return false;
    }

    $warehouse =
        pepti_dispatch_order_warehouse(
            $order_or_id
        );

    /*
     * Master Dispatch Darian.
     *
     * Always sees everything.
     */
    if (!empty($profile['master'])) {
        return true;
    }

    /*
     * Warehouse boards MUST NOT receive an
     * unassigned order.
     */
    if ($warehouse === '') {
        return !empty(
            $profile['allow_unassigned']
        );
    }

    return (
        $warehouse
        ===
        sanitize_key(
            $profile['warehouse']
            ?? ''
        )
    );
}


/* ==========================================================================
   BOARD WAREHOUSE
   ========================================================================== */

function pepti_dispatch_board_warehouse(
    $board_key
) {

    $profile =
        pepti_dispatch_get_board_profile(
            $board_key
        );

    if (!$profile) {
        return '';
    }

    return sanitize_key(
        $profile['warehouse']
        ?? ''
    );
}


/* ==========================================================================
   BOARD NAME
   ========================================================================== */

function pepti_dispatch_board_name(
    $board_key,
    $with_icon = true
) {

    $profile =
        pepti_dispatch_get_board_profile(
            $board_key
        );

    if (!$profile) {
        return '';
    }

    $name =
        (string) (
            $profile['name']
            ?? ''
        );

    if (
        $with_icon
        && !empty($profile['icon'])
    ) {
        $name .= ' '
            . $profile['icon'];
    }

    return trim($name);
}


/* ==========================================================================
   BOARD SUBTITLE
   ========================================================================== */

function pepti_dispatch_board_subtitle(
    $board_key
) {

    $profile =
        pepti_dispatch_get_board_profile(
            $board_key
        );

    return $profile
        ? sanitize_text_field(
            $profile['subtitle']
            ?? ''
        )
        : '';
}


/* ==========================================================================
   FILTER ORDER ARRAYS FOR A BOARD
   ========================================================================== */

/**
 * Allows us to pass the exact arrays already loaded by
 * Dispatch Darian through the warehouse filter.
 *
 * This means we do NOT have to rewrite Kate's order-loading
 * system just to split the boards.
 */
function pepti_dispatch_filter_orders_for_board(
    $orders,
    $board_key
) {

    if (!is_array($orders)) {
        return [];
    }

    $filtered = [];

    foreach ($orders as $order) {

        if (!$order instanceof WC_Order) {
            continue;
        }

        if (
            pepti_dispatch_board_can_see_order(
                $board_key,
                $order
            )
        ) {
            $filtered[] = $order;
        }
    }

    return $filtered;
}


/* ==========================================================================
   EMERGENCY / LEGACY ORDER HANDLING
   ========================================================================== */

/**
 * Returns true when the order has no valid fulfilment assignment.
 *
 * These orders remain visible in Dispatch Darian but will NOT appear
 * in Darian or Señorita.
 */
function pepti_dispatch_order_is_unassigned(
    $order_or_id
) {

    return (
        pepti_dispatch_order_warehouse(
            $order_or_id
        ) === ''
    );
}


/* ==========================================================================
   BOARD SAFETY CHECK
   ========================================================================== */

/**
 * Used before dispatch actions in the warehouse-specific
 * boards.
 *
 * Dispatch Darian deliberately bypasses this restriction because
 * she is the emergency/master board.
 */
function pepti_dispatch_authorise_board_order(
    $board_key,
    $order_or_id
) {

    $order = $order_or_id instanceof WC_Order
        ? $order_or_id
        : wc_get_order(
            absint($order_or_id)
        );

    if (!$order instanceof WC_Order) {
        return new WP_Error(
            'dispatch_order_missing',
            'Order could not be loaded.'
        );
    }

    $profile =
        pepti_dispatch_get_board_profile(
            $board_key
        );

    if (!$profile) {
        return new WP_Error(
            'dispatch_board_invalid',
            'Dispatch board is invalid.'
        );
    }

    /*
     * Kate is intentionally unrestricted.
     */
    if (!empty($profile['master'])) {
        return true;
    }

    $warehouse =
        pepti_dispatch_order_warehouse(
            $order
        );

    if ($warehouse === '') {
        return new WP_Error(
            'dispatch_order_unassigned',
            sprintf(
                'Order #%s does not have a valid fulfilment warehouse assignment. Use Dispatch Darian or correct the routing before dispatch.',
                $order->get_order_number()
            )
        );
    }

    $board_warehouse =
        sanitize_key(
            $profile['warehouse']
            ?? ''
        );

    if ($warehouse !== $board_warehouse) {

        return new WP_Error(
            'dispatch_wrong_warehouse',
            sprintf(
                'Order #%s belongs to %s and cannot be dispatched from %s.',
                $order->get_order_number(),
                pepti_dispatch_warehouse_name(
                    $warehouse
                ),
                $profile['name']
            )
        );
    }

    return true;
}


/* ==========================================================================
   OPTIONAL DEBUG INFORMATION
   ========================================================================== */

/**
 * Example:
 *
 * pepti_dispatch_debug_order(12345);
 *
 * Do not output this publicly. It is simply available to us
 * during development/testing.
 */
function pepti_dispatch_debug_order(
    $order_or_id
) {

    $order = $order_or_id instanceof WC_Order
        ? $order_or_id
        : wc_get_order(
            absint($order_or_id)
        );

    if (!$order instanceof WC_Order) {
        return [
            'exists' => false,
        ];
    }

    $routing =
        pepti_dispatch_order_routing_info(
            $order
        );

    return [
        'exists' =>
            true,

        'order_id' =>
            $order->get_id(),

        'order_number' =>
            $order->get_order_number(),

        'status' =>
            $order->get_status(),

        'routing' =>
            $routing,

        'boards' => [
            'kate' =>
                pepti_dispatch_board_can_see_order(
                    'kate',
                    $order
                ),

            'darian' =>
                pepti_dispatch_board_can_see_order(
                    'darian',
                    $order
                ),

            'senorita' =>
                pepti_dispatch_board_can_see_order(
                    'senorita',
                    $order
                ),
        ],
    ];
}