<?php
/**
 * ZERTI — central in-app route registry and URL builders.
 */

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

/**
 * Canonical route definitions (tabs, sub-views, query param names).
 *
 * @return array{
 *   params: array{tab:string,inv:string,fin:string,order:string,shop_view:string,customer:string,product:string},
 *   tabs: list<array{slug:string,icon:string,label:string}>,
 *   inventory: array{default:string,subs:list<array{slug:string,icon:string,label:string}>},
 *   financial: array{default:string,subs:list<array{slug:string,icon:string,label:string}>},
 *   customer_relations: array{subs:list<array{slug:string,icon:string,label:string,tab?:string}>},
 *   shop_views: list<string>,
 *   shop_view_default: string
 * }
 */
function zerti_routes(): array
{
    static $cache = null;
    if ($cache !== null) {
        return $cache;
    }

    $cache = [
        'params' => [
            'tab' => 'zerti_tab',
            'inv' => 'zerti_inv',
            'fin' => 'zerti_fin',
            'order' => 'zerti_order',
            'shop_view' => 'zerti_shop_view',
            'shop_status' => 'zerti_shop_status',
            'customer' => 'zerti_customer',
            'product' => 'zerti_product',
            'products_stock' => 'zerti_products_stock',
            'payments_scope' => 'zerti_payments_scope',
            'sales_scope' => 'zerti_sales_scope',
        ],
        'tabs' => [
            ['slug' => 'home', 'icon' => 'fa-house', 'label' => __('Home', 'zerti'), 'cap' => 'view_woocommerce_reports'],
            ['slug' => 'shop', 'icon' => 'fa-store', 'label' => __('Orders', 'zerti'), 'cap' => 'edit_shop_orders'],
            ['slug' => 'inventory', 'icon' => 'fa-boxes-stacked', 'label' => __('Inventory', 'zerti'), 'cap' => 'edit_products'],
            ['slug' => 'financial', 'icon' => 'fa-coins', 'label' => __('Finance', 'zerti'), 'cap' => 'view_woocommerce_reports'],
            [
                'slug' => 'reports',
                'icon' => 'fa-chart-bar',
                'label' => __('Reports', 'zerti'),
                'cap' => 'view_woocommerce_reports',
                'nav_group' => true,
            ],
            [
                'slug' => 'customer_relations',
                'icon' => 'fa-handshake',
                'label' => __('Customer affairs', 'zerti'),
                'cap' => 'list_users',
                'nav_group' => true,
            ],
            ['slug' => 'settings', 'icon' => 'fa-gear', 'label' => __('Settings', 'zerti'), 'cap' => 'manage_options'],
        ],
        'customer_relations' => [
            'subs' => [
                [
                    'slug' => 'customers',
                    'icon' => 'fa-users',
                    'label' => __('Customers', 'zerti'),
                    'tab' => 'customers',
                    'cap' => 'list_users',
                ],
                [
                    'slug' => 'reviews',
                    'icon' => 'fa-star',
                    'label' => __('Reviews', 'zerti'),
                    'tab' => 'reviews',
                    'cap' => 'moderate_comments',
                ],
                [
                    'slug' => 'comments',
                    'icon' => 'fa-comments',
                    'label' => __('Comments', 'zerti'),
                    'tab' => 'comments',
                    'cap' => 'moderate_comments',
                ],
            ],
        ],
        'inventory' => [
            'default' => 'warehouse',
            'subs' => [
                ['slug' => 'warehouse', 'icon' => 'fa-warehouse', 'label' => __('Products', 'zerti')],
                [
                    'slug' => 'product-new',
                    'icon' => 'fa-plus',
                    'label' => __('New product', 'zerti'),
                    'nav_only' => true,
                    'product' => 0,
                ],
                ['slug' => 'categories', 'icon' => 'fa-folder-tree', 'label' => __('Categories', 'zerti')],
                ['slug' => 'brands', 'icon' => 'fa-certificate', 'label' => __('Brands', 'zerti')],
                ['slug' => 'tags', 'icon' => 'fa-tag', 'label' => __('Tags', 'zerti')],
                ['slug' => 'attributes', 'icon' => 'fa-tags', 'label' => __('Attributes', 'zerti')],
                [
                    'slug' => 'attribute-groups',
                    'icon' => 'fa-layer-group',
                    'label' => __('Attribute groups', 'zerti'),
                ],
                ['slug' => 'import-export', 'icon' => 'fa-arrow-right-arrow-left', 'label' => __('Import/export', 'zerti')],
            ],
        ],
        'financial' => [
            'default' => 'payments',
            'subs' => [
                ['slug' => 'payments', 'icon' => 'fa-credit-card', 'label' => __('Payments', 'zerti')],
                ['slug' => 'coupons', 'icon' => 'fa-ticket', 'label' => __('Coupons', 'zerti')],
            ],
        ],
        'reports' => [
            'default' => 'sales-report',
            'subs' => [
                ['slug' => 'sales-report', 'icon' => 'fa-chart-column', 'label' => __('Sales report', 'zerti')],
            ],
        ],
        'shop_views' => ['detail', 'invoice'],
        'shop_view_default' => 'detail',
    ];

    /**
     * @param array{
     *   params: array<string,string>,
     *   tabs: list<array{slug:string,icon:string,label:string}>,
     *   inventory: array{default:string,subs:list<array{slug:string,icon:string,label:string}>},
     *   financial: array{default:string,subs:list<array{slug:string,icon:string,label:string}>},
     *   shop_views: list<string>,
     *   shop_view_default: string
     * } $routes
     */
    $cache = apply_filters('zerti_routes', $cache);

    return $cache;
}

