<?php

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

class AIEO_DMM_Tools extends AIEO_DMM_Module_Base {

    
    const OPTION_KEY = 'aieo_dmm_tools_settings';

    
    const OPTION_CAPS = 'aieo_dmm_per_page_caps';

    public function get_id()       { return 'tools'; }
    public function get_label()    { return __('Reports &amp; Lookups', 'ai-eshop-optimizer'); }
    public function get_priority() { return 10; } 
    public function get_group()    { return 'tools'; }

    
    public function get_tools() {
        return array(
            'brand_metabox_enhance' => array(
                'label'   => __('Searchable + alphabetised Brands metabox', 'ai-eshop-optimizer'),
                'desc'    => __('On the product edit page, sort the Brands list A→Z and add a live search filter above it. Fixes the WP/Woo metabox\'s popular-first-then-by-ID order which is painful with hundreds of brands.', 'ai-eshop-optimizer'),
                'default' => 1,
            ),
        );
    }

    public function register_hooks() {
        add_action('wp_ajax_aieo_dmm_tools_save',           array($this, 'ajax_save'));
        add_action('wp_ajax_aieo_dmm_tools_save_branding',  array($this, 'ajax_save_branding'));
        add_action('wp_ajax_aieo_dmm_tools_save_caps',      array($this, 'ajax_save_caps'));
        add_action('wp_ajax_aieo_dmm_tools_save_quiet',     array($this, 'ajax_save_quiet'));

        
        
        
        
        if (is_admin()) {
            add_filter('get_user_option_edit_orders_per_page',     array($this, 'cap_orders_per_page'));
            add_filter('get_user_option_edit_shop_order_per_page', array($this, 'cap_orders_per_page'));
            add_filter('get_user_option_edit_product_per_page',    array($this, 'cap_products_per_page'));
        }

        
        
        add_action('wp_ajax_aieo_dmm_tools_sku_lookup',     array($this, 'ajax_sku_lookup'));
        add_action('wp_ajax_aieo_dmm_tools_barcode_lookup', array($this, 'ajax_barcode_lookup'));

        
        add_action('wp_ajax_aieo_dmm_tools_export_brand_margins', array($this, 'ajax_export_brand_margins'));
        add_action('wp_ajax_aieo_dmm_tools_import_brand_margins', array($this, 'ajax_import_brand_margins'));
        add_action('wp_ajax_aieo_dmm_tools_apply_cogs',           array($this, 'ajax_apply_cogs'));

        
        
        add_action('wp_ajax_aieo_dmm_offer_effectiveness',        array($this, 'ajax_offer_effectiveness'));
        add_action('wp_ajax_aieo_dmm_offer_effectiveness_export', array($this, 'ajax_offer_effectiveness_export'));

        
        
        if ($this->is_enabled('brand_metabox_enhance')) {
            add_action('admin_enqueue_scripts', array($this, 'enqueue_brand_metabox_tool'));
        }
    }

    
    public function get_settings() {
        $stored = get_option(self::OPTION_KEY, array());
        if (!is_array($stored)) { $stored = array(); }
        $defaults = array();
        foreach ($this->get_tools() as $slug => $info) {
            $defaults[$slug] = !empty($info['default']) ? 1 : 0;
        }
        return array_merge($defaults, $stored);
    }

    public function is_enabled($slug) {
        $cfg = $this->get_settings();
        return !empty($cfg[$slug]);
    }

    
    public function get_caps() {
        $stored = get_option(self::OPTION_CAPS, array());
        if (!is_array($stored)) { $stored = array(); }
        $defaults = array(
            'orders_max'   => 200,
            'products_max' => 200,
        );
        $merged = array_merge($defaults, $stored);
        $merged['orders_max']   = max(0, (int) $merged['orders_max']);
        $merged['products_max'] = max(0, (int) $merged['products_max']);
        return $merged;
    }

    
    public function cap_orders_per_page($result) {
        $caps = $this->get_caps();
        $max  = (int) $caps['orders_max'];
        if ($max <= 0) { return $result; }
        $val = (int) $result;
        if ($val <= 0) { return $result; } 
        return $val > $max ? $max : $val;
    }

    
    public function cap_products_per_page($result) {
        $caps = $this->get_caps();
        $max  = (int) $caps['products_max'];
        if ($max <= 0) { return $result; }
        $val = (int) $result;
        if ($val <= 0) { return $result; }
        return $val > $max ? $max : $val;
    }

    
    public function ajax_save_caps() {
        AIEO_DMM::verify_ajax_request();
        if (!current_user_can('install_plugins')) {
            wp_send_json_error(array('message' => __('Insufficient permissions.', 'ai-eshop-optimizer')));
        }
        $orders   = isset($_POST['orders_max'])   ? max(0, (int) $_POST['orders_max'])   : 200;
        $products = isset($_POST['products_max']) ? max(0, (int) $_POST['products_max']) : 200;
        
        $orders   = min(10000, $orders);
        $products = min(10000, $products);
        update_option(self::OPTION_CAPS, array(
            'orders_max'   => $orders,
            'products_max' => $products,
        ), false);
        wp_send_json_success(array(
            'message'      => __('Per-page caps saved. Operators see the new ceiling on their next list-table render.', 'ai-eshop-optimizer'),
            'orders_max'   => $orders,
            'products_max' => $products,
        ));
    }

    public function enqueue_brand_metabox_tool($hook) {
        
        
        $screen = function_exists('get_current_screen') ? get_current_screen() : null;
        if (!$screen || $screen->post_type !== 'product') { return; }
        if (!in_array($hook, array('post.php', 'post-new.php'), true)) { return; }

        $handle = 'aieo-tools-brand-metabox';
        wp_enqueue_script(
            $handle,
            plugins_url('assets/js/aieo-tools-brand-metabox.js', AIEO_FILE),
            array(),
            defined('AIEO_VERSION') ? AIEO_VERSION : '1.0',
            true
        );
        wp_localize_script($handle, 'aieoToolsBrand', array(
            'placeholder' => __('Search brands…', 'ai-eshop-optimizer'),
            'noResults'   => __('No brands match.', 'ai-eshop-optimizer'),
        ));
    }

    public function ajax_save() {
        AIEO_DMM::verify_ajax_request();
        $patch = array();
        $tools = $this->get_tools();
        foreach ($tools as $slug => $info) {
            $patch[$slug] = !empty($_POST[$slug]) ? 1 : 0;
        }
        update_option(self::OPTION_KEY, $patch, false);
        wp_send_json_success(array('message' => __('Tools settings saved.', 'ai-eshop-optimizer')));
    }

    
    public function ajax_save_quiet() {
        AIEO_DMM::verify_ajax_request();
        $norm = static function ($v, $def) {
            $v = trim((string) $v);
            if (preg_match('/^(\d{1,2}):(\d{2})$/', $v, $m) && (int) $m[1] <= 23 && (int) $m[2] <= 59) {
                return sprintf('%02d:%02d', (int) $m[1], (int) $m[2]);
            }
            return $def;
        };
        $start = $norm(isset($_POST['quiet_start']) ? wp_unslash($_POST['quiet_start']) : '', '22:00');
        $end   = $norm(isset($_POST['quiet_end'])   ? wp_unslash($_POST['quiet_end'])   : '', '09:00');
        AIEO_DMM_Settings::update(array(
            'contact_quiet_start' => $start,
            'contact_quiet_end'   => $end,
        ));
        wp_send_json_success(array(
            'message'     => __('Quiet hours saved — applied to web-push now, and to newsletters / non-transactional email going forward.', 'ai-eshop-optimizer'),
            'quiet_start' => $start,
            'quiet_end'   => $end,
        ));
    }

    
    private function render_quiet_hours_card($nonce, $ajax) {
        $start = (string) AIEO_DMM_Settings::get('contact_quiet_start', '22:00');
        $end   = (string) AIEO_DMM_Settings::get('contact_quiet_end',   '09:00');
        echo '<div class="aieo-dmm-card">';
        echo '<h3 style="margin:0 0 4px;">' . esc_html__('Quiet hours — customer-contact window', 'ai-eshop-optimizer') . '</h3>';
        echo '<p class="description" style="margin:0 0 10px;font-size:12px;max-width:760px;">'
            . esc_html__('No non-transactional message is sent during these hours (Europe/Athens). This is the GLOBAL window — it governs web-push now and newsletters / marketing email going forward. Transactional mail (order confirmations etc.) is never affected. Set the two times equal to disable quiet hours.', 'ai-eshop-optimizer')
            . '</p>';
        echo '<p style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;">';
        echo '<label>' . esc_html__('From', 'ai-eshop-optimizer') . ' <input type="time" id="aieo-quiet-start" value="' . esc_attr($start) . '" style="width:120px;"></label>';
        echo '<label>' . esc_html__('To', 'ai-eshop-optimizer')   . ' <input type="time" id="aieo-quiet-end" value="' . esc_attr($end) . '" style="width:120px;"></label>';
        echo '<button type="button" class="button button-primary" id="aieo-quiet-save">' . esc_html__('Save quiet hours', 'ai-eshop-optimizer') . '</button>';
        echo '<span id="aieo-quiet-status" style="color:#646970;font-size:13px;"></span>';
        echo '</p>';
        $script = sprintf(
            "<script>(function(){var b=document.getElementById('aieo-quiet-save');if(!b)return;"
          . "b.addEventListener('click',function(){var s=document.getElementById('aieo-quiet-status');s.textContent=%s;"
          . "var fd=new FormData();fd.append('action','aieo_dmm_tools_save_quiet');fd.append('nonce',%s);"
          . "fd.append('quiet_start',document.getElementById('aieo-quiet-start').value);"
          . "fd.append('quiet_end',document.getElementById('aieo-quiet-end').value);"
          . "fetch(%s,{method:'POST',credentials:'same-origin',body:fd}).then(function(r){return r.json();})"
          . ".then(function(j){s.textContent=(j&&j.data&&j.data.message)?j.data.message:%s;})"
          . ".catch(function(){s.textContent=%s;});});})();</script>",
            wp_json_encode(__('Saving…', 'ai-eshop-optimizer')),
            wp_json_encode($nonce),
            wp_json_encode($ajax),
            wp_json_encode(__('Saved.', 'ai-eshop-optimizer')),
            wp_json_encode(__('Save failed.', 'ai-eshop-optimizer'))
        );
        echo $script; 
        echo '</div>';
    }

