<?php

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

class AIEO_DMM {

    const MENU_SLUG        = 'ai-eshop-dmm';
    const NONCE_ACTION     = 'aieo_dmm_nonce';
    
    const LANDING_USER_META = 'aieo_dmm_landing_tab';
    const OPTION_VERSION   = 'aieo_dmm_version';
    const ASSETS_HANDLE    = 'aieo-dmm';

    
    private static $instance = null;

    
    private $modules = array();

    
    private $subtabs = array();

    
    public static function instance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {
        $this->load_core();
        $this->load_modules();

        add_action('admin_menu', array($this, 'register_menu'), 20);
        
        
        
        add_action('admin_menu', array($this, 'reorder_admin_submenu'), 999);
        add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_assets'));
        add_action('wp_ajax_aieo_dmm_save_recipe', array($this, 'ajax_save_recipe'));
        add_action('wp_ajax_aieo_dmm_save_enabled_modules', array($this, 'ajax_save_enabled_modules'));
        add_action('wp_ajax_aieo_dmm_delete_export_job', array($this, 'ajax_delete_export_job'));

        
        
        add_action('in_admin_header', array($this, 'suppress_third_party_notices'), 1);
        add_action('admin_print_styles', array($this, 'suppress_third_party_notices'), 1);

        
        foreach ($this->modules as $module) {
            $module->register_hooks();
        }
    }

    
    private function load_core() {
        $base = AIEO_DIR . 'includes/dmm/';

        
        
        if ( file_exists( AIEO_DIR . 'includes/class-aieo-admin-color.php' ) ) {
            require_once AIEO_DIR . 'includes/class-aieo-admin-color.php';
        }
        require_once $base . 'class-aieo-dmm-settings.php';
        require_once $base . 'class-aieo-dmm-cache.php';
        require_once $base . 'class-aieo-dmm-product-fp.php';
        require_once $base . 'class-aieo-dmm-user-fp.php';
        
        
        
        require_once $base . 'class-aieo-identity-bridge.php';
        
        
        
        
        require_once $base . 'class-aieo-recompute-queue.php';
        require_once $base . 'class-aieo-dmm-effective-prices.php';
        require_once $base . 'class-aieo-dmm-effective-recos.php';
        require_once $base . 'class-aieo-dmm-effective-eligibility.php';
        require_once $base . 'class-aieo-dmm-badge-renderer.php';
        
        
        
        require_once $base . 'class-aieo-module-manifest.php';
        
        
        $v2_base = AIEO_DIR . 'includes/dmm/modules/_v2/class-aieo-module-v2-base.php';
        if (file_exists($v2_base)) { require_once $v2_base; }
        
        
        $blocks_loader = AIEO_DIR . 'includes/dmm/blocks/class-aieo-blocks-loader.php';
        if (file_exists($blocks_loader)) { require_once $blocks_loader; }
        
        
        $patterns_class = AIEO_DIR . 'includes/dmm/blocks/class-aieo-block-patterns.php';
        if (file_exists($patterns_class)) { require_once $patterns_class; }
        
        
        $brand_page_installer = AIEO_DIR . 'includes/dmm/class-aieo-brand-page-installer.php';
        if (file_exists($brand_page_installer)) { require_once $brand_page_installer; }
        
        
        
        
        $block_fields = AIEO_DIR . 'includes/dmm/modules/checkout-block-fields/class-aieo-checkout-block-fields.php';
        if (file_exists($block_fields)) { require_once $block_fields; }
        
        
        
        $blocks_bridge = AIEO_DIR . 'includes/dmm/modules/checkout-block-fields/class-aieo-third-party-blocks-bridge.php';
        if (file_exists($blocks_bridge)) { require_once $blocks_bridge; }
        require_once $base . 'class-aieo-dmm-pricing-engine.php';
        require_once $base . 'class-aieo-dmm-pricing-rest.php';
        require_once $base . 'class-aieo-dmm-main-price-filter.php';
        require_once $base . 'class-aieo-dmm-role-price-filter.php';
        require_once $base . 'class-aieo-dmm-sample.php';
        require_once $base . 'modules/class-aieo-dmm-module-base.php';

        
        
        
        
        
        
        
        
        foreach (array(
            'class-aieo-dmm-brand-extras-data.php',
            'class-aieo-dmm-need-extras-data.php',
            'class-aieo-dmm-supplier-extras-data.php',
            'class-aieo-dmm-cancellation-reasons-data.php',
        ) as $data_file) {
            $path = $base . $data_file;
            if (file_exists($path)) { require_once $path; }
        }

        
        
        
        
        
        require_once $base . 'services/class-aieo-dmm-offer-matcher.php';
        
        
        
        
        require_once $base . 'services/class-aieo-dmm-offer-attributor.php';
        require_once $base . 'services/class-aieo-dmm-shipping-cost-resolver.php';
        require_once $base . 'services/class-aieo-dmm-xlsx-writer.php';
        
        
        
        
        require_once $base . 'services/class-aieo-dmm-product-picker.php';
        AIEO_DMM_Product_Picker::register_ajax();
        AIEO_DMM_Offer_Attributor::instance();
        AIEO_DMM_Shipping_Cost_Resolver::instance();

        
        
        
        AIEO_DMM_Pricing_REST::instance();

        
        AIEO_DMM_Main_Price_Filter::instance()->maybe_register();

        
        
        
        AIEO_DMM_Role_Price_Filter::instance()->maybe_register();

        
        
        add_action('save_post_product',            array('AIEO_DMM_Product_FP', 'on_product_save'), 20, 1);
        add_action('woocommerce_update_product',   array('AIEO_DMM_Product_FP', 'on_product_save'), 20, 1);
        add_action('profile_update',               array('AIEO_DMM_User_FP',    'on_user_change'), 20, 1);
        add_action('set_user_role',                array('AIEO_DMM_User_FP',    'on_user_change'), 20, 1);
        add_action('add_user_role',                array('AIEO_DMM_User_FP',    'on_user_change'), 20, 1);
        add_action('remove_user_role',             array('AIEO_DMM_User_FP',    'on_user_change'), 20, 1);

        
        
        
        
        
        if (class_exists('AIEO_Identity_Bridge'))          { AIEO_Identity_Bridge::bootstrap(); }
        
        
        
        if (class_exists('AIEO_Recompute_Queue'))          { AIEO_Recompute_Queue::bootstrap(); }
        if (class_exists('AIEO_Effective_Prices'))         { AIEO_Effective_Prices::bootstrap(); }
        if (class_exists('AIEO_Effective_Recos'))          { AIEO_Effective_Recos::bootstrap(); }
        if (class_exists('AIEO_Effective_Eligibility'))    { AIEO_Effective_Eligibility::bootstrap(); }
        if (class_exists('AIEO_DMM_Badge_Renderer'))       { AIEO_DMM_Badge_Renderer::bootstrap(); }
        
        
        if (class_exists('AIEO_Module_V2_Loader'))         { AIEO_Module_V2_Loader::boot_all(); }
        
        
        if (class_exists('AIEO_Blocks_Loader'))            { AIEO_Blocks_Loader::bootstrap(); }
        
        
        if (class_exists('AIEO_Block_Patterns'))           { AIEO_Block_Patterns::bootstrap(); }
        
        
        if (class_exists('AIEO_Brand_Page_Installer'))     { AIEO_Brand_Page_Installer::bootstrap(); }
        
        if (class_exists('AIEO_Checkout_Block_Fields'))    { AIEO_Checkout_Block_Fields::bootstrap(); }
        if (class_exists('AIEO_Third_Party_Blocks_Bridge')) { AIEO_Third_Party_Blocks_Bridge::bootstrap(); }
        
        
        
        
        
        if (!class_exists('AIEO_Greek_Nomi')) {
            $aieo_nomi_path = AIEO_DIR . 'includes/dmm/modules/address-autocomplete/class-aieo-greek-nomi.php';
            if (file_exists($aieo_nomi_path)) { require_once $aieo_nomi_path; }
        }
        if (class_exists('AIEO_Greek_Nomi'))               { AIEO_Greek_Nomi::register(); }

        
        
        
        
        
        
        
        
        
        
        
        
        
        if (!class_exists('AIEO_Address_Provider_Google') && class_exists('WC_Address_Provider')) {
            $aieo_addr_path = AIEO_DIR . 'includes/dmm/modules/address-autocomplete/class-aieo-address-provider-google.php';
            if (file_exists($aieo_addr_path)) { require_once $aieo_addr_path; }
        }
        if (class_exists('AIEO_Address_Provider_Google'))  { AIEO_Address_Provider_Google::register(); }
        if (class_exists('AIEO_DMM_Term_Relations'))       { AIEO_DMM_Term_Relations::bootstrap(); }
        if (class_exists('AIEO_DMM_Brand_Extras_Data'))    { AIEO_DMM_Brand_Extras_Data::bootstrap(); }
        if (class_exists('AIEO_DMM_Need_Extras_Data'))     { AIEO_DMM_Need_Extras_Data::bootstrap(); }
        if (class_exists('AIEO_DMM_Supplier_Extras_Data')) { AIEO_DMM_Supplier_Extras_Data::bootstrap(); }
        if (class_exists('AIEO_DMM_Related_Tab'))          { AIEO_DMM_Related_Tab::register(); }
        
        
        
        
        
        $post_relations_metabox = AIEO_DIR . 'includes/dmm/class-aieo-dmm-post-relations-metabox.php';
        if (is_admin() && file_exists($post_relations_metabox)) {
            require_once $post_relations_metabox;
            if (class_exists('AIEO_DMM_Post_Relations_Metabox')) {
                AIEO_DMM_Post_Relations_Metabox::register();
            }
        }
        
        
        
        
        foreach (array(
            'class-aieo-dmm-cancellation-reasons-data.php',
            'class-aieo-dmm-order-cancellations.php',
            'class-aieo-dmm-product-behavior-metrics.php',
            'class-aieo-dmm-user-behavior-metrics.php',
            'class-aieo-dmm-campaigns.php',
            'class-aieo-dmm-reco-penalty.php',
            'class-aieo-dmm-risk-gating.php',
            
            
            
            'class-aieo-dmm-cod-country-block.php',
            
            
            'modules/class-aieo-dmm-payment-gating.php',
            
            
            
            
            'class-aieo-dmm-payment-country-block.php',
        ) as $f) {
            $p = $base . $f;
            if (file_exists($p)) { require_once $p; }
        }

        if (class_exists('AIEO_DMM_Order_Cancellations'))      { AIEO_DMM_Order_Cancellations::bootstrap(); }
        if (class_exists('AIEO_DMM_Product_Behavior_Metrics')) { AIEO_DMM_Product_Behavior_Metrics::bootstrap(); }
        if (class_exists('AIEO_DMM_User_Behavior_Metrics'))    { AIEO_DMM_User_Behavior_Metrics::bootstrap(); }
        if (class_exists('AIEO_DMM_Reco_Penalty'))             { AIEO_DMM_Reco_Penalty::bootstrap(); }
        if (class_exists('AIEO_DMM_Risk_Gating'))              { AIEO_DMM_Risk_Gating::bootstrap(); }
        if (class_exists('AIEO_DMM_COD_Country_Block'))        { AIEO_DMM_COD_Country_Block::bootstrap(); }
        if (class_exists('AIEO_DMM_Payment_Gating'))           { AIEO_DMM_Payment_Gating::bootstrap(); }
        if (class_exists('AIEO_DMM_Payment_Country_Block'))    { AIEO_DMM_Payment_Country_Block::bootstrap(); }

        
        
        
        if (class_exists('WooCommerce')) {
            $moi_bootstrap = $base . 'marketplace-order-importer/bootstrap.php';
            if (file_exists($moi_bootstrap)) { require_once $moi_bootstrap; }
        }
    }

    
    private static function is_pure_frontend_request() {
        if (is_admin() || wp_doing_ajax() || wp_doing_cron()) {
            return false;
        }
        if (defined('WP_CLI') && WP_CLI) {
            return false;
        }
        if (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) {
            return false;
        }
        if (defined('REST_REQUEST') && REST_REQUEST) {
            return false;
        }
        
        
        if (isset($_GET['wc-ajax'])) {
            return false;
        }
        $uri = isset($_SERVER['REQUEST_URI']) ? (string) wp_unslash($_SERVER['REQUEST_URI']) : '';
        if ($uri !== '') {
            $rest_prefix = function_exists('rest_get_url_prefix') ? rest_get_url_prefix() : 'wp-json';
            if (strpos($uri, '/' . $rest_prefix . '/') !== false || strpos($uri, 'rest_route=') !== false) {
                return false;
            }
        }
        return true;
    }

    
    private function load_modules() {
        $modules_dir = AIEO_DIR . 'includes/dmm/modules/';

        $files = array(
            'class-aieo-dmm-role-pricing.php'      => 'AIEO_DMM_Role_Pricing',
            'class-aieo-dmm-brand-discounts.php'   => 'AIEO_DMM_Brand_Discounts',
            'class-aieo-dmm-brand-gifts.php'       => 'AIEO_DMM_Brand_Gifts',
            'class-aieo-dmm-loyalty-classes.php'   => 'AIEO_DMM_Loyalty_Classes',
            'class-aieo-dmm-exit-intent.php'       => 'AIEO_DMM_Exit_Intent',
            'class-aieo-dmm-free-shipping.php'     => 'AIEO_DMM_Free_Shipping',
            'class-aieo-dmm-free-shipping-display.php' => 'AIEO_DMM_Free_Shipping_Display',
            'class-aieo-dmm-side-cart.php'         => 'AIEO_DMM_Side_Cart',
            'class-aieo-dmm-sticky-atc.php'        => 'AIEO_DMM_Sticky_ATC',
            'class-aieo-dmm-product-needs.php'     => 'AIEO_DMM_Product_Needs',
            'class-aieo-dmm-product-needs-display.php' => 'AIEO_DMM_Product_Needs_Display',
            'class-aieo-dmm-ratings-display.php'   => 'AIEO_DMM_Ratings_Display',
            'class-aieo-dmm-web-push-display.php'  => 'AIEO_DMM_Web_Push_Display',
            'class-aieo-dmm-wishlist-display.php'  => 'AIEO_DMM_Wishlist_Display',
            'class-aieo-dmm-waitlist-display.php'  => 'AIEO_DMM_Waitlist_Display',
            'class-aieo-dmm-complementary-display.php' => 'AIEO_DMM_Complementary_Display',
            'class-aieo-dmm-branch-scanner.php'    => 'AIEO_DMM_Branch_Scanner',
            'class-aieo-dmm-missing-hot-sellers.php' => 'AIEO_DMM_Missing_Hot_Sellers',
            'class-aieo-dmm-physical-recovery.php' => 'AIEO_DMM_Physical_Recovery',
            'class-aieo-dmm-saved-abandoned-carts.php' => 'AIEO_DMM_Saved_Abandoned_Carts',
            'class-aieo-dmm-problematic-variations.php' => 'AIEO_DMM_Problematic_Variations',
            'class-aieo-dmm-orders-export.php'     => 'AIEO_DMM_Orders_Export',
            'class-aieo-dmm-stock-import.php'      => 'AIEO_DMM_Stock_Import',
            'class-aieo-dmm-price-export.php'      => 'AIEO_DMM_Price_Export',
            'class-aieo-dmm-marketplace-feeds.php' => 'AIEO_DMM_Marketplace_Feeds',
            'class-aieo-dmm-catalog-importer.php' => 'AIEO_DMM_Catalog_Importer',
            'class-aieo-dmm-marketplace-taxonomy.php' => 'AIEO_DMM_Marketplace_Taxonomy',
            'class-aieo-dmm-google-reviews.php'    => 'AIEO_DMM_Google_Reviews',
            'class-aieo-dmm-product-exchanger.php' => 'AIEO_DMM_Product_Exchanger',
            'class-aieo-dmm-fulfillment.php'       => 'AIEO_DMM_Fulfillment',
            'class-aieo-dmm-data-prep-scheduler.php' => 'AIEO_DMM_Data_Prep_Scheduler',
            'class-aieo-dmm-product-orders-analytics.php' => 'AIEO_DMM_Product_Orders_Analytics',
            
            
            
            
            'class-aieo-dmm-insights-manage.php'               => 'AIEO_DMM_Insights_Manage',
            'class-aieo-dmm-tools.php'              => 'AIEO_DMM_Tools',
            'class-aieo-dmm-my-settings.php'       => 'AIEO_DMM_My_Settings',
            'class-aieo-dmm-plugin-usage.php'      => 'AIEO_DMM_Plugin_Usage',
            'class-aieo-dmm-media-cleanup.php'     => 'AIEO_DMM_Media_Cleanup',
            'class-aieo-dmm-button-styles.php'     => 'AIEO_DMM_Button_Styles',
            'class-aieo-dmm-as-cleanup.php'         => 'AIEO_DMM_As_Cleanup',
            'class-aieo-dmm-remote-export.php'      => 'AIEO_DMM_Remote_Export',
            'class-aieo-dmm-shipment-cost-reports.php' => 'AIEO_DMM_Shipment_Cost_Reports',
            'class-aieo-dmm-insights-chat.php'      => 'AIEO_DMM_Insights_Chat',
            'class-aieo-dmm-address-autocomplete.php' => 'AIEO_DMM_Address_Autocomplete',
            'class-aieo-dmm-checkout-invoicing.php'   => 'AIEO_DMM_Checkout_Invoicing',
            'class-aieo-dmm-checkout-layout.php'      => 'AIEO_DMM_Checkout_Layout',
            'class-aieo-dmm-account-handling.php'     => 'AIEO_DMM_Account_Handling',
            'class-aieo-dmm-min-order.php'            => 'AIEO_DMM_Min_Order',
            'class-aieo-dmm-phone-orders.php'         => 'AIEO_DMM_Phone_Orders',
            'class-aieo-dmm-checkout-modal.php'       => 'AIEO_DMM_Checkout_Modal',
            'class-aieo-dmm-social-login.php'         => 'AIEO_DMM_Social_Login',
            'class-aieo-dmm-shipping-rates.php'       => 'AIEO_DMM_Shipping_Rates',
            'class-aieo-dmm-local-pickup.php'         => 'AIEO_DMM_Local_Pickup',
            'class-aieo-dmm-smart-shipping-label.php' => 'AIEO_DMM_Smart_Shipping_Label',
            'class-aieo-dmm-checkout-product-images.php' => 'AIEO_DMM_Checkout_Product_Images',
            'class-aieo-dmm-product-display.php'      => 'AIEO_DMM_Product_Display',
            'class-aieo-dmm-payment-logos.php'        => 'AIEO_DMM_Payment_Logos',
            'class-aieo-dmm-product-labels.php'       => 'AIEO_DMM_Product_Labels',
            'class-aieo-dmm-badges.php'               => 'AIEO_DMM_Badges',
            'class-aieo-dmm-add-to-cart-text.php'     => 'AIEO_DMM_Add_To_Cart_Text',
            'class-aieo-dmm-trust-badges.php'         => 'AIEO_DMM_Trust_Badges',
            'class-aieo-dmm-product-meta.php'         => 'AIEO_DMM_Product_Meta',
            'class-aieo-dmm-product-categories.php'   => 'AIEO_DMM_Product_Categories',
            'class-aieo-dmm-product-card.php'         => 'AIEO_DMM_Product_Card',
            'class-aieo-dmm-product-archive-card.php' => 'AIEO_DMM_Product_Archive_Card',
            'class-aieo-dmm-product-video.php'        => 'AIEO_DMM_Product_Video',
            'class-aieo-dmm-variations-gallery.php'   => 'AIEO_DMM_Variations_Gallery',
            'class-aieo-dmm-erp-bridge.php'        => 'AIEO_DMM_ERP_Bridge',
            'class-aieo-dmm-erp-database.php'      => 'AIEO_DMM_ERP_Database',
            'class-aieo-dmm-attribution.php'       => 'AIEO_DMM_Attribution',
            'class-aieo-dmm-waitlist.php'          => 'AIEO_DMM_Waitlist',
            'class-aieo-dmm-wishlist.php'          => 'AIEO_DMM_Wishlist',
            'class-aieo-dmm-ratings.php'           => 'AIEO_DMM_Ratings',
            'class-aieo-dmm-web-push.php'          => 'AIEO_DMM_Web_Push',
            'class-aieo-dmm-surveys.php'           => 'AIEO_DMM_Surveys',
            'class-aieo-dmm-ai-chat-analytics.php' => 'AIEO_DMM_AI_Chat_Analytics',
            'class-aieo-dmm-events.php'            => 'AIEO_DMM_Events',
            'class-aieo-dmm-competitions.php'      => 'AIEO_DMM_Competitions',
            'class-aieo-dmm-faq.php'              => 'AIEO_DMM_FAQ',
            'class-aieo-dmm-store.php'            => 'AIEO_DMM_Store',
            'class-aieo-dmm-food-beverages.php'  => 'AIEO_DMM_Food_Beverages',
            'class-aieo-dmm-complementary.php'     => 'AIEO_DMM_Complementary',
            'class-aieo-dmm-conversions.php'       => 'AIEO_DMM_Conversions',
            'class-aieo-dmm-consent.php'           => 'AIEO_DMM_Consent',
            'class-aieo-dmm-checkout-timing.php'   => 'AIEO_DMM_Checkout_Timing',
            'class-aieo-dmm-session-analytics.php' => 'AIEO_DMM_Session_Analytics',
            'class-aieo-dmm-swatches.php'          => 'AIEO_DMM_Swatches',
            'class-aieo-dmm-price-history.php'     => 'AIEO_DMM_Price_History',
            'class-aieo-dmm-user-vitals.php'       => 'AIEO_DMM_User_Vitals',
            'class-aieo-dmm-newsletter-signup.php' => 'AIEO_DMM_Newsletter_Signup',
            'class-aieo-dmm-navigator.php'         => 'AIEO_DMM_Navigator',
            'class-aieo-dmm-category-extras.php'   => 'AIEO_DMM_Category_Extras',
            'class-aieo-dmm-brand-extras.php'      => 'AIEO_DMM_Brand_Extras',
            'class-aieo-dmm-brand-display.php'     => 'AIEO_DMM_Brand_Display',
            'class-aieo-dmm-custom-slots.php'      => 'AIEO_DMM_Custom_Slots',
            'class-aieo-dmm-custom-tabs.php'       => 'AIEO_DMM_Custom_Tabs',
            
            
            
            'class-aieo-dmm-seo.php'               => 'AIEO_DMM_SEO',
            'class-aieo-dmm-seo-import.php'        => 'AIEO_DMM_SEO_Import',
            'class-aieo-dmm-seo-health.php'        => 'AIEO_DMM_SEO_Health',
            'class-aieo-dmm-seo-opportunities.php' => 'AIEO_DMM_SEO_Opportunities',
            'class-aieo-dmm-seo-redirects.php'     => 'AIEO_DMM_SEO_Redirects',
            'class-aieo-dmm-seo-schema.php'        => 'AIEO_DMM_SEO_Schema',
            'class-aieo-dmm-seo-social.php'        => 'AIEO_DMM_SEO_Social',
            'class-aieo-dmm-need-extras.php'       => 'AIEO_DMM_Need_Extras',
            'class-aieo-dmm-tag-extras.php'        => 'AIEO_DMM_Tag_Extras',
            'class-aieo-dmm-supplier-extras.php'   => 'AIEO_DMM_Supplier_Extras',
            'class-aieo-dmm-cancellations.php'     => 'AIEO_DMM_Cancellations',
            'class-aieo-dmm-campaigns-admin.php'   => 'AIEO_DMM_Campaigns_Admin',
            'class-aieo-dmm-promo-surfaces.php'    => 'AIEO_DMM_Promo_Surfaces',
        );

        
        
        
        
        
        
        $aieo_food = get_option( 'aieo_food_settings', array() );
        if ( is_array( $aieo_food ) && ! empty( $aieo_food['enabled'] )
            && ( ! isset( $aieo_food['features']['option_groups'] ) || ! empty( $aieo_food['features']['option_groups'] ) ) ) {
            $files['class-aieo-dmm-option-groups.php'] = 'AIEO_DMM_Option_Groups';
        }

        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        $is_frontend_request = defined('OM_REQUEST_TYPE')
            ? (OM_REQUEST_TYPE === 'frontend')
            : self::is_pure_frontend_request();
        $frontend_skip = $is_frontend_request ? array(
            'AIEO_DMM_Attribution',
            
            
            'AIEO_DMM_Session_Analytics',
            'AIEO_DMM_Branch_Scanner',
            'AIEO_DMM_Data_Prep_Scheduler',
            'AIEO_DMM_Product_Orders_Analytics',
            'AIEO_DMM_Insights_Manage',
            'AIEO_DMM_ERP_Bridge',
            'AIEO_DMM_ERP_Database',
            'AIEO_DMM_Fulfillment',
            
            
            
            
            
            
            
            
            
            
            'AIEO_DMM_Loyalty_Classes',
            'AIEO_DMM_Marketplace_Feeds',
            'AIEO_DMM_Orders_Export',
            'AIEO_DMM_Phone_Orders',
            'AIEO_DMM_Price_Export',
            
            
            
            'AIEO_DMM_Product_Exchanger',
            'AIEO_DMM_Ratings',
            'AIEO_DMM_Shipment_Cost_Reports',
            'AIEO_DMM_Shipping_Rates',
            'AIEO_DMM_Social_Login',
            'AIEO_DMM_Stock_Import',
            'AIEO_DMM_Tools',
            'AIEO_DMM_As_Cleanup',
            
            
            'AIEO_DMM_SEO',
            
            'AIEO_DMM_SEO_Import',
            
            'AIEO_DMM_SEO_Health',
            
            'AIEO_DMM_SEO_Opportunities',
            
            
            'AIEO_DMM_SEO_Redirects',
            
            'AIEO_DMM_SEO_Schema',
            'AIEO_DMM_SEO_Social',
            
            
            'AIEO_DMM_Brand_Extras',
            'AIEO_DMM_Need_Extras',
            'AIEO_DMM_Tag_Extras',
            'AIEO_DMM_Supplier_Extras',
            'AIEO_DMM_Cancellations',
            
            'AIEO_DMM_Complementary_Display',
            'AIEO_DMM_Free_Shipping_Display',
            'AIEO_DMM_Product_Needs_Display',
            'AIEO_DMM_Ratings_Display',
            'AIEO_DMM_Waitlist_Display',
            'AIEO_DMM_Web_Push_Display',
            'AIEO_DMM_Wishlist_Display',
        ) : array();
        $frontend_skip = array_flip($frontend_skip); 

        
        
        
        
        $router_on = $is_frontend_request
            && class_exists('AIEO_Module_Manifest')
            && AIEO_Module_Manifest::is_enabled();

        foreach ($files as $file => $class) {
            if (isset($frontend_skip[$class])) {
                continue;
            }
            if ($router_on && !AIEO_Module_Manifest::should_load($class)) {
                continue;
            }
            $path = $modules_dir . $file;
            if (!file_exists($path)) {
                continue;
            }
            require_once $path;
            if (class_exists($class)) {
                $module = new $class();
                if ($module instanceof AIEO_DMM_Module_Base) {
                    $this->modules[$module->get_id()] = $module;
                    
                    
                    
                    $module_group   = method_exists($module, 'get_group')
                        ? $this->resolve_group_alias($module->get_group())
                        : null;
                    
                    
                    
                    
                    $module_section = '';
                    if (method_exists($module, 'get_section')) {
                        $own = $module->get_section();
                        if (is_string($own) && $own !== '') {
                            $module_section = $own;
                        }
                    }
                    if ($module_section === '') {
                        $module_section = $this->resolve_module_section($module->get_id());
                    }
                    
                    
                    
                    
                    
                    if ($module_section === '') {
                        $raw_group = method_exists($module, 'get_group') ? (string) $module->get_group() : '';
                        if ($raw_group !== '' && $raw_group !== $module_group) {
                            $secs  = $this->get_section_definitions();
                            $valid = isset($secs[$module_group]) ? wp_list_pluck($secs[$module_group], 'id') : array();
                            if (in_array($raw_group, $valid, true)) { $module_section = $raw_group; }
                        }
                    }
                    $this->subtabs[] = array(
                        'id'       => $module->get_id(),
                        'label'    => $module->get_label(),
                        'priority' => $module->get_priority(),
                        'group'    => $module_group,
                        'section'  => $module_section,
                    );
                }
            }
        }

        
        
        
        
        do_action('aieo_dmm_register_dynamic_modules', $this);

        usort($this->subtabs, static function ($a, $b) {
            return $a['priority'] <=> $b['priority'];
        });
    }

    
    public function register_module($module) {
        if (!($module instanceof AIEO_DMM_Module_Base)) { return; }
        $id = (string) $module->get_id();
        if ($id === '' || isset($this->modules[$id])) { return; }
        $this->modules[$id] = $module;
        $group = method_exists($module, 'get_group') ? $this->resolve_group_alias($module->get_group()) : null;
        $section = '';
        if (method_exists($module, 'get_section')) {
            $own = $module->get_section();
            if (is_string($own) && $own !== '') { $section = $own; }
        }
        if ($section === '') { $section = $this->resolve_module_section($id); }
        $this->subtabs[] = array(
            'id'       => $id,
            'label'    => $module->get_label(),
            'priority' => $module->get_priority(),
            'group'    => $group,
            'section'  => $section,
        );
    }

    
    public function get_group_definitions() {
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        return apply_filters('aieo_dmm_group_definitions', array(
            
            
            
            
            array(
                'id'       => 'catalog_sync',
                'label'    => __('Catalog Sync', 'ai-eshop-optimizer'),
                'priority' => 10,
            ),
            array(
                'id'       => 'pricing_offers',
                'label'    => __('Pricing &amp; Offers', 'ai-eshop-optimizer'),
                'priority' => 20,
            ),
            array(
                'id'       => 'storefront',
                'label'    => __('Storefront Display', 'ai-eshop-optimizer'),
                'priority' => 30,
            ),
            
            
            
            array(
                'id'       => 'seo',
                'label'    => __('SEO', 'ai-eshop-optimizer'),
                'priority' => 40,
            ),
            
            
            array(
                'id'       => 'aichat',
                'label'    => __('AI Chat', 'ai-eshop-optimizer'),
                'priority' => 45,
            ),
            array(
                'id'       => 'eshop_insights',
                'label'    => __('e-Shop Insights', 'ai-eshop-optimizer'),
                'priority' => 50,
            ),
            array(
                'id'       => 'customer_profiling',
                'label'    => __('Customer Profiling', 'ai-eshop-optimizer'),
                'priority' => 60,
            ),
            array(
                'id'       => 'attribution',
                'label'    => __('Attribution', 'ai-eshop-optimizer'),
                'priority' => 70,
            ),
            array(
                'id'       => 'custom_post_types',
                'label'    => __('Custom Post Types', 'ai-eshop-optimizer'),
                'priority' => 80,
            ),
            array(
                'id'       => 'tools',
                'label'    => __('Tools &amp; Settings', 'ai-eshop-optimizer'),
                'priority' => 90,
            ),
            
            
            
            array(
                'id'       => 'setup',
                'label'    => __('Set Up', 'ai-eshop-optimizer'),
                'priority' => 95,
            ),
        ));
    }

    
    public function get_nav_link_items() {
        
        
        
        
        
        
        
        $analytics = admin_url('admin.php?page=ai-eshop-optimizer');
        $chat      = admin_url('admin.php?page=ai-eshop-chat');

        $items = array();

        $p = 10;
        foreach (array(
            'Overview'        => '#aieo-card-intro',
            'Preferences'     => '#aieo-card-status',
            'Orders Export'   => '#aieo-card-orders-export',
            'Statistics'      => '#aieo-card-indicative-statistics',
            'AI Processing'   => '#aieo-card-process-data',
            'Eshop Update'    => '#aieo-card-eshop-update',
            'Expert Services' => '#aieo-card-expert-services',
            'Pro Panel'       => '#aieo-card-pro-panel',
        ) as $label => $hash) {
            $items[] = array(
                'group'    => 'setup',
                'id'       => 'setup_an_' . sanitize_title($label),
                'label'    => __($label, 'ai-eshop-optimizer'), 
                'url'      => $analytics . $hash,
                'priority' => $p,
            );
            $p += 10;
        }

        $p = 10;
        foreach (array(
            'API & Models'    => '#aieo-card-chat-step-1-api',
            'Frontend'        => '#aieo-card-chat-step-2-frontend',
            'Knowledge Base'  => '#aieo-card-chat-knowledge-base',
            'Analytics Setup' => '#aieo-card-chat-analytics',
        ) as $label => $hash) {
            $items[] = array(
                'group'    => 'aichat',
                'section'  => 'setup',
                'id'       => 'setup_chat_' . sanitize_title($label),
                'label'    => __($label, 'ai-eshop-optimizer'), 
                'url'      => $chat . $hash,
                'priority' => $p,
            );
            $p += 10;
        }

        return apply_filters('aieo_dmm_nav_link_items', $items);
    }

    
    public function get_group_aliases() {
        return apply_filters('aieo_dmm_group_aliases', array(
            'visuals'                => 'storefront',
            'product_display'        => 'storefront',
            'import_export'          => 'catalog_sync',
            'product_management'     => 'catalog_sync',
            'campaigns'              => 'pricing_offers',
            'special_pricing_offers' => 'pricing_offers',
            
            
            
            
            'checkout_handling'      => 'storefront',
        ));
    }

