<?php

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

class AIEO_Competition_CPT {

    const POST_TYPE = 'aieo_competition';

    const META_GF        = '_aieo_comp_gf_form_id';
    const META_SHORTDESC = '_aieo_comp_short_desc';
    const META_IMG_DESK  = '_aieo_comp_image_desktop';
    const META_IMG_MOB   = '_aieo_comp_image_mobile';
    const META_TNP_LIST  = '_aieo_comp_tnp_list_id'; 
    const META_START     = '_aieo_comp_start';       
    const META_END       = '_aieo_comp_end';         

    
    const META_BRANDS        = '_aieo_comp_brands';        
    const META_CATEGORIES    = '_aieo_comp_categories';    
    const META_PRODUCTS      = '_aieo_comp_products';      
    const META_WINNERS_COUNT = '_aieo_comp_winners_count'; 
    const META_PRIZE_VALUE   = '_aieo_comp_prize_value';   

    
    const META_ANNOUNCE_AT     = '_aieo_comp_announce_at';          
    const META_WINNERS_ANNOUNCE = '_aieo_comp_winners_announcement'; 

    private static $registered = false;

    public static function register() {
        if (self::$registered) { return; }
        self::$registered = true;
        add_action('init', array(__CLASS__, 'register_cpt'));
        if (is_admin()) {
            add_action('add_meta_boxes', array(__CLASS__, 'add_metabox'));
            add_action('save_post_' . self::POST_TYPE, array(__CLASS__, 'save_metabox'), 10, 2);
            add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueue_editor_assets'));
        }
    }

    
    public static function enqueue_editor_assets() {
        $screen = function_exists('get_current_screen') ? get_current_screen() : null;
        if (!$screen || $screen->post_type !== self::POST_TYPE) { return; }
        if (!defined('AIEO_FILE')) { return; }
        wp_enqueue_media();
        wp_enqueue_script(
            'aieo-competitions-admin',
            plugins_url('assets/js/aieo-competitions-admin.js', AIEO_FILE),
            array('jquery'),
            defined('AIEO_VERSION') ? AIEO_VERSION : '1.0',
            true
        );
        wp_localize_script('aieo-competitions-admin', 'aieoCompetitions', array(
            'ajaxurl' => admin_url('admin-ajax.php'),
            'nonce'   => wp_create_nonce('aieo_competitions'),
            'i18n'    => array(
                'select'       => __('Select image', 'ai-eshop-optimizer'),
                'use'          => __('Use this image', 'ai-eshop-optimizer'),
                'copied'       => __('Copied!', 'ai-eshop-optimizer'),
                'saving'       => __('Drawing…', 'ai-eshop-optimizer'),
                'removeWinner' => __('Remove winner', 'ai-eshop-optimizer'),
            ),
        ));

        
        
        self::enqueue_picker_bundle();
    }

    
    private static function enqueue_picker_bundle() {
        if (!defined('AIEO_URI') || !defined('AIEO_DIR')) { return; }
        foreach (array('select2', 'selectWoo') as $h) { if (wp_script_is($h, 'registered')) { wp_enqueue_script($h); break; } }
        foreach (array('select2', 'selectWoo') as $h) { if (wp_style_is($h, 'registered'))  { wp_enqueue_style($h);  break; } }
        wp_enqueue_script('jquery-ui-sortable');
        $dmm_js = AIEO_DIR . 'assets/js/dmm.js';
        wp_enqueue_script('aieo-dmm', AIEO_URI . 'assets/js/dmm.js', array('jquery', 'jquery-ui-sortable'), file_exists($dmm_js) ? (string) filemtime($dmm_js) : (defined('AIEO_VERSION') ? AIEO_VERSION : '1.0'), true);
        $dmm_css = AIEO_DIR . 'assets/css/dmm.css';
        if (file_exists($dmm_css)) { wp_enqueue_style('aieo-dmm', AIEO_URI . 'assets/css/dmm.css', array(), (string) filemtime($dmm_css)); }
        if (class_exists('AIEO_DMM_Product_Picker')) { AIEO_DMM_Product_Picker::enqueue_assets(); }
        wp_localize_script('aieo-dmm', 'aieoDmm', array(
            'ajaxurl'   => admin_url('admin-ajax.php'),
            'nonce'     => wp_create_nonce('aieo_dmm_nonce'),
            'activeTab' => '',
            'i18n'      => array(
                'pickBrands'      => __('Pick brand(s)…', 'ai-eshop-optimizer'),
                'pickCategories'  => __('Pick categories…', 'ai-eshop-optimizer'),
                'pickNeeds'       => __('Pick needs…', 'ai-eshop-optimizer'),
                'searchByNameSku' => __('Search by name or SKU…', 'ai-eshop-optimizer'),
                'picker'          => array(
                    'deleted'    => __('deleted', 'ai-eshop-optimizer'),
                    'draft'      => __('draft', 'ai-eshop-optimizer'),
                    'variations' => __('variations', 'ai-eshop-optimizer'),
                    'searching'  => __('Searching…', 'ai-eshop-optimizer'),
                    'none'       => __('No products found.', 'ai-eshop-optimizer'),
                    'failed'     => __('Search failed.', 'ai-eshop-optimizer'),
                    'loadingV'   => __('Loading variations…', 'ai-eshop-optimizer'),
                    'noV'        => __('No variations.', 'ai-eshop-optimizer'),
                    'failV'      => __('Failed to load variations.', 'ai-eshop-optimizer'),
                    'cancel'     => __('Cancel', 'ai-eshop-optimizer'),
                    'done'       => __('Done', 'ai-eshop-optimizer'),
                    'ph'         => __('Search products by name or SKU…', 'ai-eshop-optimizer'),
                    'selOne'     => __('item selected', 'ai-eshop-optimizer'),
                    'selMany'    => __('items selected', 'ai-eshop-optimizer'),
                    'titleInc'   => __('Choose products to INCLUDE', 'ai-eshop-optimizer'),
                    'titleExc'   => __('Choose products to EXCLUDE', 'ai-eshop-optimizer'),
                    'remove'     => __('Remove', 'ai-eshop-optimizer'),
                ),
            ),
        ));
    }

    
    private static function term_select($name, $css_class, $selected_ids, $width = '100%') {
        $out = '<select name="' . esc_attr($name) . '[]" multiple class="' . esc_attr($css_class) . ' regular-text" style="width:' . esc_attr($width) . ';max-width:520px;">';
        foreach ((array) $selected_ids as $tid) {
            $tid = (int) $tid;
            if ($tid <= 0) { continue; }
            $term = get_term($tid);
            if (!$term || is_wp_error($term)) { continue; }
            $out .= '<option value="' . esc_attr((string) $tid) . '" selected>' . esc_html($term->name) . '</option>';
        }
        $out .= '</select>';
        return $out;
    }

