<?php

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

class AIEO_DMM_Product_Needs extends AIEO_DMM_Module_Base {

    public function get_id() { return 'product_needs'; }
    public function get_label() { return __('Product Needs', 'ai-eshop-optimizer'); }
    public function get_priority() { return 60; }
    public function get_group() { return 'product_management'; }

    const DISPLAY_OPTION = 'aieo_dmm_product_needs_display';
    const TERM_META_HIDDEN = 'aieo_hidden';

    public function register_hooks() {
        
        
        
        $disp0 = get_option(self::DISPLAY_OPTION, array());
        if (is_array($disp0) && !array_key_exists('enabled', $disp0) && (isset($disp0['frontend_enabled']) && $disp0['frontend_enabled'] === 'yes')) {
            $disp0['enabled'] = true;
            update_option(self::DISPLAY_OPTION, $disp0, false);
        }
        add_action('wp_ajax_aieo_dmm_needs_load_product', array($this, 'ajax_load_product'));
        add_action('wp_ajax_aieo_dmm_needs_save', array($this, 'ajax_save'));
        add_action('wp_ajax_aieo_dmm_needs_search_products', array($this, 'ajax_search_products'));
        add_action('wp_ajax_aieo_dmm_needs_save_display', array($this, 'ajax_save_display'));
        add_action('wp_ajax_aieo_dmm_needs_create_term', array($this, 'ajax_create_term'));

        
        
        
        
        
        
        $taxonomy = apply_filters('aieo_dmm_needs_taxonomy', 'pa_need');
        add_action("{$taxonomy}_add_form_fields",  array($this, 'render_term_add_form_field'));
        
        
        
        
        
        if (!class_exists('AIEO_DMM_Need_Extras_Data')) {
            add_action("{$taxonomy}_edit_form_fields", array($this, 'render_term_edit_form_field'), 10, 2);
        }
        add_action("created_{$taxonomy}", array($this, 'save_term_hidden_flag'), 10, 2);
        add_action("edited_{$taxonomy}",  array($this, 'save_term_hidden_flag'), 10, 2);
        add_filter("manage_edit-{$taxonomy}_columns",     array($this, 'term_list_add_hidden_column'));
        add_filter("manage_{$taxonomy}_custom_column",    array($this, 'term_list_render_hidden_column'), 10, 3);

        
        add_filter('post_row_actions', array($this, 'product_row_action'), 10, 2);

        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        $d = $this->get_display_settings();
        if ($this->is_active()) {
            if ($d['display_location'] === 'tab') {
                add_filter('woocommerce_product_tabs', array($this, 'add_tab'));
            } else {
                
                
                
                
                
                
                
                $use_classic_hook = ! ( function_exists('wp_is_block_theme') && wp_is_block_theme() );
                if ($use_classic_hook) {
                    
                    
                    
                    
                    
                    
                    foreach (array(
                        'woocommerce_simple_add_to_cart',
                        'woocommerce_variable_add_to_cart',
                        'woocommerce_grouped_add_to_cart',
                        'woocommerce_external_add_to_cart',
                    ) as $hook) {
                        add_action($hook, array($this, 'render_summary_hook'), 5);
                    }
                }
            }
            add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_assets'));
            add_shortcode('aieo_product_needs', array($this, 'shortcode_handler'));
        }
    }

    
    
    

    public function get_display_settings() {
        $stored = get_option(self::DISPLAY_OPTION, array());
        if (!is_array($stored)) { $stored = array(); }
        return array_merge(array(
            'enabled'           => false,
            'frontend_enabled'  => 'no',
            'display_location'  => 'summary',  
            'title'             => __('This product covers:', 'ai-eshop-optimizer'),
            'show_title'        => true,
            'tab_title'         => __('Needs', 'ai-eshop-optimizer'),
            'tab_priority'      => 25,
            'show_links'        => 'yes',
            'show_descriptions' => 'yes',
            'align'             => 'flex-start',  
            'display_style'     => 'list',         
            'icon_kind'         => 'check',        
            'icon_url'          => '',
            'icon_attachment_id'=> 0,
            'icon_color'        => '#27ae60',
            'text_color'        => '#333333',
            'link_color'        => '#0073aa',
            'bg_color'          => '#f8f9fa',
            'border_color'      => '#e9ecef',
            'border_width'      => 1,
            'border_radius'     => 0,
            'margin_top'        => 20,
            'margin_bottom'     => 20,
            
            'pill_text_size'    => 13,
            'pill_radius'       => 16,
            'pill_pad_v'        => 6,
            'pill_pad_h'        => 12,
            'pill_gap'          => 8,
            'pill_bg'           => '#eef1f4',
            'pill_border_width' => 1,
            'pill_border_color' => '#d6dbe1',
            'pill_text_color'   => '#333333',
        ), $stored);
    }