/**
 * Report sidebar items (routed via Finance ?zerti_fin=).
 *
 * @return list<array{slug:string,icon?:string,label?:string,pro_only?:bool}>
 */
function zerti_report_subs(): array
{
    return (array) (zerti_routes()['reports']['subs'] ?? []);
}

/**
 * Financial sidebar leaf items (routable subs, including report pages).
 *
 * @return list<array{slug:string,icon?:string,label?:string,pro_only?:bool}>
 */
function zerti_financial_leaf_subs(): array
{
    $leaves = [];
    foreach (zerti_routes()['financial']['subs'] as $item) {
        $slug = (string) ($item['slug'] ?? '');
        if ($slug !== '') {
            $leaves[] = $item;
        }
    }
    foreach (zerti_report_subs() as $item) {
        $leaves[] = $item;
    }

    return $leaves;
}

/**
 * Slugs opened from the root «Reports» nav group.
 *
 * @return list<string>
 */
function zerti_financial_report_sub_slugs(): array
{
    $slugs = [];
    foreach (zerti_report_subs() as $sub) {
        $slug = (string) ($sub['slug'] ?? '');
        if ($slug !== '') {
            $slugs[] = $slug;
        }
    }

    return $slugs;
}

/**
 * Whether a Finance sub-view is a report page.
 */
function zerti_is_financial_report_sub(string $sub): bool
{
    return in_array($sub, zerti_financial_report_sub_slugs(), true);
}

/**
 * Whether the root Reports nav group should appear active.
 */
function zerti_is_reports_nav_active(string $current_tab, string $fin_sub): bool
{
    return $current_tab === 'financial' && zerti_is_financial_report_sub($fin_sub);
}

/**
 * Inventory subs that load a component (excludes nav-only sidebar links such as «محصول جدید»).
 *
 * @return list<string>
 */
function zerti_inventory_component_sub_slugs(): array
{
    $slugs = [];
    foreach (zerti_routes()['inventory']['subs'] as $item) {
        if (!empty($item['nav_only'])) {
            continue;
        }
        $slug = (string) ($item['slug'] ?? '');
        if ($slug !== '') {
            $slugs[] = $slug;
        }
    }

    return $slugs;
}