    public function resolve_group_alias($slug) {
        if (!is_string($slug) || $slug === '') { return $slug; }
        $aliases = $this->get_group_aliases();
        return isset($aliases[$slug]) ? $aliases[$slug] : $slug;
    }

    
    
    public function get_menu_schema_version() { return '2026-06-09-8groups-sections'; }

    public function get_section_definitions() {
        $defs = array(
            
            
            'aichat' => array(
                array('id' => 'setup',     'label' => __('Setup', 'ai-eshop-optimizer')),
                array('id' => 'analytics', 'label' => __('Analytics', 'ai-eshop-optimizer')),
            ),
            'storefront' => array(
                array('id' => 'product_cards',     'label' => __('Product Cards', 'ai-eshop-optimizer')),
                array('id' => 'pdp',               'label' => __('Single Product Page', 'ai-eshop-optimizer')),
                array('id' => 'discoverability',   'label' => __('Discoverability', 'ai-eshop-optimizer')),
                array('id' => 'checkout_handling', 'label' => __('Checkout', 'ai-eshop-optimizer')),
            ),
            
            
            'catalog_sync' => array(
                array('id' => 'sync_feeds',       'label' => __('Sync &amp; Feeds', 'ai-eshop-optimizer')),
                array('id' => 'stock_management', 'label' => __('Stock Management', 'ai-eshop-optimizer')),
            ),
            
            
            
            'seo' => array(
                array('id' => 'health',    'label' => __('SEO Health', 'ai-eshop-optimizer')),
                array('id' => 'general',   'label' => __('General', 'ai-eshop-optimizer')),
                array('id' => 'social',    'label' => __('Social', 'ai-eshop-optimizer')),
                array('id' => 'schema',    'label' => __('Schema', 'ai-eshop-optimizer')),
                array('id' => 'sitemap',   'label' => __('Sitemap', 'ai-eshop-optimizer')),
                array('id' => 'redirects', 'label' => __('Redirects', 'ai-eshop-optimizer')),
                array('id' => 'linking',   'label' => __('Internal Linking', 'ai-eshop-optimizer')),
                array('id' => 'tools',     'label' => __('Tools', 'ai-eshop-optimizer')),
            ),
        );
        
        
        if (class_exists('AIEO_DMM_Insights_Base')) {
            $defs['eshop_insights'] = AIEO_DMM_Insights_Base::section_defs();
        }
        return apply_filters('aieo_dmm_section_definitions', $defs);
    }

    
    public function get_module_section_assignments() {
        return apply_filters('aieo_dmm_module_section_assignments', array(
            
            'product_archive_card' => 'product_cards',
            'product_card'        => 'product_cards',
            'badges'              => 'product_cards',
            'add_to_cart_text'    => 'product_cards',
            'product_labels'      => 'product_cards',
            'ratings_display'     => 'product_cards',
            'swatches'            => 'product_cards',
            'tag_extras'          => 'product_cards',
            'trust_badges'        => 'product_cards',

            
            'variations_gallery'  => 'pdp',
            'product_video'       => 'pdp',
            'product_meta'        => 'pdp',
            'product_categories'  => 'pdp',
            'product_display'     => 'pdp',
            'sticky_atc'          => 'pdp',
            'custom_slots'        => 'pdp',
            'custom_tabs'         => 'pdp',
            'payment_logos'       => 'pdp',
            'free_shipping_display'=> 'pdp',
            'supplier_extras'     => 'pdp',
            'brand_display'       => 'pdp',

            
            'navigator'           => 'discoverability',
            'product_needs_display'=> 'discoverability',
            'complementary_display'=> 'discoverability',
            'side_cart'           => 'discoverability',
            'web_push_display'    => 'discoverability',
            'wishlist_display'    => 'discoverability',
            'waitlist_display'    => 'discoverability',
            'brand_extras'        => 'discoverability',
            'category_extras'     => 'discoverability',
            'need_extras'         => 'discoverability',
            'newsletter_signup'   => 'discoverability',

            
            'missing_hot_sellers' => 'stock_management',
            'stock_recovery'      => 'stock_management',
            'saved_abandoned_carts' => 'stock_management',
            'problematic_variations' => 'stock_management',
            'branch_scanner'      => 'stock_management',
            'stock_import'        => 'stock_management',
            'price_export'        => 'stock_management',
            'data_prep_scheduler' => 'stock_management',

            
            'orders_export'              => 'sync_feeds',
            'marketplace_feeds'          => 'sync_feeds',
            'product_exchanger'          => 'sync_feeds',
            'fulfillment'                => 'sync_feeds',
            'complementary'              => 'sync_feeds',
            'product_needs'              => 'sync_feeds',
            'marketplace_order_importer' => 'sync_feeds',
            'catalog_importer'           => 'sync_feeds',
            'google_reviews'             => 'sync_feeds',
        ));
    }

