<?php

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

class AIEO_DMM_Custom_Slots extends AIEO_DMM_Module_Base {

    const OPTION_KEY = 'aieo_dmm_custom_slots';

    
    const TYPES = array('tolstoy', 'html');

    public function get_id()       { return 'custom_slots'; }
    public function get_label()    { return __('Custom Slots', 'ai-eshop-optimizer'); }
    
    
    
    
    public function get_priority() { return 57; }
    public function get_group()    { return 'product_display'; }

    public function register_hooks() {
        add_action('wp_ajax_aieo_dmm_custom_slots_save',   array($this, 'ajax_save'));
        add_action('wp_ajax_aieo_dmm_custom_slots_add',    array($this, 'ajax_add'));
        add_action('wp_ajax_aieo_dmm_custom_slots_delete', array($this, 'ajax_delete'));

        
        
        
        add_action('wp_enqueue_scripts', array($this, 'enqueue_tolstoy_scripts'));

        
        
        
        
        
        
        
        
        
        
        
        
        if (!function_exists('wp_is_block_theme') || !wp_is_block_theme()) {
            add_action('woocommerce_after_single_product_summary', array($this, 'render_classic_theme_region'), 25);
        }
    }

    
    public function render_classic_theme_region() {
        if (!function_exists('is_singular') || !is_singular('product')) { return; }
        $slots = self::get_all_slots();
        if (empty($slots)) { return; }

        
        
        
        $visible_map = null;
        if (class_exists('AIEO_DMM_Product_Display') && method_exists('AIEO_DMM_Product_Display', 'get_reco_order')) {
            $visible_map = array();
            foreach (AIEO_DMM_Product_Display::get_reco_order() as $row) {
                if (!empty($row['id'])) {
                    $visible_map[$row['id']] = !empty($row['visible']);
                }
            }
        }

        $out = '';
        foreach ($slots as $slot) {
            if (empty($slot['enabled'])) { continue; }
            $slot_id = (string) $slot['id'];
            if (is_array($visible_map) && array_key_exists($slot_id, $visible_map) && !$visible_map[$slot_id]) {
                continue;
            }
            $html = self::render_slot($slot_id);
            if ($html === '') { continue; }
            $clean = esc_attr(sanitize_html_class($slot_id));
            $out .= sprintf(
                '<section class="aieo-custom-slot aieo-custom-slot--%1$s aieo-recommendations" data-aieo-reco="%1$s" data-section="%1$s">%2$s</section>',
                $clean,
                $html
            );
        }
        if ($out === '') { return; }
        
        echo $out;
    }

    
    
    

    
    public static function get_all_slots() {
        $stored = get_option(self::OPTION_KEY, array());
        if (!is_array($stored)) { return array(); }
        $out = array();
        foreach ($stored as $row) {
            if (!is_array($row) || empty($row['id']) || empty($row['type'])) { continue; }
            if (!in_array($row['type'], self::TYPES, true)) { continue; }
            $out[] = array_merge(array(
                'id'                   => '',
                'name'                 => '',
                'type'                 => 'html',
                'enabled'              => false,
                
                
                
                
                'title'                => '',
                'show_title'           => false,
                'tolstoy_widget_id'    => '',
                'tolstoy_account_uuid' => '',
                'raw_html'             => '',
            ), $row);
        }
        return $out;
    }

    
    public static function get_slot($slot_id) {
        $slot_id = (string) $slot_id;
        if ($slot_id === '') { return null; }
        foreach (self::get_all_slots() as $row) {
            if ($row['id'] === $slot_id) { return $row; }
        }
        return null;
    }

    
    public static function update_all_slots(array $slots) {
        $reserved = array('upsells', 'crosssells', 'related', 'recently_viewed', 'same_needs');
        $clean = array();
        $seen  = array();
        foreach ($slots as $row) {
            if (!is_array($row)) { continue; }
            $id   = isset($row['id']) ? sanitize_key($row['id']) : '';
            $type = isset($row['type']) && in_array($row['type'], self::TYPES, true) ? $row['type'] : 'html';
            if ($id === '' || in_array($id, $reserved, true) || isset($seen[$id])) { continue; }
            $seen[$id] = true;
            $clean[]   = array(
                'id'                   => $id,
                'name'                 => isset($row['name']) ? sanitize_text_field((string) $row['name']) : '',
                'type'                 => $type,
                'enabled'              => !empty($row['enabled']),
                'title'                => isset($row['title']) ? sanitize_text_field((string) $row['title']) : '',
                'show_title'           => !empty($row['show_title']),
                'tolstoy_widget_id'    => isset($row['tolstoy_widget_id']) ? sanitize_text_field((string) $row['tolstoy_widget_id']) : '',
                'tolstoy_account_uuid' => isset($row['tolstoy_account_uuid']) ? sanitize_text_field((string) $row['tolstoy_account_uuid']) : '',
                
                
                
                
                
                
                
                'raw_html'             => isset($row['raw_html']) ? (string) wp_unslash($row['raw_html']) : '',
            );
        }
        update_option(self::OPTION_KEY, $clean, false);
    }

    
    public static function add_slot($type) {
        if (!in_array($type, self::TYPES, true)) { $type = 'html'; }
        $slots = self::get_all_slots();
        $id    = 'slot_' . wp_generate_password(8, false, false);
        $slots[] = array(
            'id'      => $id,
            'name'    => $type === 'tolstoy' ? __('Tolstoy widget', 'ai-eshop-optimizer') : __('Custom block', 'ai-eshop-optimizer'),
            'type'    => $type,
            'enabled' => false, 
        );
        self::update_all_slots($slots);
        return $id;
    }

    
    public static function delete_slot($slot_id) {
        $slots = self::get_all_slots();
        $kept  = array();
        foreach ($slots as $row) {
            if ($row['id'] === $slot_id) { continue; }
            $kept[] = $row;
        }
        self::update_all_slots($kept);
    }

    
    
    

    
    public static function render_slot($slot_id) {
        $slot = self::get_slot((string) $slot_id);
        if (!$slot || empty($slot['enabled'])) { return ''; }

        
        
        
        
        
        
        $title_html = '';
        if (!empty($slot['show_title']) && trim((string) $slot['title']) !== '') {
            $title_html = '<h2 class="aieo-recommendations-title">' . esc_html((string) $slot['title']) . '</h2>';
        }

        $body_html = '';
        if ($slot['type'] === 'tolstoy') {
            $widget = trim((string) $slot['tolstoy_widget_id']);
            
            
            
            
            $widget = preg_replace('/[^A-Za-z0-9]/', '', $widget);
            if ($widget === '') {
                
                
                
                $raw_fallback = trim((string) $slot['raw_html']);
                if ($raw_fallback === '') { return ''; }
                $body_html = do_shortcode(apply_filters('aieo_dmm_custom_slot_html', $raw_fallback, $slot));
            } else {
                $product_id = function_exists('get_the_ID') ? (int) get_the_ID() : 0;
                $body_html = sprintf(
                    '<tolstoy-widget data-tolstoy-widget-id="%s" data-product-id="%d"></tolstoy-widget>',
                    esc_attr($widget),
                    $product_id
                );
            }
        } else {
            
            
            
            
            
            
            
            
            $raw = (string) $slot['raw_html'];
            
            $raw = apply_filters('aieo_dmm_custom_slot_html', $raw, $slot);
            $body_html = do_shortcode($raw);
        }

        if ($body_html === '') { return ''; }
        return $title_html . $body_html;
    }

    
    public function enqueue_tolstoy_scripts() {
        if (is_admin() || !function_exists('is_singular') || !is_singular('product')) { return; }

        
        
        
        
        $attr_path = AIEO_DIR . 'assets/js/aieo-tolstoy-attribution.js';
        $attr_ver  = file_exists($attr_path) ? (string) filemtime($attr_path) : (defined('AIEO_VERSION') ? AIEO_VERSION : '1.0');
        wp_enqueue_script(
            'aieo-tolstoy-attribution',
            AIEO_URI . 'assets/js/aieo-tolstoy-attribution.js',
            array(),
            $attr_ver,
            false 
                  
                  
                  
        );

        
        
        
        $seen_pairs = array();
        foreach (self::get_all_slots() as $slot) {
            if ($slot['type'] !== 'tolstoy' || empty($slot['enabled'])) { continue; }
            $widget = preg_replace('/[^A-Za-z0-9]/', '', (string) $slot['tolstoy_widget_id']);
            $uuid   = preg_replace('/[^A-Za-z0-9\-]/', '', (string) $slot['tolstoy_account_uuid']);
            if ($widget === '' || $uuid === '') { continue; }
            $key = $uuid . '|' . $widget;
            if (isset($seen_pairs[$key])) { continue; }
            $seen_pairs[$key] = true;

            $handle = 'aieo-tolstoy-' . md5($key);
            $src    = sprintf(
                'https://ai-widgets.gotolstoy.com/%s/%s/latest/dist/widget.iife.js',
                $uuid,
                $widget
            );
            wp_enqueue_script($handle, $src, array(), null, true);
            if (function_exists('wp_script_add_data')) {
                wp_script_add_data($handle, 'defer', true);
            }
        }
    }

    
    
    