/**
 * Sidebar labels keyed by slug (tabs, inventory subs, financial subs).
 *
 * @return array{tabLabels: array<string, string>, inventoryLabels: array<string, string>, financialLabels: array<string, string>}
 */
function zerti_routes_nav_label_maps(): array
{
    $routes = zerti_routes();
    $tab_labels = [];
    foreach ($routes['tabs'] as $tab) {
        $slug = (string) ($tab['slug'] ?? '');
        if ($slug !== '') {
            $tab_labels[$slug] = (string) ($tab['label'] ?? '');
        }
    }
    $inventory_labels = [];
    foreach ($routes['inventory']['subs'] as $sub) {
        $slug = (string) ($sub['slug'] ?? '');
        if ($slug !== '') {
            $inventory_labels[$slug] = (string) ($sub['label'] ?? '');
        }
    }
    $financial_labels = [];
    foreach (zerti_financial_leaf_subs() as $sub) {
        $slug = (string) ($sub['slug'] ?? '');
        if ($slug !== '') {
            $financial_labels[$slug] = (string) ($sub['label'] ?? '');
        }
    }
    foreach ($routes['customer_relations']['subs'] as $sub) {
        $panel = (string) ($sub['tab'] ?? $sub['slug'] ?? '');
        if ($panel !== '') {
            $tab_labels[$panel] = (string) ($sub['label'] ?? '');
        }
    }

    return [
        'tabLabels' => $tab_labels,
        'inventoryLabels' => $inventory_labels,
        'financialLabels' => $financial_labels,
    ];
}

/**
 * Sidebar label for a top-level admin tab slug.
 */
function zerti_tab_nav_label(string $slug): string
{
    $maps = zerti_routes_nav_label_maps();

    return (string) ($maps['tabLabels'][$slug] ?? '');
}

/**
 * Panel tab slugs nested under «امور مشتریان».
 *
 * @return list<string>
 */
function zerti_customer_relations_panel_tab_slugs(): array
{
    $slugs = [];
    foreach (zerti_routes()['customer_relations']['subs'] as $sub) {
        $panel = (string) ($sub['tab'] ?? $sub['slug'] ?? '');
        if ($panel !== '') {
            $slugs[] = $panel;
        }
    }

    return $slugs;
}

/**
 * All content panel tab slugs from the route registry (not filtered by user caps).
 * Used when building shareable admin URLs (e.g. customer / product detail links).
 *
 * @return list<string>
 */
function zerti_registered_panel_tab_slugs(): array
{
    $routes = zerti_routes();
    $slugs = [];
    $seen = [];

    foreach ($routes['tabs'] as $tab) {
        $slug = (string) ($tab['slug'] ?? '');
        if ($slug === '' || !empty($tab['nav_group'])) {
            continue;
        }
        if (!isset($seen[$slug])) {
            $slugs[] = $slug;
            $seen[$slug] = true;
        }
    }

    foreach ($routes['customer_relations']['subs'] as $sub) {
        $panel_slug = (string) ($sub['tab'] ?? $sub['slug'] ?? '');
        if ($panel_slug === '' || isset($seen[$panel_slug])) {
            continue;
        }
        $slugs[] = $panel_slug;
        $seen[$panel_slug] = true;
    }

    return $slugs;
}

/**
 * Whether $tab is a panel opened from the customer-relations nav group.
 */
function zerti_is_customer_relations_panel_tab(string $tab): bool
{
    return in_array($tab, zerti_customer_relations_panel_tab_slugs(), true);
}

/**
 * Human-readable title for the active sidebar item (panel heading).
 *
 * @param array<string, mixed>|null $route Normalized route; defaults to current request.
 */