    public function ajax_save_display() {
        AIEO_DMM::verify_ajax_request();
        $align = isset($_POST['align']) ? sanitize_key(wp_unslash($_POST['align'])) : 'flex-start';
        if (!in_array($align, array('flex-start', 'center', 'flex-end'), true)) {
            $align = 'flex-start';
        }
        $location = isset($_POST['display_location']) ? sanitize_key(wp_unslash($_POST['display_location'])) : 'summary';
        if (!in_array($location, array('summary', 'tab'), true)) { $location = 'summary'; }

        $style = isset($_POST['display_style']) ? sanitize_key(wp_unslash($_POST['display_style'])) : 'list';
        if (!in_array($style, array('list', 'pills'), true)) { $style = 'list'; }

        $icon_kind = isset($_POST['icon_kind']) ? sanitize_key(wp_unslash($_POST['icon_kind'])) : 'check';
        if (!in_array($icon_kind, array('check', 'custom', 'none'), true)) { $icon_kind = 'check'; }
        $icon_url = isset($_POST['icon_url']) ? esc_url_raw(wp_unslash($_POST['icon_url'])) : '';
        $icon_aid = isset($_POST['icon_attachment_id']) ? max(0, (int) $_POST['icon_attachment_id']) : 0;
        if ($icon_kind === 'custom' && $icon_url === '') { $icon_kind = 'check'; }

        $data = array(
            
            
            'enabled'           => !empty($_POST['enabled']),
            'display_location'  => $location,
            'title'             => isset($_POST['title'])         ? sanitize_text_field(wp_unslash($_POST['title']))         : '',
            'show_title'        => !empty($_POST['show_title']),
            'tab_title'         => isset($_POST['tab_title'])     ? sanitize_text_field(wp_unslash($_POST['tab_title']))     : '',
            'tab_priority'      => isset($_POST['tab_priority'])  ? max(1, min(999, (int) $_POST['tab_priority']))           : 25,
            'show_links'        => !empty($_POST['show_links'])        ? 'yes' : 'no',
            'show_descriptions' => !empty($_POST['show_descriptions']) ? 'yes' : 'no',
            'align'             => $align,
            'display_style'     => $style,
            'icon_kind'         => $icon_kind,
            'icon_url'          => $icon_url,
            'icon_attachment_id'=> $icon_aid,
            'icon_color'        => sanitize_hex_color(wp_unslash($_POST['icon_color']   ?? '')) ?: '#27ae60',
            'text_color'        => sanitize_hex_color(wp_unslash($_POST['text_color']   ?? '')) ?: '#333333',
            'link_color'        => sanitize_hex_color(wp_unslash($_POST['link_color']   ?? '')) ?: '#0073aa',
            'bg_color'          => sanitize_hex_color(wp_unslash($_POST['bg_color']     ?? '')) ?: '#f8f9fa',
            'border_color'      => sanitize_hex_color(wp_unslash($_POST['border_color'] ?? '')) ?: '#e9ecef',
            'border_width'      => isset($_POST['border_width'])  ? max(0, min(20,  (int) $_POST['border_width']))           : 1,
            'border_radius'     => isset($_POST['border_radius']) ? max(0, min(100, (int) $_POST['border_radius']))          : 0,
            'margin_top'        => isset($_POST['margin_top'])    ? max(0, min(200, (int) $_POST['margin_top']))             : 20,
            'margin_bottom'     => isset($_POST['margin_bottom']) ? max(0, min(200, (int) $_POST['margin_bottom']))          : 20,
            'pill_text_size'    => isset($_POST['pill_text_size'])    ? max(8, min(40,  (int) $_POST['pill_text_size']))     : 13,
            'pill_radius'       => isset($_POST['pill_radius'])       ? max(0, min(100, (int) $_POST['pill_radius']))        : 16,
            'pill_pad_v'        => isset($_POST['pill_pad_v'])        ? max(0, min(60,  (int) $_POST['pill_pad_v']))         : 6,
            'pill_pad_h'        => isset($_POST['pill_pad_h'])        ? max(0, min(80,  (int) $_POST['pill_pad_h']))         : 12,
            'pill_gap'          => isset($_POST['pill_gap'])          ? max(0, min(60,  (int) $_POST['pill_gap']))           : 8,
            'pill_bg'           => sanitize_hex_color(wp_unslash($_POST['pill_bg']           ?? '')) ?: '#eef1f4',
            'pill_border_width' => isset($_POST['pill_border_width']) ? max(0, min(20,  (int) $_POST['pill_border_width'])) : 1,
            'pill_border_color' => sanitize_hex_color(wp_unslash($_POST['pill_border_color'] ?? '')) ?: '#d6dbe1',
            'pill_text_color'   => sanitize_hex_color(wp_unslash($_POST['pill_text_color']   ?? '')) ?: '#333333',
        );
        
        
        
        $stored = get_option(self::DISPLAY_OPTION, array());
        if (!is_array($stored)) { $stored = array(); }
        update_option(self::DISPLAY_OPTION, array_merge($stored, $data), false);
        wp_send_json_success(array('message' => __('Display settings saved.', 'ai-eshop-optimizer')));
    }