    public function resolve_module_section($module_id) {
        $map = $this->get_module_section_assignments();
        return isset($map[$module_id]) ? (string) $map[$module_id] : '';
    }

    
    public function get_subtab_tree($active_id = '') {
        $groups = array();
        foreach ($this->get_group_definitions() as $g) {
            $groups[$g['id']] = array(
                'kind'       => 'group',
                'id'         => $g['id'],
                'label'      => $g['label'],
                'priority'   => $g['priority'],
                'children'   => array(),
                'has_active' => false,
            );
        }

        $top = array();
        foreach ($this->subtabs as $tab) {
            $gid = isset($tab['group']) ? $tab['group'] : null;
            if ($gid !== null && isset($groups[$gid])) {
                $groups[$gid]['children'][] = $tab;
                if ($tab['id'] === $active_id) {
                    $groups[$gid]['has_active'] = true;
                }
            } else {
                $top[] = array(
                    'kind'     => 'tab',
                    'id'       => $tab['id'],
                    'label'    => $tab['label'],
                    'priority' => $tab['priority'],
                );
            }
        }

        
        
        
        
        foreach ($this->get_nav_link_items() as $li) {
            $gid = isset($li['group']) ? $li['group'] : null;
            if ($gid !== null && isset($groups[$gid])) {
                $groups[$gid]['children'][] = array(
                    'kind'     => 'link',
                    'id'       => $li['id'],
                    'label'    => $li['label'],
                    'url'      => $li['url'],
                    'section'  => isset($li['section']) ? (string) $li['section'] : '',
                    'priority' => isset($li['priority']) ? (int) $li['priority'] : 100,
                );
            }
        }

        
        
        
        
        
        $section_defs = $this->get_section_definitions();

        foreach ($groups as $g) {
            
            usort($g['children'], static function ($a, $b) {
                return $a['priority'] <=> $b['priority'];
            });

            if (!empty($section_defs[$g['id']])) {
                
                $section_buckets = array();
                foreach ($section_defs[$g['id']] as $sdef) {
                    $section_buckets[$sdef['id']] = array(
                        'id'       => $sdef['id'],
                        'label'    => $sdef['label'],
                        'children' => array(),
                    );
                }
                $other_bucket = array(
                    'id'       => '_other',
                    'label'    => '',
                    'children' => array(),
                );
                foreach ($g['children'] as $ch) {
                    $sid = isset($ch['section']) ? (string) $ch['section'] : '';
                    if ($sid !== '' && isset($section_buckets[$sid])) {
                        $section_buckets[$sid]['children'][] = $ch;
                    } else {
                        $other_bucket['children'][] = $ch;
                    }
                }
                
                
                $g['sections'] = array();
                foreach ($section_buckets as $b) {
                    if (!empty($b['children'])) { $g['sections'][] = $b; }
                }
                if (!empty($other_bucket['children'])) {
                    $g['sections'][] = $other_bucket;
                }
            }

            
            if (!empty($g['children'])) {
                $top[] = $g;
            }
        }

        usort($top, static function ($a, $b) {
            return $a['priority'] <=> $b['priority'];
        });

        return $top;
    }

    
    public function build_admin_navigator_entries(): array {
        $tree = $this->get_subtab_tree();
        $out  = array();

        
        
        $tab_eshop = self::get_menu_title();

        
        
        
        
        $tab_keywords = array(
            'catalog_importer'  => 'import importer catalogue catalog products create amazon sp-api efood e-food etsy wolt marketplace barcodes sku enrich draft ingest read catalogue from marketplace vendor',
            'ai_chat_analytics' => 'ai chat analytics conversation log questions customer profiling happiness rating sentiment chat-assisted conversions origin page session tracker',
        );
        $kw = static function ($id) use ($tab_keywords) {
            return isset($tab_keywords[$id]) ? $tab_keywords[$id] : '';
        };

        foreach ($tree as $node) {
            if (!isset($node['kind'])) { continue; }
            if ($node['kind'] === 'tab') {
                $out[] = array(
                    'tab'      => $tab_eshop,
                    'label'    => (string) $node['label'],
                    'group'    => null,
                    'slug'     => (string) $node['id'],
                    'keywords' => $kw((string) $node['id']),
                    'url'      => esc_url_raw(add_query_arg(
                        array('page' => self::MENU_SLUG, 'dmm_tab' => $node['id']),
                        admin_url('admin.php')
                    )),
                );
            } elseif ($node['kind'] === 'group' && !empty($node['children'])) {
                
                
                
                
                $sec_labels = array();
                $sec_defs   = $this->get_section_definitions();
                if (isset($sec_defs[$node['id']])) {
                    foreach ($sec_defs[$node['id']] as $s) {
                        $sec_labels[$s['id']] = wp_strip_all_tags($s['label']);
                    }
                }
                foreach ($node['children'] as $child) {
                    
                    
                    
                    
                    
                    
                    if (isset($child['kind']) && 'link' === $child['kind']) { continue; }
                    $group = (string) $node['label'];
                    $sid   = isset($child['section']) ? (string) $child['section'] : '';
                    if ($sid !== '' && isset($sec_labels[$sid])) {
                        $group .= ' · ' . $sec_labels[$sid];
                    }
                    $out[] = array(
                        'tab'      => $tab_eshop,
                        'label'    => (string) $child['label'],
                        'group'    => $group,
                        'slug'     => (string) $child['id'],
                        'keywords' => $kw((string) $child['id']),
                        'url'      => esc_url_raw(add_query_arg(
                            array('page' => self::MENU_SLUG, 'dmm_tab' => $child['id']),
                            admin_url('admin.php')
                        )),
                    );
                }
            }
        }

        
        
        
        
        
        
        
        
        $g_analytics = __('Analytics', 'ai-eshop-optimizer');
        $g_chat      = __('AI Chat', 'ai-eshop-optimizer');
        $cards = apply_filters('aieo_dmm_admin_navigator_cards', array(
            
            
            
            
            array('label' => __('Overview', 'ai-eshop-optimizer'),                       'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'intro',                  'group' => $g_analytics),
            array('label' => __('Orders Export', 'ai-eshop-optimizer'),                  'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'orders-export',          'group' => $g_analytics),
            array('label' => __('Indicative Statistics', 'ai-eshop-optimizer'),          'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'indicative-statistics',  'group' => $g_analytics),
            array('label' => __('Process Data (AI service)', 'ai-eshop-optimizer'),      'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'process-data',           'group' => $g_analytics),
            array('label' => __('Eshop Update', 'ai-eshop-optimizer'),                   'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'eshop-update',           'group' => $g_analytics),
            array('label' => __('Expert Performance Services', 'ai-eshop-optimizer'),    'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'expert-services',        'group' => $g_analytics),
            array('label' => __('Pro Panel', 'ai-eshop-optimizer'),                      'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'pro-panel',              'group' => $g_analytics),
            
            array('label' => __('Display preferences', 'ai-eshop-optimizer'),                 'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'display-preferences',     'group' => $g_analytics),
            array('label' => __('Activate Google UTM Analytics', 'ai-eshop-optimizer'),       'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'utm-analytics',           'group' => $g_analytics),
            array('label' => __('AI Session Tracker', 'ai-eshop-optimizer'),                 'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'ai-session-tracker',      'group' => $g_analytics),
            array('label' => __('Database Performance Optimization', 'ai-eshop-optimizer'),   'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'db-performance',          'group' => $g_analytics),
            array('label' => __('Privacy first', 'ai-eshop-optimizer'),                       'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'privacy-first',           'group' => $g_analytics),
            array('label' => __('Repeat Registered Customers', 'ai-eshop-optimizer'),         'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'repeat-customers',        'group' => $g_analytics),
            array('label' => __('Brand / Sizes / Colours / Seasonality', 'ai-eshop-optimizer'), 'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'product-choices',       'group' => $g_analytics),
            array('label' => __('Operational Efficiency Settings', 'ai-eshop-optimizer'),     'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'operational-efficiency',  'group' => $g_analytics),
            array('label' => __('Dataset Starting Point', 'ai-eshop-optimizer'),              'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'dataset-start',           'group' => $g_analytics),
            array('label' => __('Performance Audit', 'ai-eshop-optimizer'),                   'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'performance-audit',       'group' => $g_analytics),
            array('label' => __('Link Eshop-Optimizer.com Account', 'ai-eshop-optimizer'),    'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'link-account',            'group' => $g_analytics),
            array('label' => __('Rooster Content Connector', 'ai-eshop-optimizer'),           'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'rooster-content',         'group' => $g_analytics),
            array('label' => __('Remote Transfer', 'ai-eshop-optimizer'),                     'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'remote-transfer',         'group' => $g_analytics),
            array('label' => __('Inspect Profitability', 'ai-eshop-optimizer'),               'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'profitability',           'group' => $g_analytics),
            array('label' => __('Go Phygital (offline sales)', 'ai-eshop-optimizer'),         'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'phygital',                'group' => $g_analytics),
            array('label' => __('Establish Fundamentals', 'ai-eshop-optimizer'),              'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'fundamentals',            'group' => $g_analytics),
            array('label' => __('Google GA4 Events', 'ai-eshop-optimizer'),                   'page_slug' => 'ai-eshop-optimizer', 'anchor' => 'ga4-events',              'group' => $g_analytics),

            
            
            array('label' => __('Step 1 — API + Embeddings', 'ai-eshop-optimizer'),      'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-step-1-api',         'group' => $g_chat),
            array('label' => __('Step 2 — Frontend & Config', 'ai-eshop-optimizer'),     'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-step-2-frontend',    'group' => $g_chat),
            array('label' => __('Step 2.5 — Knowledge Base', 'ai-eshop-optimizer'),      'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-knowledge-base',     'group' => $g_chat),
            array('label' => __('Chat Analytics & DB Status', 'ai-eshop-optimizer'),     'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-analytics',          'group' => $g_chat),
            
            array('label' => __('API Keys Required', 'ai-eshop-optimizer'),              'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-api-keys',           'group' => $g_chat),
            array('label' => __('Select Content Types', 'ai-eshop-optimizer'),           'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-content-types',      'group' => $g_chat),
            array('label' => __('Active Models for Frontend', 'ai-eshop-optimizer'),     'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-active-models',      'group' => $g_chat),
            array('label' => __('Floating Chat Widget', 'ai-eshop-optimizer'),           'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-widget',             'group' => $g_chat),
            array('label' => __('Chat Settings', 'ai-eshop-optimizer'),                  'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-settings',           'group' => $g_chat),
            array('label' => __('Contextual Metadata', 'ai-eshop-optimizer'),            'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-contextual-metadata','group' => $g_chat),
            array('label' => __('Search Re-Ranking Weights', 'ai-eshop-optimizer'),      'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-rerank-weights',     'group' => $g_chat),
            array('label' => __('Search Results Configuration', 'ai-eshop-optimizer'),   'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-search-config',      'group' => $g_chat),
            array('label' => __('Business Knowledge Base', 'ai-eshop-optimizer'),        'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-business-kb',        'group' => $g_chat),
            array('label' => __('Add Business Information', 'ai-eshop-optimizer'),       'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-add-business-info',  'group' => $g_chat),
            array('label' => __('WooCommerce Shipping Rates', 'ai-eshop-optimizer'),     'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-shipping-rates',     'group' => $g_chat),
            array('label' => __('Import from Existing Pages', 'ai-eshop-optimizer'),     'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-import-pages',       'group' => $g_chat),
            array('label' => __('Chat Statistics', 'ai-eshop-optimizer'),                'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-statistics',         'group' => $g_chat),
            array('label' => __('Database Status', 'ai-eshop-optimizer'),                'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-db-status',          'group' => $g_chat),
            array('label' => __('Process Automation', 'ai-eshop-optimizer'),             'page_slug' => 'ai-eshop-chat',      'anchor' => 'chat-process-automation', 'group' => $g_chat),

            
            array('label' => __('Display Order (drag-and-drop)', 'ai-eshop-optimizer'), 'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'product_display', 'anchor' => 'display-order'),
            array('label' => __('Product page layout & element positioning (order + under-image)', 'ai-eshop-optimizer'), 'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'product_display', 'anchor' => 'display-order'),

            
            array('label' => __('Saved & Abandoned Carts', 'ai-eshop-optimizer'),                       'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'saved_abandoned_carts', 'anchor' => 'saved-abandoned-carts'),
            array('label' => __('Abandoned cart report (lost revenue / recovery)', 'ai-eshop-optimizer'), 'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'saved_abandoned_carts', 'anchor' => 'saved-abandoned-carts'),

            
            array('label' => __('Subscribers', 'ai-eshop-optimizer'),         'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'web-push', 'anchor' => 'subscribers'),
            array('label' => __('Newsletter settings', 'ai-eshop-optimizer'), 'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'web-push', 'anchor' => 'newsletter-settings'),
            array('label' => __('Campaign launcher', 'ai-eshop-optimizer'),   'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'web-push', 'anchor' => 'campaign-launcher'),
            array('label' => __('Segments', 'ai-eshop-optimizer'),            'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'web-push', 'anchor' => 'segments'),
            array('label' => __('Reactivation', 'ai-eshop-optimizer'),        'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'web-push', 'anchor' => 'reactivation'),
            array('label' => __('Lost cohort', 'ai-eshop-optimizer'),         'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'web-push', 'anchor' => 'lost-cohort'),
            array('label' => __('Lookalike export', 'ai-eshop-optimizer'),    'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'web-push', 'anchor' => 'lookalike-export'),
            array('label' => __('Top customers', 'ai-eshop-optimizer'),       'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'web-push', 'anchor' => 'top-customers'),
            array('label' => __('Triggers', 'ai-eshop-optimizer'),            'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'web-push', 'anchor' => 'triggers'),
            array('label' => __('Dispatch log', 'ai-eshop-optimizer'),        'page_slug' => self::MENU_SLUG, 'dmm_tab' => 'web-push', 'anchor' => 'dispatch-log'),
        ));

        
        
        
        $tab_map = array(
            'ai-eshop-optimizer' => __('Analytics', 'ai-eshop-optimizer'),
            self::MENU_SLUG      => self::get_menu_title(),
            'ai-eshop-chat'      => __('AI Chat', 'ai-eshop-optimizer'),
        );

        foreach ($cards as $c) {
            $page_slug = isset($c['page_slug']) ? (string) $c['page_slug'] : self::MENU_SLUG;
            $args = array('page' => $page_slug);
            if (!empty($c['dmm_tab'])) {
                $args['dmm_tab'] = (string) $c['dmm_tab'];
            }
            $url = esc_url_raw(add_query_arg($args, admin_url('admin.php'))) . '#aieo-card-' . rawurlencode((string) $c['anchor']);

            
            $group = isset($c['group']) ? (string) $c['group'] : '';
            if ($group === '' && !empty($c['dmm_tab'])) {
                foreach ($out as $row) {
                    if ($row['slug'] === $c['dmm_tab']) { $group = $row['label']; break; }
                }
            }

            $out[] = array(
                'tab'      => isset($tab_map[$page_slug]) ? $tab_map[$page_slug] : $page_slug,
                'label'    => (string) $c['label'],
                'group'    => $group !== '' ? $group : $page_slug,
                'slug'     => $page_slug . (isset($c['dmm_tab']) ? '/' . $c['dmm_tab'] : '') . '#' . $c['anchor'],
                'keywords' => isset($c['keywords']) ? (string) $c['keywords'] : '',
                'url'      => $url,
            );
        }

        usort($out, static function ($a, $b) {
            return strnatcasecmp((string) $a['label'], (string) $b['label']);
        });

        return $out;
    }

    
    
    const MENU_TITLE_OPTION  = 'aieo_dmm_menu_title';
    const MENU_TITLE_DEFAULT = 'e-shop Manager';

    public static function get_menu_title() {
        $stored = trim((string) get_option(self::MENU_TITLE_OPTION, ''));
        return $stored !== '' ? $stored : self::MENU_TITLE_DEFAULT;
    }

    
    const GROSS_MARGIN_OPTION  = 'aieo_gross_profit_margin';
    const GROSS_MARGIN_DEFAULT = 60;

    public static function get_gross_margin_pct() {
        $v = (float) get_option(self::GROSS_MARGIN_OPTION, self::GROSS_MARGIN_DEFAULT);
        if ($v < 1)  { return (float) self::GROSS_MARGIN_DEFAULT; }
        if ($v > 99) { return 99.0; }
        return $v;
    }

    
    public static function get_gross_margin() {
        return self::get_gross_margin_pct() / 100;
    }

    
    const FREE_SHIP_THRESHOLD_OPTION  = 'aieo_free_shipping_threshold';
    const FREE_SHIP_THRESHOLD_DEFAULT = 35;

    public static function get_free_shipping_threshold() {
        $v = get_option(self::FREE_SHIP_THRESHOLD_OPTION, self::FREE_SHIP_THRESHOLD_DEFAULT);
        $v = (float) $v;
        return $v >= 0 ? $v : (float) self::FREE_SHIP_THRESHOLD_DEFAULT;
    }

    
    const OPS_COST_MONTHLY_OPTION  = 'aieo_ops_cost_monthly';
    const OPS_COST_MONTHLY_DEFAULT = 0;

    
    public static function get_ops_cost_monthly() {
        $v = (float) get_option(self::OPS_COST_MONTHLY_OPTION, self::OPS_COST_MONTHLY_DEFAULT);
        return $v > 0 ? $v : 0.0;
    }

    
    public static function get_ops_cost_daily() {
        return self::get_ops_cost_monthly() / 30.4375;
    }

    
    public static function get_ops_cost_for_period($from, $to) {
        $ff = strtotime((string) $from);
        $tt = strtotime((string) $to);
        if (!$ff || !$tt || $tt < $ff) { return 0.0; }
        $days = (int) floor(($tt - $ff) / DAY_IN_SECONDS) + 1; 
        return self::get_ops_cost_daily() * $days;
    }

    public function register_menu() {
        
        
        
        $title = self::get_menu_title();
        add_submenu_page(
            'ai-eshop-optimizer',
            $title,                      
            '🏷️ ' . $title,              
            AIEO_CAPABILITY,
            self::MENU_SLUG,
            array($this, 'render_page')
        );
    }

    
    public function reorder_admin_submenu() {
        global $submenu;
        $parent = 'ai-eshop-optimizer';
        if (empty($submenu[$parent]) || !is_array($submenu[$parent])) { return; }

        
        $found_idx = null;
        foreach ($submenu[$parent] as $idx => $item) {
            if (isset($item[2]) && $item[2] === self::MENU_SLUG) { $found_idx = $idx; break; }
        }
        if ($found_idx === null) { return; }

        
        
        $entry = $submenu[$parent][$found_idx];
        unset($submenu[$parent][$found_idx]);
        $submenu[$parent] = array_values($submenu[$parent]);
        
        array_splice($submenu[$parent], 1, 0, array($entry));
    }

    
    public function render_page() {
        if (!current_user_can(AIEO_CAPABILITY)) {
            wp_die(esc_html__('You do not have permission to access this page.', 'ai-eshop-optimizer'));
        }

        $active_id = $this->get_active_subtab_id();
        $module    = isset($this->modules[$active_id]) ? $this->modules[$active_id] : null;

        include AIEO_DIR . 'assets/pages/dmm/page.php';
    }

    
    public function get_active_subtab_id() {
        $requested = isset($_GET['dmm_tab']) ? sanitize_key(wp_unslash($_GET['dmm_tab'])) : '';
        if ($requested !== '' && isset($this->modules[$requested])) {
            return $requested;
        }
        
        
        
        $uid = get_current_user_id();
        if ($uid) {
            $landing = (string) get_user_meta($uid, self::LANDING_USER_META, true);
            if ($landing === '__resume__') {
                
                
                if (class_exists('AIEO_DMM_Plugin_Usage')) {
                    $last = AIEO_DMM_Plugin_Usage::last_tab_for_user($uid);
                    if ($last !== '' && isset($this->modules[$last])) {
                        return $last;
                    }
                }
            } elseif ($landing !== '' && isset($this->modules[$landing])) {
                return $landing;
            }
        }
        
        if (!empty($this->subtabs)) {
            return $this->subtabs[0]['id'];
        }
        return '';
    }

    
    public function get_subtab_url($subtab_id) {
        return add_query_arg(
            array('page' => self::MENU_SLUG, 'dmm_tab' => $subtab_id),
            admin_url('admin.php')
        );
    }

    
    public function get_subtabs() {
        return $this->subtabs;
    }

    
    public function get_module($id) {
        return isset($this->modules[$id]) ? $this->modules[$id] : null;
    }

    
    public function get_modules() {
        return $this->modules;
    }

    
    public function enqueue_admin_assets($hook_suffix) {
        
        $is_dmm_page = isset($_GET['page']) && sanitize_key(wp_unslash($_GET['page'])) === self::MENU_SLUG;

        
        
        
        
        $cur_page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : '';
        $is_aieo_admin = $cur_page !== '' && strpos($cur_page, 'ai-eshop-') === 0;
        if ($is_aieo_admin && current_user_can('manage_options')) {
            $admin_nav_path = AIEO_DIR . 'assets/js/aieo-admin-navigator.js';
            if (file_exists($admin_nav_path)) {
                $admin_nav_ver = (string) filemtime($admin_nav_path);
                wp_enqueue_script(
                    'aieo-admin-navigator',
                    AIEO_URI . 'assets/js/aieo-admin-navigator.js',
                    array(),
                    $admin_nav_ver,
                    true
                );
                wp_localize_script('aieo-admin-navigator', 'aieoAdminNavigator', array(
                    'entries' => $this->build_admin_navigator_entries(),
                    'i18n'    => array(
                        'openLabel'    => __('Quick navigator', 'ai-eshop-optimizer'),
                        'placeholder'  => __('Search AIEO sub-tabs by name or group…', 'ai-eshop-optimizer'),
                        'noResults'    => __('No matching sub-tabs.', 'ai-eshop-optimizer'),
                        'kbdNavigate'  => __('navigate', 'ai-eshop-optimizer'),
                        'kbdOpen'      => __('open', 'ai-eshop-optimizer'),
                        'shortcutHint' => __('Open with', 'ai-eshop-optimizer'),
                    ),
                ));
            }
        }

        
        
        
        
        
        
        $is_analytics_page = ($cur_page === 'ai-eshop-optimizer');
        $is_chat_page      = ($cur_page === 'ai-eshop-chat');
        if ($is_analytics_page || $is_chat_page) {
            $dmm_css_path = AIEO_DIR . 'assets/css/dmm.css';
            $dmm_css_ver  = file_exists($dmm_css_path) ? (string) filemtime($dmm_css_path) : AIEO_VERSION;
            
            
            
            
            
            
            
            
            wp_enqueue_style(
                self::ASSETS_HANDLE,
                AIEO_URI . 'assets/css/dmm.css',
                array(),
                $dmm_css_ver
            );
            $toc_js_path = AIEO_DIR . 'assets/js/aieo-page-toc.js';
            if (file_exists($toc_js_path)) {
                wp_enqueue_script(
                    'aieo-page-toc',
                    AIEO_URI . 'assets/js/aieo-page-toc.js',
                    array(),
                    (string) filemtime($toc_js_path),
                    true
                );
            }
        }

        if (!$is_dmm_page) {
            return;
        }

        
        
        wp_enqueue_style(
            'ai-eshop-optimizer-admin',
            AIEO_URI . 'assets/css/aieo-admin-panel.css',
            array(),
            AIEO_VERSION . '.3'
        );
        
        
        $dmm_css_path = AIEO_DIR . 'assets/css/dmm.css';
        $dmm_css_ver  = file_exists($dmm_css_path) ? (string) filemtime($dmm_css_path) : AIEO_VERSION;
        wp_enqueue_style(
            self::ASSETS_HANDLE,
            AIEO_URI . 'assets/css/dmm.css',
            array('ai-eshop-optimizer-admin'),
            $dmm_css_ver
        );

        
        
        
        
        
        
        $s2_script_handles = array('select2', 'selectWoo');
        foreach ($s2_script_handles as $h) {
            if (wp_script_is($h, 'registered')) {
                wp_enqueue_script($h);
                break;
            }
        }
        $s2_style_handles = array('select2', 'selectWoo');
        foreach ($s2_style_handles as $h) {
            if (wp_style_is($h, 'registered')) {
                wp_enqueue_style($h);
                break;
            }
        }

        
        
        wp_enqueue_script('jquery-ui-sortable');

        $dmm_js_path = AIEO_DIR . 'assets/js/dmm.js';
        $dmm_js_ver  = file_exists($dmm_js_path) ? (string) filemtime($dmm_js_path) : AIEO_VERSION;
        wp_enqueue_script(
            self::ASSETS_HANDLE,
            AIEO_URI . 'assets/js/dmm.js',
            array('jquery', 'jquery-ui-sortable'),
            $dmm_js_ver,
            true
        );

        
        
        if (class_exists('AIEO_DMM_Product_Picker')) {
            AIEO_DMM_Product_Picker::enqueue_assets();
        }

        wp_localize_script(self::ASSETS_HANDLE, 'aieoDmm', array(
            'ajaxurl'  => admin_url('admin-ajax.php'),
            'nonce'    => wp_create_nonce(self::NONCE_ACTION),
            'activeTab' => $this->get_active_subtab_id(),
            'i18n'     => array(
                'confirmDelete'    => __('Are you sure you want to delete this item?', 'ai-eshop-optimizer'),
                'saving'           => __('Saving…', 'ai-eshop-optimizer'),
                'saved'            => __('Saved', 'ai-eshop-optimizer'),
                'error'            => __('An error occurred', 'ai-eshop-optimizer'),
                'processing'       => __('Processing…', 'ai-eshop-optimizer'),
                'uploadRequired'   => __('Please choose a file to upload.', 'ai-eshop-optimizer'),
                'done'             => __('Done', 'ai-eshop-optimizer'),
                'pickBrand'        => __('Pick a brand…', 'ai-eshop-optimizer'),
                'pickBrands'       => __('Pick brand(s)…', 'ai-eshop-optimizer'),
                'pickNeed'         => __('Pick a need…', 'ai-eshop-optimizer'),
                'pickNeeds'        => __('Pick needs…', 'ai-eshop-optimizer'),
                'pickCategory'     => __('Pick a category…', 'ai-eshop-optimizer'),
                'pickCategories'   => __('Pick categories…', 'ai-eshop-optimizer'),
                'searchByNameSku'  => __('Search by name or SKU…', 'ai-eshop-optimizer'),
                'searchUsers'      => __('Search users by email / login / name…', 'ai-eshop-optimizer'),
                
                'picker'           => array(
                    'deleted'    => __('deleted', 'ai-eshop-optimizer'),
                    'draft'      => __('draft', 'ai-eshop-optimizer'),
                    'variations' => __('variations', 'ai-eshop-optimizer'),
                    'searching'  => __('Searching…', 'ai-eshop-optimizer'),
                    'none'       => __('No products found.', 'ai-eshop-optimizer'),
                    'failed'     => __('Search failed.', 'ai-eshop-optimizer'),
                    'loadingV'   => __('Loading variations…', 'ai-eshop-optimizer'),
                    'noV'        => __('No variations.', 'ai-eshop-optimizer'),
                    'failV'      => __('Failed to load variations.', 'ai-eshop-optimizer'),
                    'cancel'     => __('Cancel', 'ai-eshop-optimizer'),
                    'done'       => __('Done', 'ai-eshop-optimizer'),
                    'ph'         => __('Search products by name or SKU…', 'ai-eshop-optimizer'),
                    'selOne'     => __('item selected', 'ai-eshop-optimizer'),
                    'selMany'    => __('items selected', 'ai-eshop-optimizer'),
                    'titleInc'   => __('Choose products to INCLUDE', 'ai-eshop-optimizer'),
                    'titleExc'   => __('Choose products to EXCLUDE', 'ai-eshop-optimizer'),
                    'remove'     => __('Remove', 'ai-eshop-optimizer'),
                ),
            ),
        ));

        
        $module = $this->get_module($this->get_active_subtab_id());
        if ($module) {
            $module->enqueue_admin_assets();
        }
    }

    
    public function suppress_third_party_notices() {
        if (!$this->is_dmm_page()) {
            return;
        }
        remove_all_actions('admin_notices');
        remove_all_actions('all_admin_notices');
        remove_all_actions('network_admin_notices');
        remove_all_actions('user_admin_notices');
    }

    
    private function is_dmm_page() {
        if (!is_admin()) { return false; }
        $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : '';
        return $page === self::MENU_SLUG;
    }

    
    public function ajax_save_recipe() {
        self::verify_ajax_request();

        $patch = array();
        if (isset($_POST['recipe']) && is_array($_POST['recipe'])) {
            $patch['recipe'] = map_deep(wp_unslash($_POST['recipe']), 'sanitize_text_field');
        }
        if (isset($_POST['bundle_mode'])) {
            $mode = sanitize_key(wp_unslash($_POST['bundle_mode']));
            $patch['bundle_mode'] = in_array($mode, array('full', 'rec_only'), true) ? $mode : 'full';
        }
        if (isset($_POST['pricing_mode'])) {
            $pmode = sanitize_key(wp_unslash($_POST['pricing_mode']));
            $patch['pricing_mode'] = in_array($pmode, array('reactive', 'precomputed'), true) ? $pmode : 'reactive';
        }
        
        $patch['apply_recipe_to_main_price'] = !empty($_POST['apply_recipe_to_main_price']);

        if (!empty($patch)) {
            AIEO_DMM_Settings::update($patch);
            AIEO_DMM_Cache::bump_version('*');
        }

        
        
        if (class_exists('AIEO_Recommendations_Cache')) {
            if (method_exists('AIEO_Recommendations_Cache', 'flush_all_cache')) {
                AIEO_Recommendations_Cache::flush_all_cache();
            } elseif (function_exists('wp_cache_flush_group')) {
                wp_cache_flush_group('aieo_recommendations');
            }
        }

        wp_send_json_success(array('message' => __('Recipe saved.', 'ai-eshop-optimizer')));
    }

    
    public function ajax_delete_export_job() {
        self::verify_ajax_request();

        $job_id = isset($_POST['job_id']) ? sanitize_text_field(wp_unslash($_POST['job_id'])) : '';
        if ($job_id === '') {
            wp_send_json_error(array('message' => __('Missing job id.', 'ai-eshop-optimizer')));
        }

        global $wpdb;
        $table = $wpdb->prefix . 'aieo_dmm_export_jobs';
        
        $row = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table} WHERE job_id = %s", $job_id), ARRAY_A);
        if (!$row) {
            wp_send_json_error(array('message' => __('Job not found.', 'ai-eshop-optimizer')));
        }

        
        
        
        $candidates = array();
        $params = !empty($row['params']) ? json_decode($row['params'], true) : null;
        if (is_array($params)) {
            foreach (array('path', 'xlsx_path', 'staging_path') as $k) {
                if (!empty($params[$k])) {
                    $candidates[] = (string) $params[$k];
                }
            }
        }
        if (!empty($row['filename'])) {
            
            $subdirs = array('orders', 'prices', 'logs', 'exports', 'feeds');
            foreach ($subdirs as $sub) {
                $try = AIEO_DMM::get_upload_path($sub);
                $candidates[] = trailingslashit($try['path']) . $row['filename'];
            }
        }

        $deleted_files = 0;
        foreach (array_unique($candidates) as $path) {
            if ($path !== '' && file_exists($path) && is_file($path)) {
                
                if (@unlink($path)) {
                    $deleted_files++;
                }
            }
        }

        $wpdb->delete($table, array('job_id' => $job_id), array('%s'));

        wp_send_json_success(array(
            'job_id' => $job_id,
            'files_removed' => $deleted_files,
            'message' => __('Export deleted.', 'ai-eshop-optimizer'),
        ));
    }

    
    public function ajax_save_enabled_modules() {
        self::verify_ajax_request();

        $raw = isset($_POST['enabled_modules']) && is_array($_POST['enabled_modules']) ? map_deep(wp_unslash($_POST['enabled_modules']), 'sanitize_text_field') : array();
        $out = array();
        foreach ($raw as $mid => $flag) {
            $out[sanitize_key($mid)] = !empty($flag);
        }
        AIEO_DMM_Settings::update(array('enabled_modules' => $out));
        wp_send_json_success(array('message' => __('Modules updated. Reload the page to take effect.', 'ai-eshop-optimizer')));
    }

    
    private static $iapi_module_status = array(
        'pricing'       => 'production',
        'wishlist'      => 'production',
        'waitlist'      => 'production',
        'complementary' => 'production',
        'reco'          => 'production',  
        'ratings'       => 'production',  
        'swatches'      => 'scaffold',
        'sticky_atc'    => 'scaffold',
        'side_cart'     => 'scaffold',
    );

    
    public static function is_iapi_enabled($module) {
        static $cache = array();
        $module = sanitize_key((string) $module);
        if ($module === '') { return false; }
        if (isset($cache[$module])) { return $cache[$module]; }

        $override = (string) get_option('aieo_dmm_' . $module . '_iapi_enabled', 'inherit');
        $resolved = ($override === 'yes');

        
        
        $status = isset(self::$iapi_module_status[$module])
            ? self::$iapi_module_status[$module]
            : 'unknown';
        if ($resolved && $status !== 'production') {
            $allow_scaffold = (bool) apply_filters('aieo/iapi/allow_scaffold', false, $module, $status);
            if (!$allow_scaffold) {
                $resolved = false;
                if (defined('WP_DEBUG') && WP_DEBUG
                    && !isset($GLOBALS['_aieo_iapi_warned'][$module])) {
                    $GLOBALS['_aieo_iapi_warned'][$module] = true;
                    
                    error_log(sprintf(
                        '[AIEO IAPI] Module "%s" requested IAPI activation but is marked "%s". '
                      . 'Set add_filter("aieo/iapi/allow_scaffold", "__return_true") to override (dev only).',
                        $module, $status
                    ));
                }
            }
        }

        
        $resolved = (bool) apply_filters('aieo/iapi/enabled', $resolved, $module);
        $cache[$module] = $resolved;
        return $resolved;
    }

    
    public static function get_iapi_module_statuses() {
        return self::$iapi_module_status;
    }

    
    public static function is_iapi_master_on() {
        return (bool) get_option('roosterx_iapi_enabled', false);
    }

    
    public static function verify_ajax_request() {
        check_ajax_referer(self::NONCE_ACTION, 'nonce');
        if (!current_user_can(AIEO_CAPABILITY)) {
            wp_send_json_error(array(
                'message' => __('Insufficient permissions.', 'ai-eshop-optimizer'),
            ));
        }
    }

    
    public static function get_upload_path($subdir = '') {
        $upload = wp_upload_dir();
        $base   = trailingslashit($upload['basedir']) . 'aieo-dmm';
        $url    = trailingslashit($upload['baseurl']) . 'aieo-dmm';
        if ($subdir !== '') {
            $subdir = trim($subdir, "/\\");
            $base  .= '/' . $subdir;
            $url   .= '/' . $subdir;
        }
        if (!file_exists($base)) {
            wp_mkdir_p($base);
            
            $index = $base . '/index.html';
            if (!file_exists($index)) {
                file_put_contents($index, '');
            }
        }
        return array('path' => $base, 'url' => $url);
    }

    
    public static function get_exports_path() {
        $upload = wp_upload_dir();
        $base   = trailingslashit($upload['basedir']) . 'exports';
        $url    = trailingslashit($upload['baseurl']) . 'exports';
        if (!file_exists($base)) {
            wp_mkdir_p($base);
            $index = $base . '/index.html';
            if (!file_exists($index)) {
                file_put_contents($index, '');
            }
        }
        return array('path' => $base, 'url' => $url);
    }
}