    public static function register_cpt() {
        register_post_type(self::POST_TYPE, array(
            'labels'       => array(
                'name'          => __('Competitions', 'ai-eshop-optimizer'),
                'singular_name' => __('Competition', 'ai-eshop-optimizer'),
                'add_new_item'  => __('Add Competition', 'ai-eshop-optimizer'),
                'edit_item'     => __('Edit Competition', 'ai-eshop-optimizer'),
                'menu_name'     => __('Competitions', 'ai-eshop-optimizer'),
            ),
            'public'       => true,
            'show_in_rest' => true, 
            'has_archive'  => true,
            'menu_icon'    => 'dashicons-awards',
            
            
            
            'show_in_menu' => false,
            'supports'     => array('title', 'editor', 'thumbnail', 'excerpt', 'custom-fields', 'page-attributes'),
            'rewrite'      => array('slug' => 'competitions', 'with_front' => false),
        ));

        register_post_meta(self::POST_TYPE, self::META_GF, array(
            'type' => 'integer', 'single' => true, 'show_in_rest' => true,
            'auth_callback' => static function () { return current_user_can('edit_posts'); },
        ));
        register_post_meta(self::POST_TYPE, self::META_SHORTDESC, array(
            'type' => 'string', 'single' => true, 'show_in_rest' => true,
            'auth_callback' => static function () { return current_user_can('edit_posts'); },
        ));
        foreach (array(self::META_IMG_DESK, self::META_IMG_MOB) as $key) {
            register_post_meta(self::POST_TYPE, $key, array(
                'type' => 'integer', 'single' => true, 'show_in_rest' => true,
                'auth_callback' => static function () { return current_user_can('edit_posts'); },
            ));
        }
        foreach (array(self::META_START, self::META_END, self::META_ANNOUNCE_AT) as $key) {
            register_post_meta(self::POST_TYPE, $key, array(
                'type' => 'string', 'single' => true, 'show_in_rest' => true,
                'auth_callback' => static function () { return current_user_can('edit_posts'); },
            ));
        }
        register_post_meta(self::POST_TYPE, self::META_WINNERS_ANNOUNCE, array(
            'type' => 'string', 'single' => true, 'show_in_rest' => true,
            'sanitize_callback' => static function ($v) { return wp_kses_post((string) $v); },
            'auth_callback' => static function () { return current_user_can('edit_posts'); },
        ));
        foreach (array(self::META_BRANDS, self::META_CATEGORIES, self::META_PRODUCTS) as $key) {
            register_post_meta(self::POST_TYPE, $key, array(
                'type' => 'array', 'single' => true,
                'show_in_rest' => array('schema' => array('type' => 'array', 'items' => array('type' => 'integer'))),
                'auth_callback' => static function () { return current_user_can('edit_posts'); },
            ));
        }
        register_post_meta(self::POST_TYPE, self::META_WINNERS_COUNT, array(
            'type' => 'integer', 'single' => true, 'show_in_rest' => true,
            'auth_callback' => static function () { return current_user_can('edit_posts'); },
        ));
        register_post_meta(self::POST_TYPE, self::META_PRIZE_VALUE, array(
            'type' => 'number', 'single' => true, 'show_in_rest' => true,
            'auth_callback' => static function () { return current_user_can('edit_posts'); },
        ));

        
        
        if (!get_option('aieo_competition_cpt_flushed')) {
            update_option('aieo_competition_cpt_flushed', 1, false);
            flush_rewrite_rules(false);
        }
    }

    