function zerti_panel_nav_title(?array $route = null): string
{
    $route = $route ?? zerti_route_from_request();
    $tab = (string) ($route['tab'] ?? 'home');
    $maps = zerti_routes_nav_label_maps();

    if ($tab === 'inventory') {
        $inv = (string) ($route['inv'] ?? zerti_routes()['inventory']['default']);
        if ($inv === 'warehouse' && isset($route['product'])) {
            $product_id = (int) $route['product'];
            if ($product_id === 0) {
                return $maps['inventoryLabels']['product-new'] ?? __('New product', 'zerti');
            }
        }
        if (isset($maps['inventoryLabels'][$inv]) && $maps['inventoryLabels'][$inv] !== '') {
            return $maps['inventoryLabels'][$inv];
        }
    }

    if ($tab === 'financial') {
        $fin = (string) ($route['fin'] ?? zerti_routes()['financial']['default']);
        if (isset($maps['financialLabels'][$fin]) && $maps['financialLabels'][$fin] !== '') {
            return $maps['financialLabels'][$fin];
        }
    }

    if ($tab === 'shop' && isset($route['order']) && (int) $route['order'] === 0) {
        return __('New order', 'zerti');
    }

    return $maps['tabLabels'][$tab] ?? '';
}

/**
 * Route config exposed to admin JavaScript (mirrors zerti_admin_route_url).
 *
 * @return array<string, mixed>
 */
function zerti_routes_client_config(): array
{
    $routes = zerti_routes();

    $tab_caps = [];
    foreach ($routes['tabs'] as $tab) {
        $slug = (string) ($tab['slug'] ?? '');
        if ($slug !== '') {
            $tab_caps[$slug] = zerti_tab_capability($slug);
        }
    }

    $label_maps = zerti_routes_nav_label_maps();

    return [
        'params' => $routes['params'],
        'tabs' => function_exists('zerti_admin_route_tab_slugs') ? zerti_admin_route_tab_slugs() : array_column($routes['tabs'], 'slug'),
        'navTabs' => array_column($routes['tabs'], 'slug'),
        'tabCaps' => $tab_caps,
        'tabLabels' => $label_maps['tabLabels'],
        'inventoryLabels' => $label_maps['inventoryLabels'],
        'financialLabels' => $label_maps['financialLabels'],
        'inventory' => [
            'default' => $routes['inventory']['default'],
            'subs' => zerti_inventory_component_sub_slugs(),
        ],
        'financial' => [
            'default' => $routes['financial']['default'],
            'subs' => array_column($routes['financial']['subs'], 'slug'),
        ],
        'reports' => [
            'default' => $routes['reports']['default'],
            'subs' => zerti_financial_report_sub_slugs(),
        ],
        'customerRelations' => [
            'tabs' => zerti_customer_relations_panel_tab_slugs(),
        ],
        'shopViews' => $routes['shop_views'],
        'shopViewDefault' => $routes['shop_view_default'],
        'shopStatusSlugs' => array_keys(function_exists('zerti_wc_order_status_choices') ? zerti_wc_order_status_choices() : []),
        'shopOrderCreateLabel' => __('New order', 'zerti'),
        'paymentsScopeSlugs' => function_exists('zerti_payments_scope_slugs') ? zerti_payments_scope_slugs() : ['today_success', 'period_success'],
        'salesScopeSlugs' => function_exists('zerti_sales_report_scope_slugs') ? zerti_sales_report_scope_slugs() : ['period'],
    ];
}

/**
 * @param string $slug WooCommerce order status slug (without wc- prefix).
 */
function zerti_is_valid_shop_status_slug(string $slug): bool
{
    $slug = sanitize_key($slug);

    return $slug !== '' && isset(zerti_wc_order_status_choices()[$slug]);
}

/**
 * Parse the current (or given) request into a normalized route array.
 *
 * @param array<string, mixed>|null $query Defaults to $_GET.
 * @return array{
 *   tab:string,
 *   inv?:string,
 *   fin?:string,
 *   order?:int,
 *   shop_view?:string,
 *   shop_status?:string,
 *   customer?:int,
 *   product?:int
 * }
 */