    public function enqueue_admin_assets() {
        wp_enqueue_style('wp-color-picker');
        wp_enqueue_script('wp-color-picker');
        wp_add_inline_script('wp-color-picker',
            'jQuery(function($){$(".aieo-dmm-pn-color").wpColorPicker();});'
        );
    }

    
    
    

    public function enqueue_frontend_assets() {
        if (!is_product()) { return; }
        $rel  = 'assets/css/aieo-product-needs.css';
        $path = dirname(AIEO_FILE) . '/' . $rel;
        $ver  = file_exists($path) ? filemtime($path) : AIEO_VERSION;
        wp_enqueue_style('aieo-product-needs', plugins_url($rel, AIEO_FILE), array(), $ver);
        wp_add_inline_style('aieo-product-needs', $this->build_css_vars());
    }

    private function build_css_vars() {
        $s = $this->get_display_settings();
        return sprintf(
            '.aieo-product-needs{'
          . '--aieo-pn-align:%s;--aieo-pn-icon:%s;--aieo-pn-text:%s;--aieo-pn-link:%s;'
          . '--aieo-pn-bg:%s;--aieo-pn-border:%s;'
          . '--aieo-pn-border-w:%dpx;--aieo-pn-border-r:%dpx;'
          . '--aieo-pn-mt:%dpx;--aieo-pn-mb:%dpx;'
          . '--aieo-pn-pill-fs:%dpx;--aieo-pn-pill-r:%dpx;--aieo-pn-pill-pv:%dpx;--aieo-pn-pill-ph:%dpx;--aieo-pn-pill-gap:%dpx;'
          . '--aieo-pn-pill-bg:%s;--aieo-pn-pill-bw:%dpx;--aieo-pn-pill-bc:%s;--aieo-pn-pill-text:%s;}',
            esc_attr($s['align']),
            esc_attr($s['icon_color']),
            esc_attr($s['text_color']),
            esc_attr($s['link_color']),
            esc_attr($s['bg_color']),
            esc_attr($s['border_color']),
            (int) ($s['border_width']  ?? 1),
            (int) ($s['border_radius'] ?? 0),
            (int) $s['margin_top'],
            (int) $s['margin_bottom'],
            (int) ($s['pill_text_size']    ?? 13),
            (int) ($s['pill_radius']       ?? 16),
            (int) ($s['pill_pad_v']        ?? 6),
            (int) ($s['pill_pad_h']        ?? 12),
            (int) ($s['pill_gap']          ?? 8),
            esc_attr($s['pill_bg']           ?? '#eef1f4'),
            (int) ($s['pill_border_width'] ?? 1),
            esc_attr($s['pill_border_color'] ?? '#d6dbe1'),
            esc_attr($s['pill_text_color']   ?? '#333333')
        );
    }

    public function render_summary_hook() {
        
        echo $this->render_html(false);
    }

    public function add_tab($tabs) {
        global $product;
        if (!$product) { return $tabs; }
        if (empty($this->get_product_needs($product->get_id()))) { return $tabs; }
        $s = $this->get_display_settings();
        $tabs['aieo_product_needs'] = array(
            'title'    => esc_html($s['tab_title']),
            'priority' => (int) $s['tab_priority'],
            'callback' => array($this, 'render_tab_hook'),
        );
        return $tabs;
    }

    public function render_tab_hook() {
        
        echo $this->render_html(true);
    }