    public static function add_metabox() {
        add_meta_box(
            'aieo-competition-details',
            __('Competition details', 'ai-eshop-optimizer'),
            array(__CLASS__, 'render_metabox'),
            self::POST_TYPE,
            'normal',
            'high'
        );
        add_meta_box(
            'aieo-competition-announcement',
            __('🏆 Winners announcement', 'ai-eshop-optimizer'),
            array(__CLASS__, 'render_announcement_metabox'),
            self::POST_TYPE,
            'normal',
            'high'
        );
        add_meta_box(
            'aieo-competition-winners',
            __('Competition winners', 'ai-eshop-optimizer'),
            array(__CLASS__, 'render_winners_metabox'),
            self::POST_TYPE,
            'side',
            'default'
        );
        add_meta_box(
            'aieo-competition-insights',
            __('Competition insights', 'ai-eshop-optimizer'),
            array(__CLASS__, 'render_insights_metabox'),
            self::POST_TYPE,
            'side',
            'low'
        );
    }

    
    public static function render_insights_metabox($post) {
        if (!class_exists('AIEO_Competition_Analytics')) {
            echo '<p class="description">' . esc_html__('Analytics unavailable.', 'ai-eshop-optimizer') . '</p>';
            return;
        }
        $i   = AIEO_Competition_Analytics::insights($post->ID);
        $m   = $i['metrics'];
        $cur = function_exists('get_woocommerce_currency_symbol') ? get_woocommerce_currency_symbol() : '';
        $entries = (int) $m['entries'];
        $conv    = $entries > 0 ? round(100 * (int) $i['converting_entrants'] / $entries, 1) : 0;

        echo '<ul style="margin:0;list-style:disc;padding-left:18px;">';
        echo '<li>' . esc_html__('Entries', 'ai-eshop-optimizer') . ': <strong>' . $entries . '</strong> <span style="color:#646970;">(' . (int) $m['confirmed'] . ' ' . esc_html__('confirmed', 'ai-eshop-optimizer') . ')</span></li>';
        echo '<li>' . esc_html__('Winners', 'ai-eshop-optimizer') . ': <strong>' . (int) $m['winners'] . '</strong></li>';
        if (!empty($i['has_order_data'])) {
            echo '<li>' . esc_html__('Entrants who ordered', 'ai-eshop-optimizer') . ': <strong>' . (int) $i['converting_entrants'] . '</strong> <span style="color:#646970;">(' . esc_html((string) $conv) . '%)</span></li>';
            echo '<li>' . esc_html__('Revenue from entrants', 'ai-eshop-optimizer') . ': <strong>' . esc_html($cur . number_format_i18n((float) $i['entrant_revenue'], 2)) . '</strong></li>';
        } else {
            echo '<li class="description">' . esc_html__('Order analytics not available yet.', 'ai-eshop-optimizer') . '</li>';
        }
        if ((int) $i['assoc_products'] > 0) {
            echo '<li style="margin-top:6px;"><em>' . esc_html(sprintf(__('Associated-product pull (%d products)', 'ai-eshop-optimizer'), (int) $i['assoc_products'])) . '</em></li>';
            if (!empty($i['has_order_data'])) {
                echo '<li>' . esc_html__('Units sold to entrants', 'ai-eshop-optimizer') . ': <strong>' . (int) $i['pull_units'] . '</strong></li>';
                echo '<li>' . esc_html__('Pull revenue', 'ai-eshop-optimizer') . ': <strong>' . esc_html($cur . number_format_i18n((float) $i['pull_revenue'], 2)) . '</strong></li>';
            }
        } else {
            echo '<li class="description">' . esc_html__('Link products / brands / categories above to track their pull.', 'ai-eshop-optimizer') . '</li>';
        }
        echo '</ul>';
    }

    
    public static function render_winners_metabox($post) {
        if (!class_exists('AIEO_Competition_Participants')) {
            echo '<p class="description">' . esc_html__('Participants are unavailable.', 'ai-eshop-optimizer') . '</p>';
            return;
        }
        $target   = max(1, (int) get_post_meta($post->ID, self::META_WINNERS_COUNT, true));
        $m        = AIEO_Competition_Participants::metrics($post->ID);
        $eligible = method_exists('AIEO_Competition_Participants', 'eligible_count') ? AIEO_Competition_Participants::eligible_count($post->ID) : (int) $m['confirmed'];
        $winners  = AIEO_Competition_Participants::get_winners($post->ID);

        echo '<div id="aieo-comp-winners-box" data-comp="' . (int) $post->ID . '" data-target="' . (int) $target . '">';
        echo '<p class="description">' . esc_html(sprintf(
            
            __('%1$d eligible of %2$d confirmed. Winners exclude anyone who has already won and are weighted by how many competitions each person entered (more entries → more chances).', 'ai-eshop-optimizer'),
            (int) $eligible, (int) $m['confirmed']
        )) . '</p>';
        echo '<p><button type="button" class="button button-primary" id="aieo-comp-draw-winners">' . esc_html(sprintf(
            
            _n('🎲 Draw %d winner', '🎲 Draw %d winners', $target, 'ai-eshop-optimizer'),
            $target
        )) . '</button> <span id="aieo-comp-winners-status" style="margin-left:8px;color:#646970;"></span></p>';
        echo '<ul id="aieo-comp-winners-list" style="margin:8px 0 0;">';
        foreach ($winners as $w) {
            echo self::winner_li($w); 
        }
        echo '</ul>';
        echo '<p class="description" style="margin-top:8px;">' . esc_html__('Drawing again replaces the current winners. Set the number of winners in “Competition details”. Write the public message in the “🏆 Winners announcement” box.', 'ai-eshop-optimizer') . '</p>';
        echo '</div>';
    }

    
    private static function winner_li($w) {
        $name = trim((string) ($w->first_name ?? '') . ' ' . (string) ($w->last_name ?? ''));
        return '<li data-pid="' . (int) $w->participant_id . '" style="margin:0 0 6px;padding:6px 8px;background:#f6f7f7;border-radius:4px;">'
            . '<strong>' . esc_html($name !== '' ? $name : '—') . '</strong> '
            . '<span style="color:#646970;">' . esc_html((string) $w->email) . '</span> '
            . '<button type="button" class="button-link aieo-comp-winner-remove" title="' . esc_attr__('Remove winner', 'ai-eshop-optimizer') . '" style="color:#b32d2e;float:right;">×</button>'
            . '</li>';
    }

    
    public static function render_announcement_metabox($post) {
        $announce_html = (string) get_post_meta($post->ID, self::META_WINNERS_ANNOUNCE, true);
        echo '<p class="description" style="margin-top:0;">' . esc_html__('Shown on the public competition page once it has ENDED, below the 🏆 winners list. Congratulate the winners, add photos, prize details, claim/redemption instructions, etc. Draw the winners in the “Competition winners” box (right) first.', 'ai-eshop-optimizer') . '</p>';
        wp_editor($announce_html, 'aieocompwinnersannouncement', array(
            'textarea_name' => 'aieo_comp_winners_announcement',
            'textarea_rows' => 8,
            'media_buttons' => true,
            'teeny'         => false,
            'tinymce'       => true,
            'quicktags'     => true,
        ));
    }