function zerti_route_from_request(?array $query = null): array
{
    $routes = zerti_routes();
    $p = $routes['params'];
    $query = $query ?? wp_unslash($_GET); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- admin URL routing only.
    if (!is_array($query)) {
        $query = [];
    }

    $allowed = zerti_admin_route_tab_slugs();
    $tab = zerti_default_accessible_tab();
    if (!empty($query[$p['tab']])) {
        $candidate = sanitize_key((string) $query[$p['tab']]);
        if (in_array($candidate, $allowed, true)) {
            $tab = $candidate;
        }
    }
    if ($allowed !== [] && !in_array($tab, $allowed, true)) {
        $tab = zerti_default_accessible_tab();
    }

    if (
        $tab === 'inventory'
        && !empty($query[$p['inv']])
        && sanitize_key((string) $query[$p['inv']]) === 'comments'
    ) {
        if (in_array('reviews', $allowed, true)) {
            $tab = 'reviews';
        } elseif (in_array('comments', $allowed, true)) {
            $tab = 'comments';
        }
    }

    $route = ['tab' => $tab];

    if ($tab === 'inventory') {
        $inv = '';
        if (!empty($query[$p['inv']])) {
            $inv = sanitize_key((string) $query[$p['inv']]);
        }
        $route['inv'] = zerti_is_valid_inventory_sub($inv) ? $inv : $routes['inventory']['default'];
        if (
            $route['inv'] === 'warehouse'
            && !empty($query[$p['products_stock']])
            && function_exists('zerti_is_valid_products_stock_filter')
            && zerti_is_valid_products_stock_filter(sanitize_key((string) $query[$p['products_stock']]))
        ) {
            $route['products_stock'] = sanitize_key((string) $query[$p['products_stock']]);
        }
        if ($route['inv'] === 'warehouse' && isset($query[$p['product']])) {
            $product_raw = wp_unslash((string) $query[$p['product']]);
            if ($product_raw === '' || $product_raw === 'new') {
                $route['product'] = 0;
            } else {
                $route['product'] = absint($product_raw);
            }
        }
    }

    if ($tab === 'financial') {
        $fin = '';
        if (!empty($query[$p['fin']])) {
            $fin = sanitize_key((string) $query[$p['fin']]);
        }
        $route['fin'] = zerti_is_valid_financial_sub($fin) ? $fin : $routes['financial']['default'];
        if (
            $route['fin'] === 'payments'
            && !empty($query[$p['payments_scope']])
            && function_exists('zerti_is_valid_payments_scope')
            && zerti_is_valid_payments_scope(sanitize_key((string) $query[$p['payments_scope']]))
        ) {
            $route['payments_scope'] = sanitize_key((string) $query[$p['payments_scope']]);
        }
        if (
            $route['fin'] === 'sales-report'
            && !empty($query[$p['sales_scope']])
            && function_exists('zerti_is_valid_sales_report_scope')
            && zerti_is_valid_sales_report_scope(sanitize_key((string) $query[$p['sales_scope']]))
        ) {
            $route['sales_scope'] = sanitize_key((string) $query[$p['sales_scope']]);
        }
    }

    if ($tab === 'shop') {
        if (!empty($query[$p['shop_status']])) {
            $status = sanitize_key((string) $query[$p['shop_status']]);
            if (zerti_is_valid_shop_status_slug($status)) {
                $route['shop_status'] = $status;
            }
        }
        if (array_key_exists($p['order'], $query) && $query[$p['order']] !== '') {
            $order_id = absint((string) $query[$p['order']]);
            if ($order_id === 0 && function_exists('zerti_user_can_create_shop_order') && zerti_user_can_create_shop_order()) {
                $route['order'] = 0;
            } elseif ($order_id > 0) {
                $route['order'] = $order_id;
                $view = !empty($query[$p['shop_view']]) ? sanitize_key((string) $query[$p['shop_view']]) : '';
                $route['shop_view'] = in_array($view, $routes['shop_views'], true) ? $view : $routes['shop_view_default'];
            }
        }
    }

    if ($tab === 'customers' && !empty($query[$p['customer']])) {
        $customer_id = absint((string) $query[$p['customer']]);
        if ($customer_id > 0) {
            $route['customer'] = $customer_id;
        }
    }

    return $route;
}