    public function shortcode_handler($atts = array()) {
        if (!is_singular('product')) { return ''; }
        return $this->render_html(false);
    }

    
    public function output() {
        echo $this->shortcode_handler(array()); 
    }

    
    public function is_active() {
        $stored = get_option(self::DISPLAY_OPTION, array());
        if (!is_array($stored)) { $stored = array(); }
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        return !empty($stored['enabled']);
    }

    
    private function render_html($is_tab) {
        $product = function_exists('wc_get_product') ? wc_get_product(get_the_ID()) : null;
        if (!$product) { return ''; }
        $needs = $this->get_product_needs($product->get_id());
        if (empty($needs)) { return ''; }

        $s = $this->get_display_settings();
        $style_cls = (($s['display_style'] ?? 'list') === 'pills') ? ' aieo-product-needs--pills' : '';
        $cls = 'aieo-product-needs' . ($is_tab ? ' aieo-product-needs--tab' : '') . $style_cls;
        ob_start();
        ?>
        <div class="<?php echo esc_attr($cls); ?>">
            <?php if (!$is_tab && !empty($s['show_title']) && !empty($s['title'])) : ?>
                <h4 class="aieo-product-needs-title"><?php echo esc_html($s['title']); ?></h4>
            <?php endif; ?>
            <ul class="aieo-product-needs-list">
                <?php foreach ($needs as $need) :
                    $url = get_term_link($need);
                    if (is_wp_error($url)) { $url = ''; }
                    $title_attr = '';
                    if ($s['show_descriptions'] === 'yes' && !empty($need->description)) {
                        $title_attr = ' title="' . esc_attr(wp_strip_all_tags($need->description)) . '"';
                    }
                    ?>
                    <li class="aieo-product-needs-item"<?php echo $title_attr; ?>>
                        <?php $icon_html = $this->render_icon($s); ?>
                        <?php if ($icon_html !== '') : ?>
                            <span class="aieo-product-needs-icon"><?php echo $icon_html; ?></span>
                        <?php endif; ?>
                        <?php if ($s['show_links'] === 'yes' && !empty($url)) : ?>
                            <a href="<?php echo esc_url($url); ?>" class="aieo-product-needs-link"><?php echo esc_html($need->name); ?></a>
                        <?php else : ?>
                            <span class="aieo-product-needs-text"><?php echo esc_html($need->name); ?></span>
                        <?php endif; ?>
                    </li>
                <?php endforeach; ?>
            </ul>
        </div>
        <?php
        return ob_get_clean();
    }

    
    private function get_product_needs($product_id) {
        $taxonomy = apply_filters('aieo_dmm_needs_taxonomy', 'pa_need');
        if (!taxonomy_exists($taxonomy)) { return array(); }
        $cache_key = 'aieo_pn:' . $product_id;
        $cached = wp_cache_get($cache_key, 'aieo_dmm');
        if (is_array($cached)) { return $cached; }

        $terms = wp_get_object_terms($product_id, $taxonomy, array('fields' => 'all'));
        if (is_wp_error($terms) || empty($terms)) {
            wp_cache_set($cache_key, array(), 'aieo_dmm', HOUR_IN_SECONDS);
            return array();
        }

        
        
        
        $terms = array_values(array_filter($terms, function ($t) {
            return !self::is_term_hidden((int) $t->term_id);
        }));
        if (empty($terms)) {
            wp_cache_set($cache_key, array(), 'aieo_dmm', HOUR_IN_SECONDS);
            return array();
        }

        $saved = get_post_meta($product_id, '_pne_need_order', true);
        if (!empty($saved)) {
            $order = json_decode($saved, true);
            if (is_array($order) && !empty($order)) {
                $lookup = array();
                foreach ($terms as $t) { $lookup[$t->term_id] = $t; }
                $ordered = array();
                foreach ($order as $tid) {
                    $tid = (int) $tid;
                    if (isset($lookup[$tid])) { $ordered[] = $lookup[$tid]; unset($lookup[$tid]); }
                }
                foreach ($lookup as $t) { $ordered[] = $t; }
                wp_cache_set($cache_key, $ordered, 'aieo_dmm', HOUR_IN_SECONDS);
                return $ordered;
            }
        }
        usort($terms, function ($a, $b) { return strcasecmp($a->name, $b->name); });
        wp_cache_set($cache_key, $terms, 'aieo_dmm', HOUR_IN_SECONDS);
        return $terms;
    }