    public static function render_metabox($post) {
        wp_nonce_field('aieo_comp_meta', 'aieo_comp_meta_nonce');
        $gf_id   = (int) get_post_meta($post->ID, self::META_GF, true);
        $desc    = (string) get_post_meta($post->ID, self::META_SHORTDESC, true);
        $img_d   = (int) get_post_meta($post->ID, self::META_IMG_DESK, true);
        $img_m   = (int) get_post_meta($post->ID, self::META_IMG_MOB, true);
        $start    = (string) get_post_meta($post->ID, self::META_START, true);
        $end      = (string) get_post_meta($post->ID, self::META_END, true);
        $announce = (string) get_post_meta($post->ID, self::META_ANNOUNCE_AT, true);

        echo '<p><label for="aieo_comp_gf"><strong>' . esc_html__('Gravity Form', 'ai-eshop-optimizer') . '</strong></label><br>';
        echo self::gf_form_select('aieo_comp_gf', $gf_id); 
        echo '<br><span class="description">' . esc_html__('The entry form for this competition (participants submit via this form).', 'ai-eshop-optimizer') . '</span></p>';

        echo '<p><label for="aieo_comp_desc"><strong>' . esc_html__('Short description', 'ai-eshop-optimizer') . '</strong></label><br>';
        echo '<textarea id="aieo_comp_desc" name="aieo_comp_desc" rows="3" style="width:100%;">' . esc_textarea($desc) . '</textarea></p>';

        echo '<div style="display:flex;gap:24px;flex-wrap:wrap;">';
        self::render_image_field('desktop', 'aieo_comp_img_desktop', __('Desktop image', 'ai-eshop-optimizer'), $img_d);
        self::render_image_field('mobile', 'aieo_comp_img_mobile', __('Mobile image', 'ai-eshop-optimizer'), $img_m);
        echo '</div>';

        echo '<p style="display:flex;gap:24px;flex-wrap:wrap;margin-top:16px;">';
        echo '<label style="flex:1;min-width:200px;"><strong>' . esc_html__('Starts', 'ai-eshop-optimizer') . '</strong><br><input type="datetime-local" name="aieo_comp_start" value="' . esc_attr(self::to_input($start)) . '" style="width:100%;"></label>';
        echo '<label style="flex:1;min-width:200px;"><strong>' . esc_html__('Ends', 'ai-eshop-optimizer') . '</strong><br><input type="datetime-local" name="aieo_comp_end" value="' . esc_attr(self::to_input($end)) . '" style="width:100%;"></label>';
        echo '<label style="flex:1;min-width:200px;"><strong>' . esc_html__('Winners announced', 'ai-eshop-optimizer') . '</strong><br><input type="datetime-local" name="aieo_comp_announce" value="' . esc_attr(self::to_input($announce)) . '" style="width:100%;"></label>';
        echo '</p>';
        echo '<p class="description">' . esc_html__('Optional. Before the start, visitors see a “coming soon” notice; after the end, an “ended” message. Shop managers always see the live form (preview). Leave start/end empty for an always-open competition. “Winners announced” drives the “winners will be announced on …” message and the Events timeline.', 'ai-eshop-optimizer') . '</p>';

        
        $brands  = (array) get_post_meta($post->ID, self::META_BRANDS, true);
        $cats    = (array) get_post_meta($post->ID, self::META_CATEGORIES, true);
        $prods   = array_map('intval', (array) get_post_meta($post->ID, self::META_PRODUCTS, true));
        $winners = (int) get_post_meta($post->ID, self::META_WINNERS_COUNT, true);
        $prize   = (string) get_post_meta($post->ID, self::META_PRIZE_VALUE, true);
        $cur     = function_exists('get_woocommerce_currency_symbol') ? get_woocommerce_currency_symbol() : '';

        echo '<hr style="margin:18px 0;">';
        echo '<p><strong>' . esc_html__('Associated brands / categories / products', 'ai-eshop-optimizer') . '</strong><br><span class="description">' . esc_html__('Optional. Used to monitor which products this competition drives (its “pull”). The same pickers as the discount pages.', 'ai-eshop-optimizer') . '</span></p>';

        echo '<p><label><strong>' . esc_html__('Brands', 'ai-eshop-optimizer') . '</strong></label><br>';
        echo self::term_select('aieo_comp_brands', 'aieo-dmm-brand-select', $brands); 
        echo '</p>';

        echo '<p><label><strong>' . esc_html__('Categories', 'ai-eshop-optimizer') . '</strong></label><br>';
        echo self::term_select('aieo_comp_categories', 'aieo-dmm-category-select', $cats); 
        echo '</p>';

        if (class_exists('AIEO_DMM_Product_Picker')) {
            echo '<p><label><strong>' . esc_html__('Products', 'ai-eshop-optimizer') . '</strong></label></p>';
            echo AIEO_DMM_Product_Picker::render_field(array( 
                'name'       => 'aieo_comp_products',
                'mode'       => 'include',
                'selected'   => $prods,
                'help'       => __('Specific products associated with this competition.', 'ai-eshop-optimizer'),
                'empty_text' => __('No products associated.', 'ai-eshop-optimizer'),
            ));
        }

        echo '<p style="display:flex;gap:24px;flex-wrap:wrap;margin-top:12px;">';
        echo '<label style="flex:1;min-width:180px;"><strong>' . esc_html__('Number of winners', 'ai-eshop-optimizer') . '</strong><br><input type="number" min="0" step="1" name="aieo_comp_winners_count" value="' . esc_attr((string) $winners) . '" style="width:120px;"></label>';
        echo '<label style="flex:1;min-width:180px;"><strong>' . esc_html(trim(sprintf(__('Prize value per winner %s', 'ai-eshop-optimizer'), $cur !== '' ? '(' . $cur . ')' : ''))) . '</strong><br><input type="number" min="0" step="0.01" name="aieo_comp_prize_value" value="' . esc_attr($prize) . '" style="width:140px;"></label>';
        echo '</p>';
        echo '<p class="description">' . esc_html__('e.g. 3 winners, prize value 50 each → total prize pool 150. Use the prize value when the prize is a bag of products rather than one SKU.', 'ai-eshop-optimizer') . '</p>';
        echo '<p class="description" style="margin-top:10px;"><em>' . esc_html__('Tip: the public winners announcement (rich text) is in its own “🏆 Winners announcement” box, just below this one.', 'ai-eshop-optimizer') . '</em></p>';

        if ($post->ID && get_post_status($post) === 'publish') {
            $links = self::share_links($post->ID);
            echo '<p style="margin-top:14px;"><strong>' . esc_html__('Share links', 'ai-eshop-optimizer') . '</strong></p><ul style="margin:0;">';
            foreach ($links as $net => $url) {
                echo '<li><code style="font-size:12px;">' . esc_html(ucfirst($net)) . ':</code> <input type="text" readonly value="' . esc_attr($url) . '" style="width:70%;" onclick="this.select();"></li>';
            }
            echo '</ul>';
        }
    }

    
    private static function render_image_field($which, $name, $label, $attachment_id) {
        $url = $attachment_id ? wp_get_attachment_image_url($attachment_id, 'medium') : '';
        echo '<div class="aieo-comp-image-field" data-which="' . esc_attr($which) . '" style="flex:1;min-width:220px;">';
        echo '<label><strong>' . esc_html($label) . '</strong></label><br>';
        echo '<img class="aieo-comp-image-preview" src="' . esc_url($url) . '" style="max-width:100%;height:auto;border:1px solid #dcdcde;border-radius:6px;' . ($url ? '' : 'display:none;') . '"><br>';
        echo '<input type="hidden" class="aieo-comp-image-id" name="' . esc_attr($name) . '" value="' . esc_attr((int) $attachment_id) . '">';
        echo '<button type="button" class="button aieo-comp-image-select">' . esc_html__('Select image', 'ai-eshop-optimizer') . '</button> ';
        echo '<button type="button" class="button-link aieo-comp-image-remove"' . ($url ? '' : ' style="display:none;"') . '>' . esc_html__('Remove', 'ai-eshop-optimizer') . '</button>';
        echo '</div>';
    }