/**
 * Build an admin URL for a normalized route.
 *
 * @param array{
 *   tab?:string,
 *   inv?:string,
 *   fin?:string,
 *   order?:int,
 *   shop_view?:string,
 *   shop_status?:string,
 *   customer?:int,
 *   product?:int,
 *   products_stock?:string,
 *   payments_scope?:string
 * } $route
 */
function zerti_admin_route_url(array $route = []): string
{
    $routes = zerti_routes();
    $p = $routes['params'];
    $args = [];

    $tab = isset($route['tab']) ? sanitize_key((string) $route['tab']) : 'home';
    if ($tab !== 'home' && in_array($tab, zerti_registered_panel_tab_slugs(), true)) {
        $args[$p['tab']] = $tab;
    }

    if ($tab === 'inventory') {
        $inv = isset($route['inv']) ? sanitize_key((string) $route['inv']) : $routes['inventory']['default'];
        if (zerti_is_valid_inventory_sub($inv) && $inv !== $routes['inventory']['default']) {
            $args[$p['inv']] = $inv;
        }
        if (
            $inv === 'warehouse'
            && !empty($route['products_stock'])
            && function_exists('zerti_is_valid_products_stock_filter')
            && zerti_is_valid_products_stock_filter(sanitize_key((string) $route['products_stock']))
        ) {
            $args[$p['products_stock']] = sanitize_key((string) $route['products_stock']);
        }
        if ($inv === 'warehouse' && array_key_exists('product', $route)) {
            $args[$p['product']] = (string) absint((string) $route['product']);
        }
    }

    if ($tab === 'financial') {
        $fin = isset($route['fin']) ? sanitize_key((string) $route['fin']) : $routes['financial']['default'];
        if (zerti_is_valid_financial_sub($fin) && $fin !== $routes['financial']['default']) {
            $args[$p['fin']] = $fin;
        }
        if (
            $fin === 'payments'
            && !empty($route['payments_scope'])
            && function_exists('zerti_is_valid_payments_scope')
            && zerti_is_valid_payments_scope(sanitize_key((string) $route['payments_scope']))
        ) {
            $args[$p['payments_scope']] = sanitize_key((string) $route['payments_scope']);
        }
        if (
            $fin === 'sales-report'
            && !empty($route['sales_scope'])
            && function_exists('zerti_is_valid_sales_report_scope')
            && zerti_is_valid_sales_report_scope(sanitize_key((string) $route['sales_scope']))
        ) {
            $args[$p['sales_scope']] = sanitize_key((string) $route['sales_scope']);
        }
    }

    if ($tab === 'shop') {
        if (!empty($route['shop_status'])) {
            $status = sanitize_key((string) $route['shop_status']);
            if (zerti_is_valid_shop_status_slug($status)) {
                $args[$p['shop_status']] = $status;
            }
        }
        if (array_key_exists('order', $route)) {
            $order_id = absint((string) $route['order']);
            if ($order_id === 0 && function_exists('zerti_user_can_create_shop_order') && zerti_user_can_create_shop_order()) {
                $args[$p['order']] = '0';
            } elseif ($order_id > 0) {
                $args[$p['order']] = (string) $order_id;
                $view = isset($route['shop_view']) ? sanitize_key((string) $route['shop_view']) : $routes['shop_view_default'];
                if ($view === 'invoice') {
                    $args[$p['shop_view']] = 'invoice';
                }
            }
        }
    }

    if ($tab === 'customers' && !empty($route['customer'])) {
        $customer_id = absint((string) $route['customer']);
        if ($customer_id > 0) {
            $args[$p['customer']] = (string) $customer_id;
        }
    }

    return add_query_arg($args, zerti_admin_base_url());
}