    public function render_subtab() {
        $cfg   = $this->get_settings();
        $tools = $this->get_tools();
        $nonce = wp_create_nonce(AIEO_DMM::NONCE_ACTION);
        $ajax  = admin_url('admin-ajax.php');

        echo '<div class="aieo-dmm-section">';
        echo '<h2>' . esc_html__('Tools', 'ai-eshop-optimizer') . '</h2>';
        echo '<p class="description">'
            . esc_html__('Optional admin-side conveniences. Each tool has its own on/off toggle — they\'re independent of the rest of AIEO and add no overhead when disabled.', 'ai-eshop-optimizer')
            . '</p>';

        
        
        $this->render_branding_card($nonce, $ajax);

        
        $this->render_brand_margins_card($nonce, $ajax);

        
        
        
        
        
        
        
        
        $this->render_per_page_caps_card($nonce, $ajax);

        
        
        $this->render_quiet_hours_card($nonce, $ajax);

        foreach ($tools as $slug => $info) {
            $on = !empty($cfg[$slug]);
            echo '<div class="aieo-dmm-card">';
            echo '<div style="display:flex;align-items:flex-start;gap:14px;">';
            echo '<label class="aieo-dmm-toggle" style="flex-shrink:0;margin-top:2px;">';
            echo '<input type="checkbox" data-aieo-tool-slug="' . esc_attr($slug) . '"' . ($on ? ' checked' : '') . '>';
            echo '<span class="aieo-dmm-toggle-slider"></span>';
            echo '</label>';
            echo '<div style="flex:1;">';
            echo '<h3 style="margin:0 0 4px;">' . esc_html((string) $info['label']) . '</h3>';
            echo '<p class="description" style="margin:0;font-size:12px;">' . esc_html((string) $info['desc']) . '</p>';
            echo '</div>';
            echo '</div>';
            echo '</div>';
        }

        echo '<p><button type="button" class="button button-primary" id="aieo-tools-save">'
            . esc_html__('Save tools', 'ai-eshop-optimizer') . '</button>';
        echo ' <span id="aieo-tools-status" style="margin-left:10px;color:#646970;font-size:13px;"></span></p>';

        
        
        
        
        

        
        
        echo '<style>
            .aieo-dmm-toggle{position:relative;display:inline-block;width:44px;height:22px;}
            .aieo-dmm-toggle input{opacity:0;width:0;height:0;}
            .aieo-dmm-toggle-slider{position:absolute;cursor:pointer;inset:0;background:#cbd5e1;border-radius:22px;transition:.2s;}
            .aieo-dmm-toggle-slider:before{position:absolute;content:"";height:18px;width:18px;left:2px;bottom:2px;background:white;border-radius:50%;transition:.2s;}
            .aieo-dmm-toggle input:checked + .aieo-dmm-toggle-slider{background:#15803d;}
            .aieo-dmm-toggle input:checked + .aieo-dmm-toggle-slider:before{transform:translateX(22px);}
        </style>';

        echo '<script>(function(){
            var btn = document.getElementById("aieo-tools-save");
            var status = document.getElementById("aieo-tools-status");
            if (!btn) return;
            btn.addEventListener("click", function(){
                var fd = new FormData();
                fd.set("action", "aieo_dmm_tools_save");
                fd.set("nonce", "' . esc_js($nonce) . '");
                document.querySelectorAll("[data-aieo-tool-slug]").forEach(function(inp){
                    if (inp.checked) fd.set(inp.getAttribute("data-aieo-tool-slug"), "1");
                });
                status.style.color = "#646970";
                status.textContent = "' . esc_js(__('Saving…', 'ai-eshop-optimizer')) . '";
                fetch("' . esc_js($ajax) . '", {method:"POST", credentials:"same-origin", body:fd})
                    .then(function(r){return r.json();})
                    .then(function(j){
                        if (j && j.success) {
                            status.style.color = "#15803d";
                            status.textContent = j.data.message + " " + "' . esc_js(__('Reload any open product editor to apply.', 'ai-eshop-optimizer')) . '";
                        } else {
                            status.style.color = "#b91c1c";
                            status.textContent = (j && j.data && j.data.message) || "Save failed.";
                        }
                    });
            });
        })();</script>';

        
        
        
        $this->render_offer_effectiveness_card($nonce, $ajax);

        
        $this->render_lookup_cards($nonce, $ajax);

        echo '</div>';
    }

    
    private function render_offer_effectiveness_card($nonce, $ajax) {
        echo '<div class="aieo-dmm-card" style="margin-top:18px;">';
        echo '<h3 style="margin:0 0 4px;">' . esc_html__('Offer effectiveness — monthly breakdown', 'ai-eshop-optimizer') . '</h3>';
        echo '<p class="description" style="margin:0 0 10px;font-size:12px;">'
            . esc_html__('Real P&L per offer per month. "Applied" = the value handed to the customer (gift retail × qty, discount in € forgone, etc.). "Cost" = what it actually cost us (COGS for gifts, the would-have-been carrier rate for free-shipping, the same € amount for plain discounts). "Net" = applied minus cost — the indicative revenue impact. Free-shipping rows show "Pending" until the resolver back-fills the carrier cost (runs nightly at 03:30, or run it manually above).', 'ai-eshop-optimizer')
            . '</p>';

        echo '<p style="margin:0 0 10px;display:flex;flex-wrap:wrap;gap:14px;align-items:end;">';

        echo '<label>' . esc_html__('Period:', 'ai-eshop-optimizer') . ' ';
        echo '<select id="aieo-oe-months">';
        echo '<option value="current">' . esc_html__('Current month', 'ai-eshop-optimizer') . '</option>';
        echo '<option value="last">' . esc_html__('Last month', 'ai-eshop-optimizer') . '</option>';
        foreach (array(3, 6, 12, 24, 36) as $m) {
            $sel = $m === 12 ? ' selected' : '';
            
            $label = sprintf(_n('Last %d month', 'Last %d months', $m, 'ai-eshop-optimizer'), $m);
            echo '<option value="' . $m . '"' . $sel . '>' . esc_html($label) . '</option>'; 
        }
        echo '</select></label>';

        echo '<label>' . esc_html__('Offer type:', 'ai-eshop-optimizer') . ' ';
        echo '<select id="aieo-oe-type">';
        echo '<option value="">' . esc_html__('All', 'ai-eshop-optimizer') . '</option>';
        echo '<option value="free_shipping">' . esc_html__('Free shipping', 'ai-eshop-optimizer') . '</option>';
        echo '<option value="gift">' . esc_html__('Gift', 'ai-eshop-optimizer') . '</option>';
        echo '<option value="discount">' . esc_html__('Discount', 'ai-eshop-optimizer') . '</option>';
        echo '</select></label>';

        echo '<label>' . esc_html__('Channel:', 'ai-eshop-optimizer') . ' ';
        echo '<select id="aieo-oe-channel">';
        echo '<option value="">' . esc_html__('All', 'ai-eshop-optimizer') . '</option>';
        echo '</select></label>';

        echo '<label>' . esc_html__('Shipping method:', 'ai-eshop-optimizer') . ' ';
        echo '<select id="aieo-oe-method">';
        echo '<option value="">' . esc_html__('All', 'ai-eshop-optimizer') . '</option>';
        echo '</select></label>';

        echo '<label>' . esc_html__('Shipping zone:', 'ai-eshop-optimizer') . ' ';
        echo '<select id="aieo-oe-zone">';
        echo '<option value="">' . esc_html__('All', 'ai-eshop-optimizer') . '</option>';
        echo '</select></label>';

        echo '<label>' . esc_html__('Group by:', 'ai-eshop-optimizer') . ' ';
        echo '<select id="aieo-oe-group">';
        echo '<option value="month_type">' . esc_html__('Month × Offer type', 'ai-eshop-optimizer') . '</option>';
        echo '<option value="month_type_channel">' . esc_html__('Month × Offer type × Channel', 'ai-eshop-optimizer') . '</option>';
        echo '<option value="month_type_method">' . esc_html__('Month × Offer type × Shipping method', 'ai-eshop-optimizer') . '</option>';
        echo '<option value="month_type_zone">' . esc_html__('Month × Offer type × Shipping zone', 'ai-eshop-optimizer') . '</option>';
        echo '<option value="month_method_zone">' . esc_html__('Month × Method × Zone (free-shipping focus)', 'ai-eshop-optimizer') . '</option>';
        echo '<option value="month">' . esc_html__('Month total', 'ai-eshop-optimizer') . '</option>';
        echo '<option value="type">' . esc_html__('Offer type total', 'ai-eshop-optimizer') . '</option>';
        echo '<option value="method">' . esc_html__('Shipping method total', 'ai-eshop-optimizer') . '</option>';
        echo '<option value="zone">' . esc_html__('Shipping zone total', 'ai-eshop-optimizer') . '</option>';
        echo '</select></label>';

        echo '<button type="button" class="button" id="aieo-oe-refresh">'
            . esc_html__('Refresh', 'ai-eshop-optimizer') . '</button>';
        echo '<button type="button" class="button button-primary" id="aieo-oe-export">'
            . esc_html__('Export XLSX', 'ai-eshop-optimizer') . '</button>';

        echo '</p>';

        echo '<div id="aieo-oe-summary" style="margin:8px 0;font-size:12px;color:#374151;"></div>';
        echo '<div id="aieo-oe-table-wrap" style="margin-top:8px;"></div>';

        echo '<script>(function(){
            var ajax  = "' . esc_js($ajax) . '";
            var nonce = "' . esc_js($nonce) . '";

            var monthsSel  = document.getElementById("aieo-oe-months");
            var typeSel    = document.getElementById("aieo-oe-type");
            var channelSel = document.getElementById("aieo-oe-channel");
            var methodSel  = document.getElementById("aieo-oe-method");
            var zoneSel    = document.getElementById("aieo-oe-zone");
            var groupSel   = document.getElementById("aieo-oe-group");
            var refreshBtn = document.getElementById("aieo-oe-refresh");
            var exportBtn  = document.getElementById("aieo-oe-export");
            var summary    = document.getElementById("aieo-oe-summary");
            var tableWrap  = document.getElementById("aieo-oe-table-wrap");

            function escapeHtml(s){var d=document.createElement("div");d.appendChild(document.createTextNode(String(s==null?"":s)));return d.innerHTML;}
            function fmtEur(n){
                var v = parseFloat(n);
                if (isNaN(v)) return "—";
                return v.toLocaleString("el-GR", {minimumFractionDigits:2, maximumFractionDigits:2}) + " €";
            }
            function fmtInt(n){
                var v = parseInt(n, 10);
                if (isNaN(v)) return "0";
                return v.toLocaleString("el-GR");
            }

            function buildParams(){
                var p = new URLSearchParams();
                p.set("nonce", nonce);
                p.set("months", monthsSel.value);
                p.set("offer_type", typeSel.value);
                p.set("channel", channelSel.value);
                p.set("shipping_method", methodSel.value);
                p.set("shipping_zone", zoneSel.value);
                p.set("group_by", groupSel.value);
                return p;
            }

            function fetchData(){
                refreshBtn.disabled = true;
                tableWrap.innerHTML = "<p style=\"color:#646970;font-size:12px;\">' . esc_js(__('Loading…', 'ai-eshop-optimizer')) . '</p>";
                var fd = new FormData();
                fd.set("action", "aieo_dmm_offer_effectiveness");
                buildParams().forEach(function(v,k){ fd.set(k, v); });
                fetch(ajax, {method:"POST", credentials:"same-origin", body:fd})
                    .then(function(r){ return r.json(); })
                    .then(function(j){
                        refreshBtn.disabled = false;
                        if (!j || !j.success) {
                            tableWrap.innerHTML = "<p style=\"color:#b91c1c;\">" + escapeHtml((j && j.data && j.data.message) || "Error") + "</p>";
                            return;
                        }
                        renderTable(j.data);
                        populateChannelOptions(j.data.channels || []);
                        populateOptions(methodSel, j.data.methods || []);
                        populateOptions(zoneSel,   j.data.zones   || []);
                    })
                    .catch(function(){
                        refreshBtn.disabled = false;
                        tableWrap.innerHTML = "<p style=\"color:#b91c1c;\">' . esc_js(__('Network error.', 'ai-eshop-optimizer')) . '</p>";
                    });
            }

            function populateChannelOptions(channels){ populateOptions(channelSel, channels); }
            function populateOptions(selectEl, values){
                if (!selectEl) return;
                var current = selectEl.value;
                var html = "<option value=\"\">' . esc_js(__('All', 'ai-eshop-optimizer')) . '</option>";
                values.forEach(function(c){
                    if (!c) return;
                    var sel = (c === current) ? " selected" : "";
                    html += "<option value=\"" + escapeHtml(c) + "\"" + sel + ">" + escapeHtml(c) + "</option>";
                });
                selectEl.innerHTML = html;
            }

            function renderTable(d){
                var rows = d.rows || [];
                var totals = d.totals || {fires:0, applied_total:0, cost_total:0, pending:0};

                summary.innerHTML =
                    "<strong>' . esc_js(__('Totals:', 'ai-eshop-optimizer')) . '</strong> " +
                    "' . esc_js(__('Fires', 'ai-eshop-optimizer')) . ' " + fmtInt(totals.fires) +
                    " &nbsp;|&nbsp; ' . esc_js(__('Applied', 'ai-eshop-optimizer')) . ' " + fmtEur(totals.applied_total) +
                    " &nbsp;|&nbsp; ' . esc_js(__('Cost', 'ai-eshop-optimizer')) . ' " + fmtEur(totals.cost_total) +
                    " &nbsp;|&nbsp; ' . esc_js(__('Net', 'ai-eshop-optimizer')) . ' " + fmtEur(totals.applied_total - totals.cost_total) +
                    " &nbsp;|&nbsp; ' . esc_js(__('Pending cost rows', 'ai-eshop-optimizer')) . ' " + fmtInt(totals.pending);

                if (!rows.length) {
                    tableWrap.innerHTML = "<p style=\"color:#646970;font-size:12px;\">' . esc_js(__('No attribution rows match the current filters. If you just enabled the module, place a few orders or run the retrospective free-shipping scan above.', 'ai-eshop-optimizer')) . '</p>";
                    return;
                }

                var cols = d.columns || [];
                var html = "<table class=\"wp-list-table widefat fixed striped\"><thead><tr>";
                cols.forEach(function(col){
                    html += "<th>" + escapeHtml(col.label) + "</th>";
                });
                html += "</tr></thead><tbody>";
                rows.forEach(function(row){
                    html += "<tr>";
                    cols.forEach(function(col){
                        var v = row[col.key];
                        if (col.fmt === "currency")  { html += "<td style=\"text-align:right;font-variant-numeric:tabular-nums;\">" + fmtEur(v) + "</td>"; }
                        else if (col.fmt === "integer") { html += "<td style=\"text-align:right;font-variant-numeric:tabular-nums;\">" + fmtInt(v) + "</td>"; }
                        else if (col.fmt === "net") {
                            var net = parseFloat(v) || 0;
                            var color = net >= 0 ? "#15803d" : "#b91c1c";
                            html += "<td style=\"text-align:right;font-variant-numeric:tabular-nums;color:" + color + ";\">" + fmtEur(net) + "</td>";
                        }
                        else { html += "<td>" + escapeHtml(v) + "</td>"; }
                    });
                    html += "</tr>";
                });
                html += "</tbody></table>";
                tableWrap.innerHTML = html;
            }

            refreshBtn.addEventListener("click", fetchData);
            monthsSel.addEventListener("change", fetchData);
            typeSel.addEventListener("change", fetchData);
            channelSel.addEventListener("change", fetchData);
            methodSel.addEventListener("change", fetchData);
            zoneSel.addEventListener("change", fetchData);
            groupSel.addEventListener("change", fetchData);

            exportBtn.addEventListener("click", function(){
                var p = buildParams();
                p.set("action", "aieo_dmm_offer_effectiveness_export");
                window.location.href = ajax + "?" + p.toString();
            });

            // Auto-load on first render.
            fetchData();
        })();</script>';
        echo '</div>';
    }

    
    public function ajax_offer_effectiveness() {
        AIEO_DMM::verify_ajax_request();
        if (!current_user_can('manage_woocommerce')) {
            wp_send_json_error(array('message' => __('Insufficient permissions.', 'ai-eshop-optimizer')));
        }
        $payload = $this->compute_offer_effectiveness($_POST);
        wp_send_json_success($payload);
    }

    
    public function ajax_offer_effectiveness_export() {
        AIEO_DMM::verify_ajax_request();
        if (!current_user_can('manage_woocommerce')) {
            wp_die(__('Insufficient permissions.', 'ai-eshop-optimizer')); 
        }
        $payload = $this->compute_offer_effectiveness($_GET);

        if (!class_exists('AIEO_DMM_XLSX_Writer')) {
            wp_die(esc_html__('XLSX writer missing.', 'ai-eshop-optimizer'));
        }

        $writer = new AIEO_DMM_XLSX_Writer('Offer effectiveness');

        
        $headers = array();
        foreach ($payload['columns'] as $col) {
            $headers[] = $col['label'];
        }
        $writer->add_header_row($headers);

        
        $col_formats = array();
        foreach ($payload['columns'] as $i => $col) {
            if ($col['fmt'] === 'currency' || $col['fmt'] === 'net') {
                $col_formats[$i] = 'currency';
            } elseif ($col['fmt'] === 'integer') {
                $col_formats[$i] = 'integer';
            } else {
                $col_formats[$i] = 'string';
            }
        }
        foreach ($payload['rows'] as $row) {
            $cells = array();
            foreach ($payload['columns'] as $col) {
                $cells[] = isset($row[$col['key']]) ? $row[$col['key']] : '';
            }
            $writer->add_row($cells, $col_formats);
        }

        
        $totals_row = array();
        foreach ($payload['columns'] as $i => $col) {
            if ($i === 0) {
                $totals_row[] = __('TOTAL', 'ai-eshop-optimizer');
            } elseif ($col['key'] === 'fires') {
                $totals_row[] = $payload['totals']['fires'];
            } elseif ($col['key'] === 'applied_total') {
                $totals_row[] = $payload['totals']['applied_total'];
            } elseif ($col['key'] === 'cost_total') {
                $totals_row[] = $payload['totals']['cost_total'];
            } elseif ($col['key'] === 'net') {
                $totals_row[] = $payload['totals']['applied_total'] - $payload['totals']['cost_total'];
            } elseif ($col['key'] === 'pending') {
                $totals_row[] = $payload['totals']['pending'];
            } else {
                $totals_row[] = '';
            }
        }
        $writer->add_row($totals_row, $col_formats);

        $months   = (int) $payload['filters']['months'];
        $type_tag = $payload['filters']['offer_type'] !== '' ? '-' . $payload['filters']['offer_type'] : '';
        $filename = 'offer-effectiveness-' . $months . 'mo' . $type_tag . '-' . gmdate('Y-m-d') . '.xlsx';
        $writer->stream_download($filename);
    }

    
    private function period_window_sql($period_value, $date_col) {
        $period = (string) $period_value;
        if ($period === 'current') {
            return array(
                'sql'   => "{$date_col} >= DATE_FORMAT(NOW(), '%Y-%m-01')",
                'tag'   => 'current-month',
                'label' => 'current',
                'months_for_compat' => 1,
            );
        }
        if ($period === 'last') {
            return array(
                'sql'   => "{$date_col} >= DATE_SUB(DATE_FORMAT(NOW(), '%Y-%m-01'), INTERVAL 1 MONTH)
                            AND {$date_col} <  DATE_FORMAT(NOW(), '%Y-%m-01')",
                'tag'   => 'last-month',
                'label' => 'last',
                'months_for_compat' => 1,
            );
        }
        $n = max(1, min(60, (int) $period));
        return array(
            'sql'   => "{$date_col} >= DATE_SUB(NOW(), INTERVAL {$n} MONTH)",
            'tag'   => $n . 'mo',
            'label' => (string) $n,
            'months_for_compat' => $n,
        );
    }

    
    private function compute_offer_effectiveness($input) {
        global $wpdb;
        $table = $wpdb->prefix . 'aieo_dmm_offer_attributions';

        $period_in  = isset($input['months']) ? sanitize_text_field((string) $input['months']) : '12';
        $period     = $this->period_window_sql($period_in, 'fired_at');
        $months     = $period['months_for_compat']; 
        $offer_type = isset($input['offer_type']) ? sanitize_key((string) $input['offer_type']) : '';
        $channel    = isset($input['channel'])    ? sanitize_text_field((string) $input['channel']) : '';
        $group_by   = isset($input['group_by'])   ? sanitize_key((string) $input['group_by']) : 'month_type';
        $valid_groups = array(
            'month_type', 'month_type_channel', 'month_type_method', 'month_type_zone',
            'month_method_zone', 'month', 'type', 'method', 'zone',
        );
        if (!in_array($group_by, $valid_groups, true)) {
            $group_by = 'month_type';
        }

        
        $exists = (string) $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $table));
        if ($exists !== $table) {
            return array(
                'rows' => array(), 'columns' => array(), 'channels' => array(),
                'totals' => array('fires'=>0,'applied_total'=>0,'cost_total'=>0,'pending'=>0),
                'filters' => array('months'=>$months, 'offer_type'=>$offer_type, 'channel'=>$channel, 'group_by'=>$group_by),
            );
        }

        
        
        
        switch ($group_by) {
            case 'month_type_channel':
                $group_select = "DATE_FORMAT(fired_at, '%Y-%m') AS month_key, offer_type, entry_channel";
                $group_clause = 'month_key, offer_type, entry_channel';
                $columns = array(
                    array('key'=>'month_key',     'label'=>__('Month', 'ai-eshop-optimizer'),       'fmt'=>'string'),
                    array('key'=>'offer_type',    'label'=>__('Offer type', 'ai-eshop-optimizer'),  'fmt'=>'string'),
                    array('key'=>'entry_channel', 'label'=>__('Channel', 'ai-eshop-optimizer'),     'fmt'=>'string'),
                );
                break;
            case 'month_type_method':
                $group_select = "DATE_FORMAT(fired_at, '%Y-%m') AS month_key, offer_type, COALESCE(shipping_method, '—') AS shipping_method";
                $group_clause = 'month_key, offer_type, shipping_method';
                $columns = array(
                    array('key'=>'month_key',       'label'=>__('Month', 'ai-eshop-optimizer'),            'fmt'=>'string'),
                    array('key'=>'offer_type',      'label'=>__('Offer type', 'ai-eshop-optimizer'),       'fmt'=>'string'),
                    array('key'=>'shipping_method', 'label'=>__('Shipping method', 'ai-eshop-optimizer'),  'fmt'=>'string'),
                );
                break;
            case 'month_type_zone':
                $group_select = "DATE_FORMAT(fired_at, '%Y-%m') AS month_key, offer_type, COALESCE(shipping_zone, '—') AS shipping_zone";
                $group_clause = 'month_key, offer_type, shipping_zone';
                $columns = array(
                    array('key'=>'month_key',     'label'=>__('Month', 'ai-eshop-optimizer'),           'fmt'=>'string'),
                    array('key'=>'offer_type',    'label'=>__('Offer type', 'ai-eshop-optimizer'),      'fmt'=>'string'),
                    array('key'=>'shipping_zone', 'label'=>__('Shipping zone', 'ai-eshop-optimizer'),   'fmt'=>'string'),
                );
                break;
            case 'month_method_zone':
                
                $group_select = "DATE_FORMAT(fired_at, '%Y-%m') AS month_key, COALESCE(shipping_method, '—') AS shipping_method, COALESCE(shipping_zone, '—') AS shipping_zone";
                $group_clause = 'month_key, shipping_method, shipping_zone';
                $columns = array(
                    array('key'=>'month_key',       'label'=>__('Month', 'ai-eshop-optimizer'),            'fmt'=>'string'),
                    array('key'=>'shipping_method', 'label'=>__('Shipping method', 'ai-eshop-optimizer'),  'fmt'=>'string'),
                    array('key'=>'shipping_zone',   'label'=>__('Shipping zone', 'ai-eshop-optimizer'),    'fmt'=>'string'),
                );
                break;
            case 'method':
                $group_select = "COALESCE(shipping_method, '—') AS shipping_method";
                $group_clause = 'shipping_method';
                $columns = array(
                    array('key'=>'shipping_method', 'label'=>__('Shipping method', 'ai-eshop-optimizer'), 'fmt'=>'string'),
                );
                break;
            case 'zone':
                $group_select = "COALESCE(shipping_zone, '—') AS shipping_zone";
                $group_clause = 'shipping_zone';
                $columns = array(
                    array('key'=>'shipping_zone', 'label'=>__('Shipping zone', 'ai-eshop-optimizer'), 'fmt'=>'string'),
                );
                break;
            case 'month':
                $group_select = "DATE_FORMAT(fired_at, '%Y-%m') AS month_key";
                $group_clause = 'month_key';
                $columns = array(
                    array('key'=>'month_key', 'label'=>__('Month', 'ai-eshop-optimizer'), 'fmt'=>'string'),
                );
                break;
            case 'type':
                $group_select = "offer_type";
                $group_clause = 'offer_type';
                $columns = array(
                    array('key'=>'offer_type', 'label'=>__('Offer type', 'ai-eshop-optimizer'), 'fmt'=>'string'),
                );
                break;
            case 'month_type':
            default:
                $group_select = "DATE_FORMAT(fired_at, '%Y-%m') AS month_key, offer_type";
                $group_clause = 'month_key, offer_type';
                $columns = array(
                    array('key'=>'month_key',  'label'=>__('Month', 'ai-eshop-optimizer'),      'fmt'=>'string'),
                    array('key'=>'offer_type', 'label'=>__('Offer type', 'ai-eshop-optimizer'), 'fmt'=>'string'),
                );
                break;
        }

        
        
        if ($group_by === 'month_method_zone' && $offer_type === '') {
            $offer_type = 'free_shipping';
        }

        
        $columns[] = array('key'=>'fires',         'label'=>__('Fires', 'ai-eshop-optimizer'),         'fmt'=>'integer');
        $columns[] = array('key'=>'applied_total', 'label'=>__('Applied (€)', 'ai-eshop-optimizer'),   'fmt'=>'currency');
        $columns[] = array('key'=>'cost_total',    'label'=>__('Cost (€)', 'ai-eshop-optimizer'),      'fmt'=>'currency');
        $columns[] = array('key'=>'net',           'label'=>__('Net (€)', 'ai-eshop-optimizer'),       'fmt'=>'net');
        $columns[] = array('key'=>'pending',       'label'=>__('Pending cost', 'ai-eshop-optimizer'),  'fmt'=>'integer');

        
        
        
        $where  = array();
        $params = array();
        $where[] = '(' . $period['sql'] . ')';
        if ($offer_type !== '' && in_array($offer_type, array('free_shipping','gift','discount','customer_pricing'), true)) {
            $where[]  = 'offer_type = %s';
            $params[] = $offer_type;
        }
        if ($channel !== '') {
            $where[]  = 'entry_channel = %s';
            $params[] = $channel;
        }
        $f_method = isset($input['shipping_method']) ? sanitize_text_field((string) $input['shipping_method']) : '';
        $f_zone   = isset($input['shipping_zone'])   ? sanitize_text_field((string) $input['shipping_zone'])   : '';
        if ($f_method !== '') {
            $where[]  = 'shipping_method = %s';
            $params[] = $f_method;
        }
        if ($f_zone !== '') {
            $where[]  = 'shipping_zone = %s';
            $params[] = $f_zone;
        }
        $where_sql = $where ? ('WHERE ' . implode(' AND ', $where)) : '';

        $sql = "SELECT {$group_select},
                       COUNT(*) AS fires,
                       SUM(applied_value) AS applied_total,
                       SUM(COALESCE(actual_cost, 0)) AS cost_total,
                       SUM(actual_cost IS NULL) AS pending
                FROM {$table}
                {$where_sql}
                GROUP BY {$group_clause}
                ORDER BY " . $this->order_clause_for_group($group_by);

        $prepared = $wpdb->prepare($sql, $params);
        $rows_raw = $wpdb->get_results($prepared, ARRAY_A);
        if (!is_array($rows_raw)) { $rows_raw = array(); }

        $rows = array();
        $totals = array('fires'=>0, 'applied_total'=>0.0, 'cost_total'=>0.0, 'pending'=>0);
        foreach ($rows_raw as $r) {
            $fires   = (int) $r['fires'];
            $applied = (float) $r['applied_total'];
            $cost    = (float) $r['cost_total'];
            $pending = (int) $r['pending'];
            $row = array(
                'fires'         => $fires,
                'applied_total' => round($applied, 2),
                'cost_total'    => round($cost, 2),
                'net'           => round($applied - $cost, 2),
                'pending'       => $pending,
            );
            if (isset($r['month_key']))       { $row['month_key']       = $r['month_key']; }
            if (isset($r['offer_type']))      { $row['offer_type']      = $r['offer_type']; }
            if (isset($r['entry_channel']))   { $row['entry_channel']   = $r['entry_channel'] !== '' ? $r['entry_channel'] : '—'; }
            if (isset($r['shipping_method'])) { $row['shipping_method'] = $r['shipping_method'] !== '' ? $r['shipping_method'] : '—'; }
            if (isset($r['shipping_zone']))   { $row['shipping_zone']   = $r['shipping_zone']   !== '' ? $r['shipping_zone']   : '—'; }
            $rows[] = $row;

            $totals['fires']         += $fires;
            $totals['applied_total'] += $applied;
            $totals['cost_total']    += $cost;
            $totals['pending']       += $pending;
        }
        $totals['applied_total'] = round($totals['applied_total'], 2);
        $totals['cost_total']    = round($totals['cost_total'], 2);

        
        
        
        
        $period_clause = $period['sql'];
        $channels = $wpdb->get_col(
            "SELECT DISTINCT entry_channel FROM {$table}
             WHERE ({$period_clause}) AND entry_channel <> ''
             ORDER BY entry_channel ASC"
        );
        if (!is_array($channels)) { $channels = array(); }

        $methods = $wpdb->get_col(
            "SELECT DISTINCT shipping_method FROM {$table}
             WHERE ({$period_clause}) AND shipping_method IS NOT NULL AND shipping_method <> ''
             ORDER BY shipping_method ASC"
        );
        if (!is_array($methods)) { $methods = array(); }

        $zones = $wpdb->get_col(
            "SELECT DISTINCT shipping_zone FROM {$table}
             WHERE ({$period_clause}) AND shipping_zone IS NOT NULL AND shipping_zone <> ''
             ORDER BY shipping_zone ASC"
        );
        if (!is_array($zones)) { $zones = array(); }

        return array(
            'rows'     => $rows,
            'columns'  => $columns,
            'totals'   => $totals,
            'channels' => $channels,
            'methods'  => $methods,
            'zones'    => $zones,
            'filters'  => array(
                'months'          => $months,
                'offer_type'      => $offer_type,
                'channel'         => $channel,
                'shipping_method' => isset($input['shipping_method']) ? sanitize_text_field((string) $input['shipping_method']) : '',
                'shipping_zone'   => isset($input['shipping_zone'])   ? sanitize_text_field((string) $input['shipping_zone'])   : '',
                'group_by'        => $group_by,
            ),
        );
    }

    private function order_clause_for_group($group_by) {
        switch ($group_by) {
            case 'month_type_channel': return 'month_key DESC, offer_type ASC, entry_channel ASC';
            case 'month_type_method':  return 'month_key DESC, offer_type ASC, shipping_method ASC';
            case 'month_type_zone':    return 'month_key DESC, offer_type ASC, shipping_zone ASC';
            case 'month_method_zone':  return 'month_key DESC, shipping_method ASC, shipping_zone ASC';
            case 'method':             return 'shipping_method ASC';
            case 'zone':               return 'shipping_zone ASC';
            case 'month':              return 'month_key DESC';
            case 'type':               return 'offer_type ASC';
            case 'month_type':
            default:                   return 'month_key DESC, offer_type ASC';
        }
    }

    
    private function render_branding_card($nonce, $ajax) {
        $current = AIEO_DMM::get_menu_title();
        echo '<div class="aieo-dmm-card">';
        echo '<h3>' . esc_html__('Admin menu branding', 'ai-eshop-optimizer') . '</h3>';
        echo '<p class="description">'
            . sprintf(
                
                esc_html__('Custom label for the admin sidebar pill (and the page title). Defaults to %s — set it to "Femme Fatale e-shop Manager" or any per-client wording. Takes effect on the next admin page load.', 'ai-eshop-optimizer'),
                '<code>' . esc_html(AIEO_DMM::MENU_TITLE_DEFAULT) . '</code>'
            )
            . '</p>';
        $margin = AIEO_DMM::get_gross_margin_pct();
        $fs     = AIEO_DMM::get_free_shipping_threshold();
        $ops    = AIEO_DMM::get_ops_cost_monthly();
        echo '<table class="form-table">';
        echo '<tr><th scope="row"><label for="aieo-tools-menu-title">' . esc_html__('Menu title', 'ai-eshop-optimizer') . '</label></th>';
        echo '<td>';
        echo '<input type="text" id="aieo-tools-menu-title" class="regular-text" value="' . esc_attr($current) . '" maxlength="60" placeholder="' . esc_attr(AIEO_DMM::MENU_TITLE_DEFAULT) . '">';
        echo '<p class="description">' . esc_html__('Leave empty to fall back to the default.', 'ai-eshop-optimizer') . '</p>';
        echo '</td></tr>';
        echo '<tr><th scope="row"><label for="aieo-tools-gross-margin">' . esc_html__('Gross profit margin (%)', 'ai-eshop-optimizer') . '</label></th>';
        echo '<td>';
        echo '<input type="number" id="aieo-tools-gross-margin" class="small-text" min="1" max="99" step="1" value="' . esc_attr((string) round($margin)) . '"> %';
        echo '<p class="description">' . esc_html__('Rough average gross margin on product sales (default 60). Used to estimate profit per order and the break-even free-shipping threshold in Fulfillment → Delivery Statistics.', 'ai-eshop-optimizer') . '</p>';
        echo '</td></tr>';
        echo '<tr><th scope="row"><label for="aieo-tools-ops-cost">' . esc_html__('Operations costs (€ / month)', 'ai-eshop-optimizer') . '</label></th>';
        echo '<td>';
        echo '€ <input type="number" id="aieo-tools-ops-cost" class="small-text" min="0" step="50" value="' . esc_attr((string) (float) $ops) . '"> ' . esc_html__('/ month', 'ai-eshop-optimizer');
        echo '<p class="description">' . esc_html__('Your fixed MONTHLY overhead — hosting, wages, tooling, everything EXCEPT ad spend (e.g. 8000). The ROI Wizard charges a prorated share against the report period (per-day rate × days in the range), so ROI reflects true business profit, not just revenue minus ad spend.', 'ai-eshop-optimizer') . '</p>';
        echo '</td></tr>';
        echo '<tr><th scope="row"><label for="aieo-tools-free-ship">' . esc_html__('Free-shipping threshold (€)', 'ai-eshop-optimizer') . '</label></th>';
        echo '<td>';
        echo '€ <input type="number" id="aieo-tools-free-ship" class="small-text" min="0" step="0.5" value="' . esc_attr((string) (float) $fs) . '">';
        echo '<p class="description">' . esc_html__('Your CURRENT order-subtotal bar for free shipping (default 35). The Delivery Statistics “Free-ship ≥” column recommends raising it to this + (courier cost ÷ margin), so the extra turnover covers the courier cost you absorb.', 'ai-eshop-optimizer') . '</p>';
        echo '</td></tr></table>';
        echo '<p><button type="button" class="button button-primary" id="aieo-tools-branding-save">'
            . esc_html__('Save', 'ai-eshop-optimizer') . '</button>';
        echo ' <span id="aieo-tools-branding-status" style="margin-left:10px;color:#646970;font-size:13px;"></span></p>';

        echo '<script>(function(){
            var inp = document.getElementById("aieo-tools-menu-title");
            var btn = document.getElementById("aieo-tools-branding-save");
            var status = document.getElementById("aieo-tools-branding-status");
            if (!btn) return;
            btn.addEventListener("click", function(){
                var fd = new FormData();
                fd.set("action", "aieo_dmm_tools_save_branding");
                fd.set("nonce", "' . esc_js($nonce) . '");
                fd.set("menu_title", inp.value);
                var marginEl = document.getElementById("aieo-tools-gross-margin");
                if (marginEl) { fd.set("gross_margin", marginEl.value); }
                var fsEl = document.getElementById("aieo-tools-free-ship");
                if (fsEl) { fd.set("free_ship_threshold", fsEl.value); }
                var opsEl = document.getElementById("aieo-tools-ops-cost");
                if (opsEl) { fd.set("ops_cost_monthly", opsEl.value); }
                status.style.color = "#646970";
                status.textContent = "' . esc_js(__('Saving…', 'ai-eshop-optimizer')) . '";
                fetch("' . esc_js($ajax) . '", {method:"POST", body:fd, credentials:"same-origin"})
                    .then(function(r){return r.json();})
                    .then(function(j){
                        if (j && j.success) {
                            status.style.color = "#15803d";
                            status.textContent = j.data.message;
                            setTimeout(function(){ window.location.reload(); }, 800);
                        } else {
                            status.style.color = "#b91c1c";
                            status.textContent = (j && j.data && j.data.message) || "Save failed.";
                        }
                    });
            });
        })();</script>';
        echo '</div>';
    }

    public function ajax_save_branding() {
        AIEO_DMM::verify_ajax_request();
        $title = isset($_POST['menu_title']) ? sanitize_text_field((string) wp_unslash($_POST['menu_title'])) : '';
        $title = mb_substr(trim($title), 0, 60);
        update_option(AIEO_DMM::MENU_TITLE_OPTION, $title, false);

        if (isset($_POST['gross_margin']) && $_POST['gross_margin'] !== '') {
            $m = (float) $_POST['gross_margin'];
            if ($m < 1)  { $m = 1; }
            if ($m > 99) { $m = 99; }
            update_option(AIEO_DMM::GROSS_MARGIN_OPTION, $m, false);
        }

        if (isset($_POST['free_ship_threshold']) && $_POST['free_ship_threshold'] !== '') {
            $fs = (float) $_POST['free_ship_threshold'];
            if ($fs < 0) { $fs = 0; }
            update_option(AIEO_DMM::FREE_SHIP_THRESHOLD_OPTION, $fs, false);
        }

        if (isset($_POST['ops_cost_monthly']) && $_POST['ops_cost_monthly'] !== '') {
            $oc = (float) $_POST['ops_cost_monthly'];
            if ($oc < 0) { $oc = 0; }
            update_option(AIEO_DMM::OPS_COST_MONTHLY_OPTION, $oc, false);
        }

        wp_send_json_success(array(
            'message'         => __('Saved. Reloading to refresh the admin menu…', 'ai-eshop-optimizer'),
            'effective_title' => AIEO_DMM::get_menu_title(),
            'gross_margin'    => AIEO_DMM::get_gross_margin_pct(),
        ));
    }

    

    
    private static function cogs_feature_enabled() {
        try {
            $cls = 'Automattic\\WooCommerce\\Internal\\CostOfGoodsSold\\CostOfGoodsSoldController';
            if (function_exists('wc_get_container') && class_exists($cls)) {
                $ctrl = wc_get_container()->get($cls);
                if (is_object($ctrl) && method_exists($ctrl, 'feature_is_enabled')) {
                    return (bool) $ctrl->feature_is_enabled();
                }
            }
        } catch (\Throwable $e) {  }
        return false;
    }

    
    private static function fmt_pct($v) {
        if ($v === null || $v === '') { return ''; }
        return rtrim(rtrim(number_format((float) $v, 2, '.', ''), '0'), '.');
    }

    private function render_brand_margins_card($nonce, $ajax) {
        $default_margin = (int) round(AIEO_DMM::get_gross_margin_pct());
        $cogs_on        = self::cogs_feature_enabled();
        $export_url     = $ajax . '?action=aieo_dmm_tools_export_brand_margins&nonce=' . rawurlencode($nonce);

        echo '<div class="aieo-dmm-card">';
        echo '<h3>' . esc_html__('Brand margins & Cost of Goods', 'ai-eshop-optimizer') . '</h3>';
        echo '<p class="description" style="max-width:880px;">'
            . sprintf(
                
                esc_html__('Set a gross profit margin per brand (Brands → edit → Catalog tab). Brands without one inherit the store default (%d%%). Export to review/bulk-edit margins in a spreadsheet, re-import to apply, then push them into WooCommerce Cost of Goods — cost = regular price × (1 − margin).', 'ai-eshop-optimizer'),
                $default_margin
            )
            . '</p>';

        echo '<p>';
        echo '<a class="button" href="' . esc_url($export_url) . '">' . esc_html__('Export brand margins (CSV)', 'ai-eshop-optimizer') . '</a> ';
        echo '<input type="file" id="aieo-bm-file" accept=".csv,text/csv,text/plain" style="display:none;">';
        echo '<button type="button" class="button" id="aieo-bm-import-pick">' . esc_html__('Import margins (CSV)…', 'ai-eshop-optimizer') . '</button> ';
        echo '<span id="aieo-bm-import-status" style="margin-left:8px;color:#646970;font-size:13px;"></span>';
        echo '</p>';
        echo '<p class="description">' . esc_html__('CSV columns: brand_id, brand, slug, products, margin_percent. Matched by brand_id (then slug). A blank margin_percent = inherit the default.', 'ai-eshop-optimizer') . '</p>';

        echo '<hr style="margin:14px 0;border:none;border-top:1px solid #e5e7eb;">';

        if (!$cogs_on) {
            echo '<p style="color:#b91c1c;">' . esc_html__('WooCommerce “Cost of Goods Sold” is not enabled — turn it on in WooCommerce → Settings → Advanced → Features before applying.', 'ai-eshop-optimizer') . '</p>';
        }
        echo '<p>';
        echo '<button type="button" class="button button-primary" id="aieo-bm-apply"' . ($cogs_on ? '' : ' disabled') . '>' . esc_html__('Apply margins → Cost of Goods', 'ai-eshop-optimizer') . '</button> ';
        echo '<span id="aieo-bm-apply-status" style="margin-left:10px;color:#646970;font-size:13px;"></span>';
        echo '</p>';
        echo '<p class="description">' . esc_html__('Sets Cost of Goods only on products that don’t have one yet (never overwrites existing/manual costs), and refreshes the product-vitals cost. Runs in batches and fires product-save hooks — run it off-peak. Re-runnable.', 'ai-eshop-optimizer') . '</p>';

        echo '<script>(function(){
            var ajax = ' . wp_json_encode($ajax) . ', nonce = ' . wp_json_encode($nonce) . ';
            function post(action, extra){ var fd=new FormData(); fd.set("action",action); fd.set("nonce",nonce); if(extra){Object.keys(extra).forEach(function(k){fd.set(k,extra[k]);});} return fetch(ajax,{method:"POST",body:fd,credentials:"same-origin"}).then(function(r){return r.json();}); }
            var fileEl=document.getElementById("aieo-bm-file"), pickBtn=document.getElementById("aieo-bm-import-pick"), impStatus=document.getElementById("aieo-bm-import-status");
            pickBtn && pickBtn.addEventListener("click", function(){ fileEl.click(); });
            fileEl && fileEl.addEventListener("change", function(){
                if(!fileEl.files.length) return;
                var fd=new FormData(); fd.set("action","aieo_dmm_tools_import_brand_margins"); fd.set("nonce",nonce); fd.set("file", fileEl.files[0]);
                impStatus.style.color="#646970"; impStatus.textContent=' . wp_json_encode(__('Importing…', 'ai-eshop-optimizer')) . ';
                fetch(ajax,{method:"POST",body:fd,credentials:"same-origin"}).then(function(r){return r.json();}).then(function(j){
                    if(j&&j.success){ impStatus.style.color="#15803d"; impStatus.textContent=j.data.message; } else { impStatus.style.color="#b91c1c"; impStatus.textContent=(j&&j.data&&j.data.message)||"error"; }
                    fileEl.value="";
                }).catch(function(){ impStatus.style.color="#b91c1c"; impStatus.textContent="network error"; });
            });
            var applyBtn=document.getElementById("aieo-bm-apply"), applyStatus=document.getElementById("aieo-bm-apply-status");
            applyBtn && applyBtn.addEventListener("click", function(){
                if(!confirm(' . wp_json_encode(__('Apply brand margins to Cost of Goods for products without a cost? Runs in batches; can take a while.', 'ai-eshop-optimizer')) . ')) return;
                applyBtn.disabled=true; var offset=0, updated=0, skipped=0;
                function step(){
                    post("aieo_dmm_tools_apply_cogs", {offset:offset}).then(function(j){
                        if(!j||!j.success){ applyStatus.style.color="#b91c1c"; applyStatus.textContent=(j&&j.data&&j.data.message)||"error"; applyBtn.disabled=false; return; }
                        var d=j.data; updated+=d.updated; skipped+=d.skipped; offset=d.next_offset;
                        applyStatus.style.color="#646970"; applyStatus.textContent="… "+Math.min(offset,d.total)+"/"+d.total+" · set "+updated+" · skipped "+skipped;
                        if(d.done){ applyStatus.style.color="#15803d"; applyStatus.textContent=' . wp_json_encode(__('Done — set', 'ai-eshop-optimizer')) . '+" "+updated+", "+' . wp_json_encode(__('skipped (already costed)', 'ai-eshop-optimizer')) . '+" "+skipped+"."; applyBtn.disabled=false; }
                        else { step(); }
                    }).catch(function(){ applyStatus.style.color="#b91c1c"; applyStatus.textContent="network error"; applyBtn.disabled=false; });
                }
                step();
            });
        })();</script>';
        echo '</div>';
    }

    
    public function ajax_export_brand_margins() {
        AIEO_DMM::verify_ajax_request();
        if (!class_exists('AIEO_DMM_Brand_Extras_Data')) { wp_die(esc_html__('Brand Extras unavailable.', 'ai-eshop-optimizer')); }
        $tax     = 'product_brand';
        $terms   = get_terms(array('taxonomy' => $tax, 'hide_empty' => false));
        nocache_headers();
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename=brand-margins-' . gmdate('Ymd-His') . '.csv');
        $out = fopen('php://output', 'w');
        fwrite($out, "\xEF\xBB\xBF"); 
        fputcsv($out, array('brand_id', 'brand', 'slug', 'products', 'margin_percent', 'effective_percent'));
        if (!is_wp_error($terms)) {
            foreach ($terms as $t) {
                $row = AIEO_DMM_Brand_Extras_Data::get($tax, $t->term_id);
                $eff = AIEO_DMM_Brand_Extras_Data::effective_margin_pct($t->term_id, $tax);
                fputcsv($out, array(
                    (int) $t->term_id,
                    $t->name,
                    $t->slug,
                    (int) $t->count,
                    self::fmt_pct($row['gross_margin']),
                    self::fmt_pct($eff),
                ));
            }
        }
        fclose($out);
        exit;
    }

    
    public function ajax_import_brand_margins() {
        AIEO_DMM::verify_ajax_request();
        if (empty($_FILES['file']['tmp_name']) || !is_uploaded_file($_FILES['file']['tmp_name'])) {
            wp_send_json_error(array('message' => __('No file uploaded.', 'ai-eshop-optimizer')));
        }
        $fh = fopen($_FILES['file']['tmp_name'], 'r'); 
        if (!$fh) { wp_send_json_error(array('message' => __('Could not read the file.', 'ai-eshop-optimizer'))); }

        $tax = 'product_brand';
        $updated = 0; $cleared = 0; $unmatched = 0; $rownum = 0;
        $col = array();
        while (($cells = fgetcsv($fh)) !== false) {
            $rownum++;
            if ($rownum === 1) { $cells[0] = preg_replace('/^\xEF\xBB\xBF/', '', (string) $cells[0]); }
            
            if ($rownum === 1 && !ctype_digit(trim((string) ($cells[0] ?? '')))) {
                foreach ($cells as $i => $h) { $col[strtolower(trim((string) $h))] = $i; }
                continue;
            }
            $cell = static function ($name, $pos) use ($cells, $col) {
                if (isset($col[$name]) && isset($cells[$col[$name]])) { return (string) $cells[$col[$name]]; }
                return isset($cells[$pos]) ? (string) $cells[$pos] : '';
            };
            $bid    = (int) $cell('brand_id', 0);
            $slug   = trim($cell('slug', 2));
            $margin = trim($cell('margin_percent', 4));

            $term = null;
            if ($bid > 0) { $t = get_term($bid, $tax); if ($t && !is_wp_error($t)) { $term = $t; } }
            if (!$term && $slug !== '') { $t = get_term_by('slug', $slug, $tax); if ($t) { $term = $t; } }
            if (!$term) { $unmatched++; continue; }

            $margin = str_replace(array('%', ','), array('', '.'), $margin);
            if ($margin === '') {
                AIEO_DMM_Brand_Extras_Data::save($tax, (int) $term->term_id, array('gross_margin' => null));
                $cleared++;
            } else {
                AIEO_DMM_Brand_Extras_Data::save($tax, (int) $term->term_id, array('gross_margin' => (float) $margin));
                $updated++;
            }
        }
        fclose($fh);
        wp_send_json_success(array(
            'message' => sprintf(
                
                __('Imported — %1$d updated, %2$d set to inherit, %3$d unmatched.', 'ai-eshop-optimizer'),
                $updated, $cleared, $unmatched
            ),
        ));
    }

    
    public function ajax_apply_cogs() {
        AIEO_DMM::verify_ajax_request();
        if (!self::cogs_feature_enabled()) {
            wp_send_json_error(array('message' => __('Cost of Goods Sold is not enabled in WooCommerce.', 'ai-eshop-optimizer')));
        }
        if (!function_exists('wc_get_product') || !class_exists('AIEO_DMM_Brand_Extras_Data')) {
            wp_send_json_error(array('message' => __('WooCommerce / Brand Extras unavailable.', 'ai-eshop-optimizer')));
        }
        $offset = isset($_POST['offset']) ? max(0, (int) $_POST['offset']) : 0;
        @set_time_limit(0); 
        self::suppress_bulk_product_save_hooks();
        wp_send_json_success(self::apply_cogs_batch($offset, 150));
    }

    
    public static function suppress_bulk_product_save_hooks() {
        $deny = apply_filters('aieo_cogs_bulk_hook_denylist', array(
            
            'Recommendations_Cache', 'Recompute_Queue', 'Core_Brand_Vitals', 'AIEO_DMM_Product_FP',
            'AIEO_DMM_Navigator', 'Embedding_Manager',
            
            'DgoraWcas', 'FiboFilters', 'AutomateWoo', 'AIOSEO', 'PixelYourSite', 'Pods',
        ));
        $hooks = array('save_post_product', 'woocommerce_update_product', 'woocommerce_new_product', 'woocommerce_process_product_meta', 'save_post', 'updated_post_meta');
        foreach ($hooks as $h) {
            if (empty($GLOBALS['wp_filter'][$h]) || empty($GLOBALS['wp_filter'][$h]->callbacks)) { continue; }
            foreach ($GLOBALS['wp_filter'][$h]->callbacks as $prio => $cbs) {
                foreach ($cbs as $key => $cb) {
                    $fn  = isset($cb['function']) ? $cb['function'] : null;
                    $cls = is_array($fn) ? (is_object($fn[0]) ? get_class($fn[0]) : (string) $fn[0]) : (is_string($fn) ? $fn : '');
                    if ($cls === '') { continue; }
                    foreach ($deny as $needle) {
                        if (stripos($cls, $needle) !== false) { unset($GLOBALS['wp_filter'][$h]->callbacks[$prio][$key]); break; }
                    }
                }
            }
        }
    }

    
    public static function apply_cogs_batch($offset, $batch = 150) {
        global $wpdb;
        $offset = max(0, (int) $offset);
        $batch  = max(1, (int) $batch);

        $total = (int) $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type IN ('product','product_variation') AND post_status IN ('publish','private')");
        $ids   = $wpdb->get_col($wpdb->prepare(
            "SELECT ID FROM {$wpdb->posts} WHERE post_type IN ('product','product_variation') AND post_status IN ('publish','private') ORDER BY ID ASC LIMIT %d OFFSET %d",
            $batch, $offset
        ));

        $vitals      = $wpdb->prefix . 'aieo_core_product_vitals';
        $have_vitals = ((string) $wpdb->get_var("SHOW TABLES LIKE '{$vitals}'") === $vitals);

        $updated = 0; $skipped = 0;
        foreach ((array) $ids as $pid) {
            $pid     = (int) $pid;
            $product = wc_get_product($pid);
            if (!$product || $product->is_type('variable')) { $skipped++; continue; } 
            $existing = $product->get_cogs_value();
            if ($existing !== null && (float) $existing > 0) { $skipped++; continue; } 
            $base = (float) $product->get_regular_price();
            if ($base <= 0) { $base = (float) $product->get_price(); }
            if ($base <= 0) { $skipped++; continue; }
            $margin = AIEO_DMM_Brand_Extras_Data::margin_pct_for_product($pid);
            $cost   = round($base * (1 - $margin / 100), 2);
            if ($cost <= 0) { $skipped++; continue; }
            $product->set_cogs_value($cost);
            $product->save();
            if ($have_vitals) {
                $wpdb->query($wpdb->prepare("UPDATE `{$vitals}` SET cost = %f WHERE product_id = %d", $cost, $pid));
            }
            $updated++;
        }

        $next = $offset + $batch;
        $done = (count((array) $ids) < $batch) || $next >= $total;
        return array(
            'updated'     => $updated,
            'skipped'     => $skipped,
            'next_offset' => $next,
            'total'       => $total,
            'done'        => $done,
        );
    }

    
    private function render_per_page_caps_card($nonce, $ajax) {
        $caps     = $this->get_caps();
        $is_admin = current_user_can('install_plugins');
        $disabled = $is_admin ? '' : ' disabled';
        $wrap_cls = 'aieo-dmm-card' . ($is_admin ? '' : ' aieo-caps-locked');

        echo '<div class="' . esc_attr($wrap_cls) . '" style="position:relative;">';
        echo '<h3>' . esc_html__('Admin list-table per-page caps', 'ai-eshop-optimizer') . '</h3>';
        echo '<p class="description">'
            . esc_html__('Hard ceiling on the "Items per page" Screen Options for the All Orders and All Products admin lists. Operators below the cap keep their personal value untouched; only those above it get clamped on the next list render. Stops 500–600 setups from grinding the admin on every refresh. Set a cap to 0 to disable enforcement for that screen.', 'ai-eshop-optimizer')
            . '</p>';
        echo '<table class="form-table">';
        echo '<tr>';
        echo '<th scope="row"><label for="aieo-tools-orders-max">' . esc_html__('Max orders per page', 'ai-eshop-optimizer') . '</label></th>';
        echo '<td><input type="number" id="aieo-tools-orders-max" min="0" max="10000" step="1" value="' . esc_attr((string) (int) $caps['orders_max']) . '" class="small-text"' . $disabled . '> ';
        echo '<span class="description">' . esc_html__('Applies to the HPOS Orders screen + legacy edit.php?post_type=shop_order.', 'ai-eshop-optimizer') . '</span></td>';
        echo '</tr>';
        echo '<tr>';
        echo '<th scope="row"><label for="aieo-tools-products-max">' . esc_html__('Max products per page', 'ai-eshop-optimizer') . '</label></th>';
        echo '<td><input type="number" id="aieo-tools-products-max" min="0" max="10000" step="1" value="' . esc_attr((string) (int) $caps['products_max']) . '" class="small-text"' . $disabled . '> ';
        echo '<span class="description">' . esc_html__('Applies to edit.php?post_type=product.', 'ai-eshop-optimizer') . '</span></td>';
        echo '</tr>';
        echo '</table>';
        echo '<p><button type="button" class="button button-primary" id="aieo-tools-caps-save"' . $disabled . '>'
            . esc_html__('Save caps', 'ai-eshop-optimizer') . '</button>';
        echo ' <span id="aieo-tools-caps-status" style="margin-left:10px;color:#646970;font-size:13px;"></span></p>';

        
        
        
        if (!$is_admin) {
            echo '<div class="aieo-caps-lock-overlay" aria-hidden="true">';
            echo   '<div class="aieo-caps-lock-content">';
            echo     '<div class="aieo-caps-lock-icon">';
            echo       '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">';
            echo         '<path d="M6 10V8a6 6 0 1112 0v2M5 10h14a1 1 0 011 1v9a1 1 0 01-1 1H5a1 1 0 01-1-1v-9a1 1 0 011-1z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>';
            echo       '</svg>';
            echo     '</div>';
            echo     '<div>';
            echo       '<strong>' . esc_html__('Administrator only', 'ai-eshop-optimizer') . '</strong><br>';
            echo       '<span>' . esc_html__('Ask the site administrator to adjust these caps. The current values above are read-only.', 'ai-eshop-optimizer') . '</span>';
            echo     '</div>';
            echo   '</div>';
            echo '</div>';
        }

        
        
        
        
        static $caps_css_printed = false;
        if (!$caps_css_printed) {
            $caps_css_printed = true;
            echo '<style id="aieo-caps-lock-css">
                .aieo-caps-locked .form-table input,
                .aieo-caps-locked .form-table .description,
                .aieo-caps-locked h3,
                .aieo-caps-locked > p.description { filter: blur(1.2px); opacity: 0.85; user-select: none; }
                .aieo-caps-locked #aieo-tools-caps-save { pointer-events: none; opacity: 0.6; }
                .aieo-caps-lock-overlay {
                    position: absolute; inset: 0;
                    background: linear-gradient(135deg, rgba(102,126,234,0.10) 0%, rgba(118,75,162,0.25) 100%);
                    -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
                    border-radius: inherit;
                    display: flex; align-items: center; justify-content: center;
                    padding: 24px;
                    z-index: 5;
                    animation: aieoCapsFade 0.3s ease;
                }
                @keyframes aieoCapsFade { from { opacity: 0; } to { opacity: 1; } }
                .aieo-caps-lock-content {
                    display: flex; align-items: center; gap: 14px;
                    background: rgba(255,255,255,0.92);
                    border: 1px solid rgba(118,75,162,0.25);
                    border-radius: 10px;
                    padding: 14px 18px;
                    box-shadow: 0 6px 20px rgba(0,0,0,0.10);
                    max-width: 520px;
                    color: #2d2d33;
                }
                .aieo-caps-lock-content strong { font-size: 14px; color: #4f3a8a; }
                .aieo-caps-lock-content span  { font-size: 13px; color: #555; line-height: 1.45; }
                .aieo-caps-lock-icon { flex-shrink: 0; width: 36px; height: 36px; border-radius: 50%; background: linear-gradient(135deg,#667eea,#764ba2); color:#fff; display:flex; align-items:center; justify-content:center; box-shadow: 0 4px 10px rgba(118,75,162,0.30); }
            </style>';
        }

        
        
        
        if ($is_admin) {
            echo '<script>(function(){
                var btn = document.getElementById("aieo-tools-caps-save");
                var status = document.getElementById("aieo-tools-caps-status");
                var o = document.getElementById("aieo-tools-orders-max");
                var p = document.getElementById("aieo-tools-products-max");
                if (!btn) return;
                btn.addEventListener("click", function(){
                    var fd = new FormData();
                    fd.set("action", "aieo_dmm_tools_save_caps");
                    fd.set("nonce", "' . esc_js($nonce) . '");
                    fd.set("orders_max", o.value);
                    fd.set("products_max", p.value);
                    status.style.color = "#646970";
                    status.textContent = "' . esc_js(__('Saving…', 'ai-eshop-optimizer')) . '";
                    fetch("' . esc_js($ajax) . '", {method:"POST", body:fd, credentials:"same-origin"})
                        .then(function(r){return r.json();})
                        .then(function(j){
                            if (j && j.success) {
                                status.style.color = "#15803d";
                                status.textContent = j.data.message;
                            } else {
                                status.style.color = "#b91c1c";
                                status.textContent = (j && j.data && j.data.message) || "Save failed.";
                            }
                        });
                });
            })();</script>';
        }
        echo '</div>';
    }

    
    private function render_lookup_cards($nonce, $ajax) {
        
        echo '<div class="aieo-dmm-card">';
        echo '<h3>' . esc_html__('SKU → Parent Product ID lookup', 'ai-eshop-optimizer') . '</h3>';
        echo '<p class="description">'
            . esc_html__('Enter SKUs (comma-separated or one per line) to get their parent product IDs. Useful for finding parent IDs of variations.', 'ai-eshop-optimizer')
            . '</p>';
        echo '<table class="form-table"><tr>';
        echo '<th scope="row"><label for="aieo-tools-sku-input">' . esc_html__('SKUs', 'ai-eshop-optimizer') . '</label></th>';
        echo '<td>';
        echo '<textarea id="aieo-tools-sku-input" rows="6" class="large-text" placeholder="' . esc_attr("Enter SKUs here...\nSKU-001\nSKU-002, SKU-003\nSKU-004") . '"></textarea>';
        echo '<p class="description">' . esc_html__('Separated by commas or new lines.', 'ai-eshop-optimizer') . '</p>';
        echo '</td></tr></table>';
        echo '<p><button type="button" class="button button-primary" id="aieo-tools-sku-btn">'
            . esc_html__('Look up parent IDs', 'ai-eshop-optimizer') . '</button></p>';
        echo '<div id="aieo-tools-sku-results" style="display:none;margin-top:12px;"></div>';
        echo '</div>';

        
        echo '<div class="aieo-dmm-card">';
        echo '<h3>' . esc_html__('Barcode → Parent Product ID lookup', 'ai-eshop-optimizer') . '</h3>';
        echo '<p class="description">'
            . sprintf(
                
                esc_html__('Enter barcodes (comma-separated or one per line). Searches the %s meta field (WooCommerce 9.x GTIN).', 'ai-eshop-optimizer'),
                '<code>_global_unique_id</code>'
            )
            . '</p>';
        echo '<table class="form-table"><tr>';
        echo '<th scope="row"><label for="aieo-tools-barcode-input">' . esc_html__('Barcodes', 'ai-eshop-optimizer') . '</label></th>';
        echo '<td>';
        echo '<textarea id="aieo-tools-barcode-input" rows="6" class="large-text" placeholder="' . esc_attr("Enter barcodes here...\n1234567890123\n9876543210987, 5555555555555\n1111111111111") . '"></textarea>';
        echo '<p class="description">' . esc_html__('Separated by commas or new lines.', 'ai-eshop-optimizer') . '</p>';
        echo '</td></tr></table>';
        echo '<p><button type="button" class="button button-primary" id="aieo-tools-barcode-btn">'
            . esc_html__('Look up parent IDs', 'ai-eshop-optimizer') . '</button></p>';
        echo '<div id="aieo-tools-barcode-results" style="display:none;margin-top:12px;"></div>';
        echo '</div>';

        
        echo '<script>(function(){
            var ajaxUrl = "' . esc_js($ajax) . '";
            var nonce = "' . esc_js($nonce) . '";
            function escapeHtml(s){var d=document.createElement("div");d.appendChild(document.createTextNode(String(s||"")));return d.innerHTML;}
            function runLookup(kind){
                var inp = document.getElementById("aieo-tools-" + kind + "-input");
                var btn = document.getElementById("aieo-tools-" + kind + "-btn");
                var box = document.getElementById("aieo-tools-" + kind + "-results");
                var raw = (inp.value || "").trim();
                if (!raw) { alert("' . esc_js(__('Please enter at least one value.', 'ai-eshop-optimizer')) . '"); return; }
                btn.disabled = true; btn.textContent = "' . esc_js(__('Looking up…', 'ai-eshop-optimizer')) . '";
                var fd = new FormData();
                fd.set("action", "aieo_dmm_tools_" + kind + "_lookup");
                fd.set("nonce", nonce);
                fd.set("input", raw);
                fetch(ajaxUrl, {method:"POST", body:fd, credentials:"same-origin"})
                    .then(function(r){return r.json();})
                    .then(function(j){
                        btn.disabled = false; btn.textContent = "' . esc_js(__('Look up parent IDs', 'ai-eshop-optimizer')) . '";
                        if (!j || !j.success) { alert((j && j.data && j.data.message) || "' . esc_js(__('An error occurred.', 'ai-eshop-optimizer')) . '"); return; }
                        renderResults(box, kind, j.data);
                    })
                    .catch(function(){ btn.disabled = false; btn.textContent = "' . esc_js(__('Look up parent IDs', 'ai-eshop-optimizer')) . '"; alert("' . esc_js(__('Network error.', 'ai-eshop-optimizer')) . '"); });
            }
            function renderResults(box, kind, d){
                var headerLabel = (kind === "sku") ? "SKU" : "Barcode";
                var html = "";
                html += "<div class=\"notice notice-info\" style=\"margin:0 0 12px;padding:8px 10px;\">";
                html += "<strong>' . esc_js(__('Found:', 'ai-eshop-optimizer')) . '</strong> " + d.found_count + " &nbsp;|&nbsp; ";
                html += "<strong>' . esc_js(__('Not found:', 'ai-eshop-optimizer')) . '</strong> " + d.not_found_count + " &nbsp;|&nbsp; ";
                html += "<strong>' . esc_js(__('Unique parent IDs:', 'ai-eshop-optimizer')) . '</strong> " + d.unique_parent_ids.length;
                html += "</div>";
                if (d.unique_parent_ids.length > 0) {
                    html += "<p style=\"margin:0 0 4px;\"><strong>' . esc_js(__('Parent product IDs (comma-separated, click to select):', 'ai-eshop-optimizer')) . '</strong></p>";
                    html += "<textarea class=\"large-text\" rows=\"2\" readonly onclick=\"this.select();\">" + escapeHtml(d.unique_parent_ids.join(", ")) + "</textarea>";
                }
                html += "<table class=\"wp-list-table widefat fixed striped\" style=\"margin-top:10px;\">";
                html += "<thead><tr><th style=\"width:30%;\">" + headerLabel + "</th><th style=\"width:18%;\">' . esc_js(__('Product ID', 'ai-eshop-optimizer')) . '</th><th style=\"width:18%;\">' . esc_js(__('Parent ID', 'ai-eshop-optimizer')) . '</th><th>' . esc_js(__('Status', 'ai-eshop-optimizer')) . '</th></tr></thead><tbody>";
                d.results.forEach(function(item){
                    var rowStyle = item.found ? "" : "style=\"color:#b91c1c;\"";
                    html += "<tr " + rowStyle + ">";
                    html += "<td>" + escapeHtml(item.input) + "</td>";
                    html += "<td>" + (item.product_id || "—") + "</td>";
                    html += "<td>" + (item.parent_id ? "<a href=\"/?p=" + item.parent_id + "\" target=\"_blank\" rel=\"noopener\">" + item.parent_id + "</a>" : "—") + "</td>";
                    html += "<td>" + escapeHtml(item.status) + "</td>";
                    html += "</tr>";
                });
                html += "</tbody></table>";
                if (d.not_found.length > 0) {
                    html += "<p style=\"margin:10px 0 4px;\"><strong>' . esc_js(__('Not found:', 'ai-eshop-optimizer')) . '</strong></p>";
                    html += "<textarea class=\"large-text\" rows=\"3\" readonly style=\"color:#b91c1c;\">" + escapeHtml(d.not_found.join("\\n")) + "</textarea>";
                }
                box.innerHTML = html;
                box.style.display = "block";
            }
            var skuBtn = document.getElementById("aieo-tools-sku-btn");
            var bcBtn  = document.getElementById("aieo-tools-barcode-btn");
            if (skuBtn) skuBtn.addEventListener("click", function(){ runLookup("sku"); });
            if (bcBtn)  bcBtn.addEventListener("click",  function(){ runLookup("barcode"); });
        })();</script>';
    }

    public function ajax_sku_lookup() {
        AIEO_DMM::verify_ajax_request();
        if (!current_user_can('manage_woocommerce')) {
            wp_send_json_error(array('message' => __('Insufficient permissions.', 'ai-eshop-optimizer')));
        }
        $items = $this->parse_lookup_input(isset($_POST['input']) ? wp_unslash((string) sanitize_text_field( wp_unslash( $_POST['input'] ) )) : '');
        if (empty($items)) {
            wp_send_json_error(array('message' => __('No valid SKUs provided.', 'ai-eshop-optimizer')));
        }
        $results = array(); $not_found = array(); $parent_ids = array(); $found = 0;
        foreach ($items as $sku) {
            $product_id = function_exists('wc_get_product_id_by_sku') ? wc_get_product_id_by_sku($sku) : 0;
            $row = $this->resolve_lookup_row($sku, (int) $product_id);
            $results[] = $row;
            if ($row['found']) { $parent_ids[] = $row['parent_id']; $found++; }
            else { $not_found[] = $sku; }
        }
        wp_send_json_success(array(
            'results'           => $results,
            'unique_parent_ids' => array_values(array_unique(array_filter($parent_ids))),
            'not_found'         => $not_found,
            'found_count'       => $found,
            'not_found_count'   => count($not_found),
        ));
    }

    public function ajax_barcode_lookup() {
        AIEO_DMM::verify_ajax_request();
        if (!current_user_can('manage_woocommerce')) {
            wp_send_json_error(array('message' => __('Insufficient permissions.', 'ai-eshop-optimizer')));
        }
        global $wpdb;
        $items = $this->parse_lookup_input(isset($_POST['input']) ? wp_unslash((string) sanitize_text_field( wp_unslash( $_POST['input'] ) )) : '');
        if (empty($items)) {
            wp_send_json_error(array('message' => __('No valid barcodes provided.', 'ai-eshop-optimizer')));
        }
        $results = array(); $not_found = array(); $parent_ids = array(); $found = 0;
        foreach ($items as $barcode) {
            
            
            $product_id = 0;
            foreach (array('_global_unique_id', '_ean', '_gtin', '_barcode') as $mk) {
                $pid = (int) $wpdb->get_var($wpdb->prepare(
                    "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s LIMIT 1",
                    $mk, $barcode
                ));
                if ($pid > 0) { $product_id = $pid; break; }
            }
            $row = $this->resolve_lookup_row($barcode, $product_id);
            $results[] = $row;
            if ($row['found']) { $parent_ids[] = $row['parent_id']; $found++; }
            else { $not_found[] = $barcode; }
        }
        wp_send_json_success(array(
            'results'           => $results,
            'unique_parent_ids' => array_values(array_unique(array_filter($parent_ids))),
            'not_found'         => $not_found,
            'found_count'       => $found,
            'not_found_count'   => count($not_found),
        ));
    }

    
    private function parse_lookup_input($raw) {
        $raw = str_replace(array("\r\n", "\r"), "\n", (string) $raw);
        $parts = preg_split('/[\n,;]+/', $raw, -1, PREG_SPLIT_NO_EMPTY);
        $out = array();
        foreach ($parts as $p) {
            $p = trim((string) $p);
            if ($p !== '') { $out[] = $p; }
        }
        return array_values(array_unique($out));
    }

    
    private function resolve_lookup_row($input, $product_id) {
        if ($product_id <= 0) {
            return array('input' => $input, 'product_id' => null, 'parent_id' => null, 'found' => false, 'status' => __('Not found', 'ai-eshop-optimizer'));
        }
        if (!function_exists('wc_get_product')) {
            return array('input' => $input, 'product_id' => $product_id, 'parent_id' => $product_id, 'found' => true, 'status' => __('Unknown (WC missing)', 'ai-eshop-optimizer'));
        }
        $product = wc_get_product($product_id);
        if (!$product) {
            return array('input' => $input, 'product_id' => $product_id, 'parent_id' => null, 'found' => false, 'status' => __('Product not loadable', 'ai-eshop-optimizer'));
        }
        $parent_id = $product_id;
        $status    = __('Simple product', 'ai-eshop-optimizer');
        if ($product->is_type('variation')) {
            $parent_id = (int) $product->get_parent_id();
            
            $status    = sprintf(__('Variation (parent: %d)', 'ai-eshop-optimizer'), $parent_id);
        } elseif ($product->is_type('variable')) {
            $status    = __('Variable product', 'ai-eshop-optimizer');
        }
        return array('input' => $input, 'product_id' => (int) $product_id, 'parent_id' => (int) $parent_id, 'found' => true, 'status' => $status);
    }
}