    public static function save_metabox($post_id, $post) {
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; }
        if (!isset($_POST['aieo_comp_meta_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['aieo_comp_meta_nonce'])), 'aieo_comp_meta')) { return; }
        if (!current_user_can('edit_post', $post_id)) { return; }

        $gf    = isset($_POST['aieo_comp_gf']) ? (int) $_POST['aieo_comp_gf'] : 0;
        $desc  = isset($_POST['aieo_comp_desc']) ? sanitize_textarea_field(wp_unslash($_POST['aieo_comp_desc'])) : '';
        $img_d = isset($_POST['aieo_comp_img_desktop']) ? (int) $_POST['aieo_comp_img_desktop'] : 0;
        $img_m = isset($_POST['aieo_comp_img_mobile']) ? (int) $_POST['aieo_comp_img_mobile'] : 0;
        $start = isset($_POST['aieo_comp_start']) ? sanitize_text_field(wp_unslash($_POST['aieo_comp_start'])) : '';
        $end   = isset($_POST['aieo_comp_end'])   ? sanitize_text_field(wp_unslash($_POST['aieo_comp_end']))   : '';
        $announce = isset($_POST['aieo_comp_announce']) ? sanitize_text_field(wp_unslash($_POST['aieo_comp_announce'])) : '';

        $brands     = isset($_POST['aieo_comp_brands'])     ? array_map('intval', (array) wp_unslash($_POST['aieo_comp_brands']))     : array();
        $categories = isset($_POST['aieo_comp_categories']) ? array_map('intval', (array) wp_unslash($_POST['aieo_comp_categories'])) : array();
        $products   = class_exists('AIEO_DMM_Product_Picker')
            ? AIEO_DMM_Product_Picker::roll_up_to_parents(AIEO_DMM_Product_Picker::collect_ids('aieo_comp_products'))
            : (isset($_POST['aieo_comp_products']) ? array_map('intval', (array) wp_unslash($_POST['aieo_comp_products'])) : array());
        $winners    = isset($_POST['aieo_comp_winners_count']) ? (int) $_POST['aieo_comp_winners_count'] : 0;
        $prize      = isset($_POST['aieo_comp_prize_value'])   ? (float) $_POST['aieo_comp_prize_value']   : 0;

        self::persist_fields($post_id, $gf, $desc, $img_d, $img_m, $start, $end, $brands, $categories, $products, $winners, $prize, $announce);

        
        if (isset($_POST['aieo_comp_winners_announcement'])) {
            update_post_meta($post_id, self::META_WINNERS_ANNOUNCE, wp_kses_post(wp_unslash($_POST['aieo_comp_winners_announcement'])));
        }
    }

    
    public static function persist_fields($post_id, $gf_id, $short_desc, $img_desktop, $img_mobile, $start = '', $end = '', $brands = array(), $categories = array(), $products = array(), $winners_count = 0, $prize_value = 0, $announce_at = null) {
        $gf_id = (int) $gf_id;
        if ($gf_id > 0) { update_post_meta($post_id, self::META_GF, $gf_id); } else { delete_post_meta($post_id, self::META_GF); }
        update_post_meta($post_id, self::META_SHORTDESC, (string) $short_desc);
        $img_desktop = (int) $img_desktop;
        $img_mobile  = (int) $img_mobile;
        if ($img_desktop > 0) { update_post_meta($post_id, self::META_IMG_DESK, $img_desktop); } else { delete_post_meta($post_id, self::META_IMG_DESK); }
        if ($img_mobile > 0)  { update_post_meta($post_id, self::META_IMG_MOB, $img_mobile);   } else { delete_post_meta($post_id, self::META_IMG_MOB); }
        
        
        if ($img_desktop > 0) { set_post_thumbnail($post_id, $img_desktop); }

        $start = self::normalize_dt($start);
        $end   = self::normalize_dt($end);
        if ($start !== '') { update_post_meta($post_id, self::META_START, $start); } else { delete_post_meta($post_id, self::META_START); }
        if ($end   !== '') { update_post_meta($post_id, self::META_END, $end);     } else { delete_post_meta($post_id, self::META_END); }

        
        
        if ($announce_at !== null) {
            $announce_at = self::normalize_dt($announce_at);
            if ($announce_at !== '') { update_post_meta($post_id, self::META_ANNOUNCE_AT, $announce_at); } else { delete_post_meta($post_id, self::META_ANNOUNCE_AT); }
        }

        
        $clean = static function ($v) {
            return array_values(array_unique(array_filter(array_map('intval', (array) $v))));
        };
        $brands     = $clean($brands);
        $categories = $clean($categories);
        $products   = $clean($products);
        if ($brands)     { update_post_meta($post_id, self::META_BRANDS, $brands); }         else { delete_post_meta($post_id, self::META_BRANDS); }
        if ($categories) { update_post_meta($post_id, self::META_CATEGORIES, $categories); } else { delete_post_meta($post_id, self::META_CATEGORIES); }
        if ($products)   { update_post_meta($post_id, self::META_PRODUCTS, $products); }     else { delete_post_meta($post_id, self::META_PRODUCTS); }

        $winners_count = max(0, (int) $winners_count);
        $prize_value   = max(0, (float) $prize_value);
        update_post_meta($post_id, self::META_WINNERS_COUNT, $winners_count);
        if ($prize_value > 0) { update_post_meta($post_id, self::META_PRIZE_VALUE, $prize_value); } else { delete_post_meta($post_id, self::META_PRIZE_VALUE); }
    }

    
    public static function normalize_dt($v) {
        $v = str_replace('T', ' ', trim((string) $v));
        if ($v === '') { return ''; }
        if (preg_match('/^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2})(:\d{2})?$/', $v, $m)) {
            return $m[1] . ' ' . $m[2] . ((isset($m[3]) && $m[3] !== '') ? $m[3] : ':00');
        }
        return '';
    }

    
    public static function to_input($mysql_dt) {
        $mysql_dt = trim((string) $mysql_dt);
        if ($mysql_dt === '') { return ''; }
        return str_replace(' ', 'T', substr($mysql_dt, 0, 16));
    }

    
    public static function fmt_dt($mysql_dt) {
        $mysql_dt = trim((string) $mysql_dt);
        if ($mysql_dt === '') { return ''; }
        $ts = strtotime($mysql_dt);
        return $ts ? date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $ts) : $mysql_dt;
    }

    
    public static function winner_public_name($w) {
        $fn = trim((string) (is_object($w) && isset($w->first_name) ? $w->first_name : ''));
        $ln = trim((string) (is_object($w) && isset($w->last_name)  ? $w->last_name  : ''));
        if ($fn !== '') {
            return $ln !== '' ? $fn . ' ' . mb_substr($ln, 0, 1) . '.' : $fn;
        }
        return __('A lucky winner', 'ai-eshop-optimizer');
    }

    
    public static function schedule_state($post_id) {
        $start = (string) get_post_meta($post_id, self::META_START, true);
        $end   = (string) get_post_meta($post_id, self::META_END, true);
        $now   = current_time('mysql'); 
        if ($start !== '' && $now < $start) { return 'before'; }
        if ($end   !== '' && $now > $end)   { return 'ended'; }
        return 'live';
    }

    
    public static function gf_form_select($name, $selected_id) {
        $out  = '<select id="' . esc_attr($name) . '" name="' . esc_attr($name) . '" style="min-width:260px;">';
        $out .= '<option value="0">' . esc_html__('— none —', 'ai-eshop-optimizer') . '</option>';
        if (class_exists('GFAPI')) {
            foreach ((array) GFAPI::get_forms(true, false) as $f) {
                if (!isset($f['id'])) { continue; }
                $id    = (int) $f['id'];
                $title = (string) ($f['title'] ?? ('#' . $id));
                $out  .= '<option value="' . $id . '" ' . selected((int) $selected_id, $id, false) . '>#' . $id . ' — ' . esc_html($title) . '</option>';
            }
        } else {
            
            $out .= '<option value="' . (int) $selected_id . '" selected>' . esc_html(sprintf(__('Gravity Forms inactive (saved form #%d)', 'ai-eshop-optimizer'), (int) $selected_id)) . '</option>';
        }
        $out .= '</select>';
        return $out;
    }

    
    public static function share_links($post_id) {
        $permalink = get_permalink($post_id);
        if (!$permalink) { return array('facebook' => '', 'tiktok' => '', 'instagram' => ''); }
        $tag = static function ($src) use ($permalink) {
            return add_query_arg(array('utm_source' => $src, 'utm_medium' => 'social', 'utm_campaign' => 'competition'), $permalink);
        };
        return array(
            'facebook'  => 'https://www.facebook.com/sharer/sharer.php?u=' . rawurlencode($tag('facebook')),
            'tiktok'    => $tag('tiktok'),
            'instagram' => $tag('instagram'),
        );
    }
}