/**
 * Shop orders list URL preserving list filters from the current request (for detail back links).
 */
function zerti_admin_shop_list_return_url(): string
{
    $routes = zerti_routes();
    $p = $routes['params'];
    $route = ['tab' => 'shop'];
    if (!empty($_GET[$p['shop_status']])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- preserve list filter in back link URL.
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- preserve list filter in back link URL.
        $status = sanitize_key((string) wp_unslash($_GET[$p['shop_status']]));
        if (zerti_is_valid_shop_status_slug($status)) {
            $route['shop_status'] = $status;
        }
    }

    return zerti_admin_route_url($route);
}

/**
 * Inventory warehouse list URL preserving stock filter from the current request.
 */
function zerti_admin_inventory_warehouse_list_return_url(): string
{
    $routes = zerti_routes();
    $p = $routes['params'];
    $route = ['tab' => 'inventory', 'inv' => 'warehouse'];
    if (
        !empty($_GET[$p['products_stock']]) // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- preserve stock filter in back link URL.
        && function_exists('zerti_is_valid_products_stock_filter')
        && zerti_is_valid_products_stock_filter(sanitize_key((string) wp_unslash($_GET[$p['products_stock']]))) // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- preserve stock filter in back link URL.
    ) {
        $route['products_stock'] = sanitize_key((string) wp_unslash($_GET[$p['products_stock']])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- preserve stock filter in back link URL.
    }

    return zerti_admin_route_url($route);
}

/**
 * Shop order detail link for AG Grid / templates.
 */
function zerti_shop_order_detail_link_html(int $order_id, string $label = ''): string
{
    if ($order_id < 1) {
        return '';
    }
    if ($label === '') {
        $label = __('Details', 'zerti');
    }
    $url = zerti_admin_route_url([
        'tab' => 'shop',
        'order' => $order_id,
    ]);

    return sprintf(
        '<a href="%1$s" class="btn btn-sm btn-outline-secondary d-inline-flex align-items-center zerti-shop-order-detail-btn" data-zerti-shop-order="%2$s">%3$s</a>',
        esc_url($url),
        esc_attr((string) $order_id),
        esc_html($label)
    );
}

/**
 * Base URL for the ZERTI admin screen (no tab query).
 */
function zerti_admin_base_url(): string
{
    return admin_url('admin.php?page=' . ZERTI_ADMIN_PAGE_SLUG);
}

/**
 * In-app product editor link for AG Grid / templates.
 */
function zerti_product_detail_link_html(int $product_id, string $label = ''): string
{
    if ($product_id < 1) {
        return '';
    }
    if ($label === '') {
        $label = __('Details', 'zerti');
    }
    $url = zerti_admin_route_url([
        'tab' => 'inventory',
        'inv' => 'warehouse',
        'product' => $product_id,
    ]);

    return sprintf(
        '<a href="%1$s" class="btn btn-sm btn-outline-secondary d-inline-flex align-items-center zerti-product-detail-btn" data-zerti-product="%2$s">%3$s</a>',
        esc_url($url),
        esc_attr((string) $product_id),
        esc_html($label)
    );
}

/**
 * Customer detail link for AG Grid / templates.
 */
function zerti_customer_detail_link_html(int $user_id, string $label = ''): string
{
    if ($user_id < 1) {
        return '';
    }
    if ($label === '') {
        $label = __('Details', 'zerti');
    }
    $url = zerti_admin_route_url([
        'tab' => 'customers',
        'customer' => $user_id,
    ]);

    return sprintf(
        '<a href="%1$s" class="btn btn-sm btn-outline-secondary d-inline-flex align-items-center zerti-customer-detail-btn" data-zerti-customer="%2$s">%3$s</a>',
        esc_url($url),
        esc_attr((string) $user_id),
        esc_html($label)
    );
}