    public function ajax_save() {
        AIEO_DMM::verify_ajax_request();
        $raw = isset($_POST['slots']) ? wp_unslash($_POST['slots']) : array();
        if (is_string($raw)) {
            
            
            $decoded = json_decode($raw, true);
            $raw = is_array($decoded) ? $decoded : array();
        }
        if (!is_array($raw)) { $raw = array(); }
        self::update_all_slots($raw);
        wp_send_json_success(array(
            'slots'   => self::get_all_slots(),
            'message' => __('Slots saved.', 'ai-eshop-optimizer'),
        ));
    }

    public function ajax_add() {
        AIEO_DMM::verify_ajax_request();
        $type = isset($_POST['type']) ? sanitize_key(wp_unslash($_POST['type'])) : 'html';
        $id   = self::add_slot($type);
        wp_send_json_success(array(
            'id'    => $id,
            'slots' => self::get_all_slots(),
        ));
    }

    public function ajax_delete() {
        AIEO_DMM::verify_ajax_request();
        $id = isset($_POST['id']) ? sanitize_key(wp_unslash($_POST['id'])) : '';
        if ($id !== '') { self::delete_slot($id); }
        wp_send_json_success(array(
            'slots' => self::get_all_slots(),
        ));
    }

    
    
    

    public function render_subtab() {
        $slots = self::get_all_slots();
        $nonce = wp_create_nonce(AIEO_DMM::NONCE_ACTION);
        $ajax  = admin_url('admin-ajax.php');

        echo '<div class="aieo-dmm-section">';
        echo '<h2>' . esc_html__('Custom Slots', 'ai-eshop-optimizer') . '</h2>';
        echo '<p class="description">' . esc_html__('Define extra content blocks that render inside the single-product recommendations region. Two kinds of slots: (1) Tolstoy — paste a widget id + account UUID and AIEO assembles the embed for you; (2) HTML/Code — paste any raw HTML, JavaScript, or shortcode (e.g. [products limit="6"]). Each slot appears as a draggable row in the "Recommendations Ordering" card on the Dashboard so you can position it among the built-in Up-sells / Cross-sells / Related / Recently Viewed / Same-Needs rails.', 'ai-eshop-optimizer') . '</p>';

        echo '<div id="aieo-cs-list" data-aieo-cs-list>';
        if (empty($slots)) {
            echo '<p style="padding:14px;background:#f8fafc;border:1px dashed #cbd5e1;border-radius:6px;color:#475569;">' . esc_html__('No custom slots yet. Use the buttons below to add one.', 'ai-eshop-optimizer') . '</p>';
        } else {
            foreach ($slots as $slot) {
                self::render_slot_row($slot);
            }
        }
        echo '</div>';

        echo '<p style="margin-top:14px;">';
        echo '<button type="button" class="button button-secondary" data-aieo-cs-add="tolstoy">' . esc_html__('+ Add Tolstoy slot', 'ai-eshop-optimizer') . '</button> ';
        echo '<button type="button" class="button button-secondary" data-aieo-cs-add="html">' . esc_html__('+ Add HTML / code slot', 'ai-eshop-optimizer') . '</button>';
        echo '</p>';

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

        
        
        echo '<script>(function(){
            var nonce = ' . wp_json_encode($nonce) . ';
            var ajaxUrl = ' . wp_json_encode($ajax) . ';
            var listEl = document.getElementById("aieo-cs-list");
            var statusEl = document.getElementById("aieo-cs-status");

            function gather() {
                // Sync TinyMCE editors back to their underlying
                // textareas so the values we read below are current.
                // Without this, Visual-mode edits live only inside the
                // iframe and our textarea reads return the value at
                // load time — losing every change the operator made.
                if (typeof window.tinyMCE !== "undefined" && window.tinyMCE && typeof window.tinyMCE.triggerSave === "function") {
                    try { window.tinyMCE.triggerSave(); } catch (e) {}
                }
                var rows = listEl.querySelectorAll("[data-aieo-cs-slot]");
                var out = [];
                rows.forEach(function(row){
                    var slot = { id: row.getAttribute("data-aieo-cs-slot") };
                    row.querySelectorAll("[data-field]").forEach(function(input){
                        var key = input.getAttribute("data-field");
                        if (input.type === "checkbox") { slot[key] = input.checked; }
                        else { slot[key] = input.value; }
                    });
                    // HTML slot uses wp_editor — read the underlying
                    // textarea by its known ID pattern. The wrap div
                    // exposes the editor id via data-editor-id so the
                    // lookup is local to this row (no ambiguity if
                    // multiple slots are on the page).
                    var ed = row.querySelector(".aieo-cs-editor-wrap[data-editor-id]");
                    if (ed) {
                        var ta = document.getElementById(ed.getAttribute("data-editor-id"));
                        if (ta) { slot.raw_html = ta.value; }
                    }
                    out.push(slot);
                });
                return out;
            }

            function postForm(data) {
                var fd = new FormData();
                Object.keys(data).forEach(function(k){ fd.set(k, data[k]); });
                fd.set("nonce", nonce);
                return fetch(ajaxUrl, { method:"POST", credentials:"same-origin", body:fd }).then(function(r){ return r.json(); });
            }

            document.getElementById("aieo-cs-save").addEventListener("click", function(){
                statusEl.style.color = "#646970";
                statusEl.textContent = ' . wp_json_encode(__('Saving…', 'ai-eshop-optimizer')) . ';
                postForm({ action:"aieo_dmm_custom_slots_save", slots: JSON.stringify(gather()) }).then(function(j){
                    if (j && j.success) {
                        statusEl.style.color = "#15803d";
                        statusEl.textContent = j.data.message;
                    } else {
                        statusEl.style.color = "#b91c1c";
                        statusEl.textContent = (j && j.data && j.data.message) || ' . wp_json_encode(__('Save failed.', 'ai-eshop-optimizer')) . ';
                    }
                });
            });

            document.querySelectorAll("[data-aieo-cs-add]").forEach(function(btn){
                btn.addEventListener("click", function(){
                    var type = btn.getAttribute("data-aieo-cs-add");
                    postForm({ action:"aieo_dmm_custom_slots_add", type: type }).then(function(j){
                        if (j && j.success) { window.location.reload(); }
                    });
                });
            });

            listEl.addEventListener("click", function(e){
                var del = e.target.closest("[data-aieo-cs-delete]");
                if (!del) return;
                if (!confirm(' . wp_json_encode(__('Delete this slot?', 'ai-eshop-optimizer')) . ')) return;
                var id = del.getAttribute("data-aieo-cs-delete");
                postForm({ action:"aieo_dmm_custom_slots_delete", id: id }).then(function(j){
                    if (j && j.success) {
                        var row = listEl.querySelector("[data-aieo-cs-slot=\\""+id+"\\"]");
                        if (row) row.remove();
                    }
                });
            });
        })();</script>';

        echo '</div>';
    }

    
    private static function render_slot_row($slot) {
        $id   = (string) $slot['id'];
        $type = (string) $slot['type'];
        echo '<div data-aieo-cs-slot="' . esc_attr($id) . '" class="aieo-dmm-card" style="margin-top:12px;padding:14px;">';
        echo '<div style="display:flex;align-items:center;gap:10px;margin-bottom:12px;">';
        echo '<strong style="flex:1;">' . esc_html($type === 'tolstoy' ? __('Tolstoy slot', 'ai-eshop-optimizer') : __('HTML / code slot', 'ai-eshop-optimizer')) . '</strong>';
        echo '<code style="background:#f1f5f9;padding:2px 6px;border-radius:3px;color:#475569;font-size:11px;">' . esc_html($id) . '</code>';
        echo '<button type="button" class="button button-link-delete" data-aieo-cs-delete="' . esc_attr($id) . '">' . esc_html__('Delete', 'ai-eshop-optimizer') . '</button>';
        echo '</div>';

        echo '<table class="form-table" style="margin:0;"><tbody>';

        
        echo '<tr style="display:none;"><th></th><td><input type="text" data-field="type" value="' . esc_attr($type) . '"></td></tr>';

        echo '<tr><th><label>' . esc_html__('Name', 'ai-eshop-optimizer') . '</label></th><td>';
        echo '<input type="text" data-field="name" value="' . esc_attr((string) $slot['name']) . '" class="regular-text" placeholder="' . esc_attr__('Internal label, shown in the Recommendations Ordering list', 'ai-eshop-optimizer') . '">';
        echo '</td></tr>';

        echo '<tr><th><label>' . esc_html__('Enabled', 'ai-eshop-optimizer') . '</label></th><td>';
        echo '<label><input type="checkbox" data-field="enabled" ' . checked(!empty($slot['enabled']), true, false) . '> ' . esc_html__('Render this slot on single-product pages', 'ai-eshop-optimizer') . '</label>';
        echo '</td></tr>';

        
        
        
        
        echo '<tr><th><label>' . esc_html__('Title', 'ai-eshop-optimizer') . '</label></th><td>';
        echo '<input type="text" data-field="title" value="' . esc_attr((string) $slot['title']) . '" class="regular-text" placeholder="' . esc_attr__('e.g. "Στιγμές που πρέπει να δεις"', 'ai-eshop-optimizer') . '">';
        echo '<p class="description">' . esc_html__('Operator-set heading rendered above the slot content. Styled identically to the built-in "RECENTLY VIEWED PRODUCTS" / "PRODUCTS FOR THE SAME NEEDS" titles (heading + underline) via the shared aieo-recommendations-title class.', 'ai-eshop-optimizer') . '</p>';
        echo '</td></tr>';

        echo '<tr><th><label>' . esc_html__('Show title', 'ai-eshop-optimizer') . '</label></th><td>';
        echo '<label><input type="checkbox" data-field="show_title" ' . checked(!empty($slot['show_title']), true, false) . '> ' . esc_html__('Display the title above this slot', 'ai-eshop-optimizer') . '</label>';
        echo '</td></tr>';

        if ($type === 'tolstoy') {
            echo '<tr><th><label>' . esc_html__('Widget ID', 'ai-eshop-optimizer') . '</label></th><td>';
            echo '<input type="text" data-field="tolstoy_widget_id" value="' . esc_attr((string) $slot['tolstoy_widget_id']) . '" class="regular-text" placeholder="01HZ7XMP3VBQR8TKWY5JCDFN24">';
            echo '<p class="description">' . esc_html__('The base32 ID inside data-tolstoy-widget-id="…" on the embed snippet gotolstoy.com gives you.', 'ai-eshop-optimizer') . '</p>';
            echo '</td></tr>';

            echo '<tr><th><label>' . esc_html__('Account UUID', 'ai-eshop-optimizer') . '</label></th><td>';
            echo '<input type="text" data-field="tolstoy_account_uuid" value="' . esc_attr((string) $slot['tolstoy_account_uuid']) . '" class="regular-text" placeholder="a7c2f1e4-9b53-4d6e-bc01-5f8e7a3c2b94">';
            echo '<p class="description">' . esc_html__('The UUID at the start of the script URL — https://ai-widgets.gotolstoy.com/<this part>/<widget-id>/… — without https:// or any slashes.', 'ai-eshop-optimizer') . '</p>';
            echo '</td></tr>';

            echo '<tr><th><label>' . esc_html__('Or paste the full snippet', 'ai-eshop-optimizer') . '</label></th><td>';
            echo '<textarea data-field="raw_html" rows="4" class="large-text code" placeholder="' . esc_attr__('Paste the entire <tolstoy-widget …></tolstoy-widget><script …></script> block here as a shortcut. AIEO will not auto-fill the two fields above from it — they take precedence at render time.', 'ai-eshop-optimizer') . '">' . esc_textarea((string) $slot['raw_html']) . '</textarea>';
            echo '<p class="description">' . esc_html__('Optional shortcut. If you fill in Widget ID + Account UUID above, AIEO ignores this field. Useful when you have a one-off snippet that doesn\'t follow the standard URL shape.', 'ai-eshop-optimizer') . '</p>';
            echo '</td></tr>';
        } else {
            
            
            
            
            
            
            
            $editor_id = 'aieo_cs_editor_' . sanitize_key($id);
            echo '<tr><th><label>' . esc_html__('HTML / rich text / code', 'ai-eshop-optimizer') . '</label></th><td>';
            echo '<div class="aieo-cs-editor-wrap" data-editor-id="' . esc_attr($editor_id) . '">';
            wp_editor(
                (string) $slot['raw_html'],
                $editor_id,
                array(
                    'textarea_name' => $editor_id, 
                    'media_buttons' => true,
                    'teeny'         => false,
                    'textarea_rows' => 8,
                    'tinymce'       => array(
                        
                        
                        
                        
                        'wpautop'                 => false,
                        'forced_root_block'       => false,
                        'force_br_newlines'       => false,
                        'force_p_newlines'        => false,
                        'verify_html'             => false,
                        
                        
                        
                        'extended_valid_elements' => '*[*]',
                    ),
                    'quicktags'     => true,
                    'editor_height' => 240,
                )
            );
            echo '</div>';
            echo '<p class="description">' . esc_html__('Switch between Visual (rich text) and Text (raw HTML / code) tabs at the top right of the editor. Shortcodes like [products limit="6"] are processed at render time. Custom elements (e.g. <tolstoy-widget>) and <script> tags survive the round-trip — wpautop is disabled for this editor. The aieo_dmm_custom_slot_html filter is the per-site security knob if you want to wrap kses().', 'ai-eshop-optimizer') . '</p>';
            echo '</td></tr>';
        }

        echo '</tbody></table>';
        echo '</div>';
    }
}