    private function checkmark_svg() {
        return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="16" height="16" aria-hidden="true"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z"/></svg>';
    }

    
    private function render_icon(array $s) {
        $kind = isset($s['icon_kind']) ? (string) $s['icon_kind'] : 'check';
        if ($kind === 'none') { return ''; }
        if ($kind === 'custom' && !empty($s['icon_url'])) {
            return '<img src="' . esc_url($s['icon_url']) . '" alt="" width="20" height="20" loading="lazy">';
        }
        return $this->checkmark_svg();
    }

    public function render_subtab() {
        $stats = $this->get_impactful_products_without_needs(50);
        $this->render_template('product-needs.php', array(
            'all_needs'              => $this->get_available_needs(),
            'preselect_pid'          => isset($_GET['pid']) ? absint(wp_unslash($_GET['pid'])) : 0,
            'display'                => $this->get_display_settings(),
            'impactful'              => $stats['rows'],
            'impactful_total_missing'=> $stats['total_missing'],
        ));
    }

    
    public function get_impactful_products_without_needs(int $limit = 50): array {
        global $wpdb;
        $temp_orders = $wpdb->prefix . 'aieo_temp_orders';
        if (!aieo_dmm_table_exists($temp_orders)) {
            return array('rows' => array(), 'total_missing' => 0);
        }

        $taxonomy = apply_filters('aieo_dmm_needs_taxonomy', 'pa_need');

        
        
        $sql = $wpdb->prepare(
            "SELECT
                COALESCE(NULLIF(t.ParentProductId, 0), t.ProductId) AS pid,
                SUM(t.PrimaryQty)        AS qty,
                SUM(t.LineValue)         AS turnover
             FROM {$temp_orders} t
             WHERE t.OrderStatus IN ('wc-completed', 'wc-processing')
               AND COALESCE(NULLIF(t.ParentProductId, 0), t.ProductId) > 0
               AND COALESCE(NULLIF(t.ParentProductId, 0), t.ProductId) NOT IN (
                   SELECT DISTINCT tr.object_id
                   FROM {$wpdb->term_relationships} tr
                   INNER JOIN {$wpdb->term_taxonomy} tt
                           ON tt.term_taxonomy_id = tr.term_taxonomy_id
                   WHERE tt.taxonomy = %s
               )
             GROUP BY pid
             ORDER BY turnover DESC
             LIMIT %d",
            $taxonomy,
            max(1, min(500, $limit))
        );
        $rows = $wpdb->get_results($sql, ARRAY_A);
        if (!is_array($rows)) { $rows = array(); }

        
        
        $total_missing = (int) $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(DISTINCT COALESCE(NULLIF(t.ParentProductId, 0), t.ProductId))
             FROM {$temp_orders} t
             WHERE t.OrderStatus IN ('wc-completed', 'wc-processing')
               AND COALESCE(NULLIF(t.ParentProductId, 0), t.ProductId) > 0
               AND COALESCE(NULLIF(t.ParentProductId, 0), t.ProductId) NOT IN (
                   SELECT DISTINCT tr.object_id
                   FROM {$wpdb->term_relationships} tr
                   INNER JOIN {$wpdb->term_taxonomy} tt
                           ON tt.term_taxonomy_id = tr.term_taxonomy_id
                   WHERE tt.taxonomy = %s
               )",
            $taxonomy
        ));

        
        $base = add_query_arg(array(
            'page'    => AIEO_DMM::MENU_SLUG,
            'dmm_tab' => 'product_needs',
        ), admin_url('admin.php'));

        $out = array();
        foreach ($rows as $r) {
            $pid = (int) $r['pid'];
            $product = function_exists('wc_get_product') ? wc_get_product($pid) : null;
            $title = $product ? (string) $product->get_name() : '';
            $sku   = $product ? (string) $product->get_sku()  : '';
            $out[] = array(
                'pid'         => $pid,
                'qty'         => (int) $r['qty'],
                'turnover'    => (float) $r['turnover'],
                'title'       => $title,
                'sku'         => $sku,
                'edit_link'   => admin_url('post.php?post=' . $pid . '&action=edit'),
                'select_link' => add_query_arg('pid', $pid, $base) . '#aieo-dmm-needs-editor',
            );
        }

        return array(
            'rows'          => $out,
            'total_missing' => $total_missing,
        );
    }

    
    public function get_available_needs() {
        $taxonomy = apply_filters('aieo_dmm_needs_taxonomy', 'pa_need');
        $terms = get_terms(array(
            'taxonomy'   => $taxonomy,
            'hide_empty' => false,
            'orderby'    => 'name',
            'order'      => 'ASC',
        ));
        $out = array();
        if (is_array($terms)) {
            foreach ($terms as $t) {
                $out[] = array(
                    'term_id' => (int) $t->term_id,
                    'name'    => $t->name,
                    'slug'    => $t->slug,
                    'hidden'  => self::is_term_hidden((int) $t->term_id),
                );
            }
        }

        
        
        
        
        
        
        if (class_exists('Collator')) {
            $coll = new Collator('el_GR');
            $coll->setStrength(Collator::PRIMARY); 
            usort($out, function ($a, $b) use ($coll) {
                return $coll->compare((string) $a['name'], (string) $b['name']);
            });
        } else {
            usort($out, function ($a, $b) {
                $na = self::normalize_for_sort((string) $a['name']);
                $nb = self::normalize_for_sort((string) $b['name']);
                return strcmp($na, $nb);
            });
        }
        return $out;
    }

    
    private static function normalize_for_sort(string $s): string {
        $s = function_exists('mb_strtolower') ? mb_strtolower($s, 'UTF-8') : strtolower($s);
        if (class_exists('Normalizer')) {
            $s = Normalizer::normalize($s, Normalizer::FORM_D);
            $s = preg_replace('/\p{Mn}+/u', '', $s);
        }
        return $s;
    }

    
    public static function is_term_hidden(int $term_id): bool {
        $v = get_term_meta($term_id, self::TERM_META_HIDDEN, true);
        return (string) $v === '1';
    }

    
    public function ajax_create_term(): void {
        AIEO_DMM::verify_ajax_request();

        $taxonomy = apply_filters('aieo_dmm_needs_taxonomy', 'pa_need');
        if (!taxonomy_exists($taxonomy)) {
            wp_send_json_error(array('message' => __('The pa_need taxonomy is not registered. Visit Products → Attributes once to bootstrap it.', 'ai-eshop-optimizer')));
        }

        $name = isset($_POST['name']) ? sanitize_text_field(wp_unslash((string) $_POST['name'])) : '';
        $slug = isset($_POST['slug']) ? sanitize_title(wp_unslash((string) $_POST['slug'])) : '';
        $hide = !empty($_POST['hidden']);

        if ($name === '') {
            wp_send_json_error(array('message' => __('Name is required.', 'ai-eshop-optimizer')));
        }

        $args = array();
        if ($slug !== '') { $args['slug'] = $slug; }

        $created = wp_insert_term($name, $taxonomy, $args);
        if (is_wp_error($created)) {
            
            
            wp_send_json_error(array(
                'message' => $created->get_error_message(),
                'code'    => $created->get_error_code(),
            ));
        }

        $term_id = (int) $created['term_id'];
        if ($hide) {
            update_term_meta($term_id, self::TERM_META_HIDDEN, '1');
        }

        $term = get_term($term_id, $taxonomy);
        if (!$term || is_wp_error($term)) {
            wp_send_json_error(array('message' => __('Term created but could not be re-loaded.', 'ai-eshop-optimizer')));
        }

        
        
        if (function_exists('wp_cache_flush_group')) {
            wp_cache_flush_group('aieo_dmm');
        }

        wp_send_json_success(array(
            'term_id' => $term_id,
            'name'    => $term->name,
            'slug'    => $term->slug,
            'hidden'  => $hide,
        ));
    }

    
    
    

    
    public function render_term_add_form_field(): void {
        ?>
        <div class="form-field aieo-pn-hidden-field">
            <label for="aieo_pn_hidden">
                <input type="checkbox" name="aieo_pn_hidden" id="aieo_pn_hidden" value="1">
                <?php esc_html_e('Hide from front-end (internal use only)', 'ai-eshop-optimizer'); ?>
            </label>
            <p>
                <?php esc_html_e('When ticked, this need is suppressed from product-page rendering and the tab. The merchant + AI processing still see it via the editor and the API. Useful for needs you want to track internally without exposing to shoppers.', 'ai-eshop-optimizer'); ?>
            </p>
        </div>
        <?php
    }

    
    public function render_term_edit_form_field($term, $taxonomy): void {
        $hidden = self::is_term_hidden((int) $term->term_id);
        ?>
        <tr class="form-field aieo-pn-hidden-field">
            <th scope="row"><?php esc_html_e('Front-end visibility', 'ai-eshop-optimizer'); ?></th>
            <td>
                <label>
                    <input type="checkbox" name="aieo_pn_hidden" value="1" <?php checked($hidden); ?>>
                    <?php esc_html_e('Hide from front-end (internal use only)', 'ai-eshop-optimizer'); ?>
                </label>
                <p class="description">
                    <?php esc_html_e('When ticked, this need is suppressed from product-page rendering and the tab. The merchant + AI processing still see it via the editor and the API.', 'ai-eshop-optimizer'); ?>
                </p>
            </td>
        </tr>
        <?php
    }

    
    public function save_term_hidden_flag($term_id, $tt_id): void {
        
        if (!isset($_POST['aieo_pn_hidden_present']) && !isset($_POST['aieo_pn_hidden'])) {
            
            return;
        }
        $val = !empty($_POST['aieo_pn_hidden']) ? '1' : '';
        if ($val === '') {
            delete_term_meta((int) $term_id, self::TERM_META_HIDDEN);
        } else {
            update_term_meta((int) $term_id, self::TERM_META_HIDDEN, '1');
        }

        
        
        
        
        if (function_exists('wp_cache_flush_group')) {
            wp_cache_flush_group('aieo_dmm');
        }
    }

    
    public function term_list_add_hidden_column(array $columns): array {
        $new = array();
        foreach ($columns as $key => $label) {
            $new[$key] = $label;
            if ($key === 'name') {
                $new['aieo_hidden'] = __('Front-end', 'ai-eshop-optimizer');
            }
        }
        if (!isset($new['aieo_hidden'])) {
            $new['aieo_hidden'] = __('Front-end', 'ai-eshop-optimizer');
        }
        return $new;
    }

    public function term_list_render_hidden_column($content, $column_name, $term_id): string {
        if ($column_name !== 'aieo_hidden') { return (string) $content; }
        if (self::is_term_hidden((int) $term_id)) {
            return '<span style="display:inline-block;padding:2px 8px;background:#fef3c7;color:#78350f;border-radius:10px;font-size:11px;font-weight:600;">' . esc_html__('Hidden', 'ai-eshop-optimizer') . '</span>';
        }
        return '<span style="color:#15803d;font-size:11px;">' . esc_html__('Visible', 'ai-eshop-optimizer') . '</span>';
    }

    public function ajax_load_product() {
        AIEO_DMM::verify_ajax_request();

        $pid = isset($_POST['product_id']) ? absint(wp_unslash($_POST['product_id'])) : 0;
        if ($pid <= 0) {
            wp_send_json_error(array('message' => __('Invalid product id.', 'ai-eshop-optimizer')));
        }
        $post = get_post($pid);
        if (!$post || $post->post_type !== 'product') {
            wp_send_json_error(array('message' => __('Product not found.', 'ai-eshop-optimizer')));
        }

        $selected_terms = wp_get_object_terms($pid, apply_filters('aieo_dmm_needs_taxonomy', 'pa_need'), array('fields' => 'ids'));
        if (is_wp_error($selected_terms)) {
            $selected_terms = array();
        }

        global $wpdb;
        $table = $wpdb->prefix . 'aieo_dmm_product_needs';
        $row = null;
        if (aieo_dmm_table_exists($table)) {
            
            $row = $wpdb->get_row($wpdb->prepare(
                "SELECT * FROM {$table} WHERE product_id = %d",
                $pid
            ), ARRAY_A);
        }

        $order = array();
        if ($row && !empty($row['need_order'])) {
            $order = json_decode($row['need_order'], true) ?: array();
        }

        wp_send_json_success(array(
            'product_id'     => $pid,
            'title'          => $post->post_title,
            'sku'            => get_post_meta($pid, '_sku', true),
            'selected_term_ids' => array_map('intval', $selected_terms),
            'order'          => array_map('intval', (array) $order),
        ));
    }

    public function ajax_save() {
        AIEO_DMM::verify_ajax_request();

        $pid = isset($_POST['product_id']) ? absint(wp_unslash($_POST['product_id'])) : 0;
        if ($pid <= 0) {
            wp_send_json_error(array('message' => __('Invalid product id.', 'ai-eshop-optimizer')));
        }
        $term_ids = isset($_POST['term_ids']) && is_array($_POST['term_ids'])
            ? array_map('absint', wp_unslash($_POST['term_ids']))
            : array();
        $order = isset($_POST['order']) && is_array($_POST['order'])
            ? array_map('absint', wp_unslash($_POST['order']))
            : array();

        $taxonomy = apply_filters('aieo_dmm_needs_taxonomy', 'pa_need');

        
        wp_set_object_terms($pid, $term_ids, $taxonomy, false);

        
        $selected_labels = array();
        foreach ($term_ids as $tid) {
            $t = get_term($tid, $taxonomy);
            if ($t && !is_wp_error($t)) {
                $selected_labels[] = $t->name;
            }
        }

        global $wpdb;
        $table = $wpdb->prefix . 'aieo_dmm_product_needs';
        if (aieo_dmm_table_exists($table)) {
            $wpdb->replace($table, array(
                'product_id'     => $pid,
                'selected_needs' => implode(',', $selected_labels),
                'need_order'     => wp_json_encode($order),
            ), array('%d', '%s', '%s'));
        }

        AIEO_DMM_Cache::bump_version('needs');
        wp_send_json_success(array('message' => __('Product needs updated.', 'ai-eshop-optimizer')));
    }

    public function ajax_search_products() {
        AIEO_DMM::verify_ajax_request();

        $q = isset($_GET['q']) ? sanitize_text_field(wp_unslash($_GET['q'])) : '';
        global $wpdb;

        $temp_orders = $wpdb->prefix . 'aieo_temp_orders';
        $taxonomy    = apply_filters('aieo_dmm_needs_taxonomy', 'pa_need');

        
        
        
        
        
        
        
        $params = array();
        $where  = array(
            "p.post_status = 'publish'",
            "p.post_type IN ('product', 'product_variation')",
        );

        if ($q !== '') {
            $like = '%' . $wpdb->esc_like($q) . '%';
            $where[] = "(p.post_title LIKE %s OR pm.meta_value LIKE %s OR p.ID = %d)";
            $params[] = $like;
            $params[] = $like;
            $params[] = (int) preg_replace('/\D/', '', $q);
        }

        
        
        
        $has_needs_subq = "EXISTS (
            SELECT 1 FROM {$wpdb->term_relationships} tr
            JOIN {$wpdb->term_taxonomy} tt
              ON tt.term_taxonomy_id = tr.term_taxonomy_id
            WHERE tt.taxonomy = %s
              AND tr.object_id = COALESCE(p.post_parent, p.ID)
        )";

        
        
        $sql = $wpdb->prepare(
            "SELECT
                p.ID AS pid,
                p.post_title AS title,
                pm.meta_value AS sku,
                IFNULL(t.turnover, 0) AS turnover,
                ({$has_needs_subq}) AS has_needs
             FROM {$wpdb->posts} p
             LEFT JOIN {$wpdb->postmeta} pm
                    ON pm.post_id = p.ID AND pm.meta_key = '_sku'
             LEFT JOIN (
                SELECT
                    COALESCE(NULLIF(ParentProductId, 0), ProductId) AS pid,
                    SUM(LineValue) AS turnover
                FROM {$temp_orders}
                WHERE OrderStatus IN ('wc-completed', 'wc-processing')
                  AND COALESCE(NULLIF(ParentProductId, 0), ProductId) > 0
                GROUP BY pid
             ) t ON t.pid = p.ID
             WHERE " . implode(' AND ', $where) . "
                AND p.post_type = 'product'
             ORDER BY has_needs ASC, turnover DESC, p.post_title ASC
             LIMIT 30",
            array_merge(array($taxonomy), $params)
        );

        $rows = $wpdb->get_results($sql, ARRAY_A);
        $out = array();
        foreach ($rows as $r) {
            $title = (string) $r['title'];
            $sku   = (string) $r['sku'];
            $tag   = $r['has_needs'] ? '' : ' ★'; 
            $out[] = array(
                'id'   => (int) $r['pid'],
                'text' => $title . ($sku !== '' ? ' [' . $sku . ']' : '') . $tag,
            );
        }
        wp_send_json(array('results' => $out));
    }

    
    public function product_row_action($actions, $post) {
        if (!current_user_can(AIEO_CAPABILITY)) {
            return $actions;
        }
        if (!isset($post->post_type) || $post->post_type !== 'product') {
            return $actions;
        }
        $url = add_query_arg(array(
            'page'    => AIEO_DMM::MENU_SLUG,
            'dmm_tab' => 'product_needs',
            'pid'     => (int) $post->ID,
        ), admin_url('admin.php'));
        $actions['aieo_dmm_edit_needs'] = '<a href="' . esc_url($url) . '">' . esc_html__('Edit Needs', 'ai-eshop-optimizer') . '</a>';
        return $actions;
    }
}
