<?php

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

class AIEO_Event_CPT {

    const POST_TYPE = 'aieo_event';

    const META_START         = '_aieo_event_start';         
    const META_END           = '_aieo_event_end';           
    const META_RSVP_DEADLINE = '_aieo_event_rsvp_deadline'; 
    const META_LOCATION      = '_aieo_event_location';      
    const META_MAP_URL       = '_aieo_event_map_url';       
    const META_SHORTDESC     = '_aieo_event_short_desc';    
    const META_IMG_DESK      = '_aieo_event_image_desktop'; 
    const META_IMG_MOB       = '_aieo_event_image_mobile';  

    
    const META_BRANDS        = '_aieo_event_brands';        
    const META_CATEGORIES    = '_aieo_event_categories';    
    const META_PRODUCTS      = '_aieo_event_products';      

    
    const META_INVITE_SUBJECT = '_aieo_event_invite_subject'; 
    const META_INVITE_BODY    = '_aieo_event_invite_body';    

    
    const META_GF = '_aieo_event_gf_form_id'; 

    
    const META_FEE      = '_aieo_event_fee';      
    const META_CURRENCY = '_aieo_event_currency'; 

    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-events-admin',
            plugins_url('assets/js/aieo-events-admin.js', AIEO_FILE),
            array('jquery'),
            defined('AIEO_VERSION') ? AIEO_VERSION : '1.0',
            true
        );
        wp_localize_script('aieo-events-admin', 'aieoEvents', array(
            'ajaxurl' => admin_url('admin-ajax.php'),
            'nonce'   => wp_create_nonce('aieo_events'),
            'i18n'    => array(
                'select' => __('Select image', 'ai-eshop-optimizer'),
                'use'    => __('Use this image', 'ai-eshop-optimizer'),
                'copied' => __('Copied!', 'ai-eshop-optimizer'),
                'saving' => __('Saving…', 'ai-eshop-optimizer'),
            ),
        ));

        
        
        self::enqueue_picker_bundle();
    }

    
    public 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'          => __('Events', 'ai-eshop-optimizer'),
                'singular_name' => __('Event', 'ai-eshop-optimizer'),
                'add_new_item'  => __('Add Event', 'ai-eshop-optimizer'),
                'edit_item'     => __('Edit Event', 'ai-eshop-optimizer'),
                'menu_name'     => __('Events', 'ai-eshop-optimizer'),
            ),
            'public'       => true,
            'show_in_rest' => true, 
            'has_archive'  => true,
            'menu_icon'    => 'dashicons-calendar-alt',
            
            
            
            'show_in_menu' => false,
            'supports'     => array('title', 'editor', 'thumbnail', 'excerpt', 'custom-fields', 'page-attributes'),
            'rewrite'      => array('slug' => 'events', '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'); },
        ));
        foreach (array(self::META_SHORTDESC, self::META_LOCATION, self::META_INVITE_SUBJECT, self::META_CURRENCY) 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'); },
            ));
        }
        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_RSVP_DEADLINE) 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_INVITE_BODY, 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_FEE, array(
            'type' => 'number', 'single' => true, 'show_in_rest' => true,
            'auth_callback' => static function () { return current_user_can('edit_posts'); },
        ));
        register_post_meta(self::POST_TYPE, self::META_MAP_URL, array(
            'type' => 'string', 'single' => true, 'show_in_rest' => true,
            'sanitize_callback' => static function ($v) { return esc_url_raw((string) $v); },
            'auth_callback' => static function () { return current_user_can('edit_posts'); },
        ));

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

    

    public static function add_metabox() {
        add_meta_box(
            'aieo-event-details',
            __('Event details', 'ai-eshop-optimizer'),
            array(__CLASS__, 'render_metabox'),
            self::POST_TYPE,
            'normal',
            'high'
        );
        add_meta_box(
            'aieo-event-invitation',
            __('✉️ Invitation', 'ai-eshop-optimizer'),
            array(__CLASS__, 'render_invitation_metabox'),
            self::POST_TYPE,
            'normal',
            'high'
        );
    }

    
    public static function render_invitation_metabox($post) {
        $subject   = (string) get_post_meta($post->ID, self::META_INVITE_SUBJECT, true);
        $body_html = (string) get_post_meta($post->ID, self::META_INVITE_BODY, true);
        echo '<p class="description" style="margin-top:0;">' . esc_html__('The subject line and body used when you send invitations for this event. Personalise the body with the participant’s name, the schedule, location, and an RSVP link (the send pipeline comes later).', 'ai-eshop-optimizer') . '</p>';
        echo '<p><label for="aieo_event_invite_subject"><strong>' . esc_html__('Invitation subject', 'ai-eshop-optimizer') . '</strong></label><br>';
        echo '<input type="text" id="aieo_event_invite_subject" name="aieo_event_invite_subject" value="' . esc_attr($subject) . '" style="width:100%;"></p>';
        echo '<p><label><strong>' . esc_html__('Invitation body', 'ai-eshop-optimizer') . '</strong></label></p>';
        wp_editor($body_html, 'aieoeventinvitebody', array(
            'textarea_name' => 'aieo_event_invite_body',
            'textarea_rows' => 8,
            'media_buttons' => true,
            'teeny'         => false,
            'tinymce'       => true,
            'quicktags'     => true,
        ));
    }

    public static function render_metabox($post) {
        wp_nonce_field('aieo_event_meta', 'aieo_event_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);
        $loc    = (string) get_post_meta($post->ID, self::META_LOCATION, 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);
        $rsvp   = (string) get_post_meta($post->ID, self::META_RSVP_DEADLINE, true);

        echo '<p><label for="aieo_event_location"><strong>' . esc_html__('Location', 'ai-eshop-optimizer') . '</strong></label><br>';
        echo '<input type="text" id="aieo_event_location" name="aieo_event_location" value="' . esc_attr($loc) . '" style="width:100%;" placeholder="' . esc_attr__('Venue / address', 'ai-eshop-optimizer') . '"></p>';

        $map = (string) get_post_meta($post->ID, self::META_MAP_URL, true);
        echo '<p><label for="aieo_event_map_url"><strong>' . esc_html__('Map link (Google Maps URL)', 'ai-eshop-optimizer') . '</strong></label><br>';
        echo '<input type="url" id="aieo_event_map_url" name="aieo_event_map_url" value="' . esc_attr($map) . '" style="width:100%;" placeholder="https://maps.google.com/…"></p>';
        echo '<p class="description">' . esc_html__('Optional. Paste a Google Maps link so guests can tap for directions. If left empty, a Maps search link is built from the location above.', 'ai-eshop-optimizer') . '</p>';

        echo '<p><label for="aieo_event_desc"><strong>' . esc_html__('Short description', 'ai-eshop-optimizer') . '</strong></label><br>';
        echo '<textarea id="aieo_event_desc" name="aieo_event_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_event_img_desktop', __('Desktop image', 'ai-eshop-optimizer'), $img_d);
        self::render_image_field('mobile', 'aieo_event_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_event_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_event_end" value="' . esc_attr(self::to_input($end)) . '" style="width:100%;"></label>';
        echo '<label style="flex:1;min-width:200px;"><strong>' . esc_html__('RSVP deadline', 'ai-eshop-optimizer') . '</strong><br><input type="datetime-local" name="aieo_event_rsvp_deadline" value="' . esc_attr(self::to_input($rsvp)) . '" 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. Leave start/end empty for an always-open event. The RSVP deadline drives the “please respond by …” message and closes self-registration.', '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));

        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 event 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_event_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_event_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_event_products',
                'mode'       => 'include',
                'selected'   => $prods,
                'help'       => __('Specific products associated with this event.', 'ai-eshop-optimizer'),
                'empty_text' => __('No products associated.', 'ai-eshop-optimizer'),
            ));
        }

        
        $fee = (string) get_post_meta($post->ID, self::META_FEE, true);
        $cur = (string) get_post_meta($post->ID, self::META_CURRENCY, true);

        echo '<hr style="margin:18px 0;">';
        echo '<p><label for="aieo-event-gf"><strong>' . esc_html__('Self-registration form', 'ai-eshop-optimizer') . '</strong></label><br>';
        echo self::gf_form_select('aieo_event_gf', $gf_id); 
        echo '<br><span class="description">' . esc_html__('Optional. A Gravity Form people can use to self-register for this event (the front-end self-registration flow comes later).', 'ai-eshop-optimizer') . '</span></p>';

        echo '<p style="display:flex;gap:24px;flex-wrap:wrap;margin-top:12px;">';
        echo '<label style="flex:1;min-width:180px;"><strong>' . esc_html__('Admission fee', 'ai-eshop-optimizer') . '</strong><br><input type="number" min="0" step="0.01" name="aieo_event_fee" value="' . esc_attr($fee) . '" style="width:140px;"></label>';
        echo '<label style="flex:1;min-width:180px;"><strong>' . esc_html__('Currency', 'ai-eshop-optimizer') . '</strong><br><input type="text" name="aieo_event_currency" value="' . esc_attr($cur) . '" style="width:120px;" placeholder="EUR"></label>';
        echo '</p>';
        echo '<p class="description"><em>' . esc_html__('Admission fee + currency are reserved for paid events (not charged yet).', 'ai-eshop-optimizer') . '</em></p>';
    }

    
    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-event-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-event-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-event-image-id" name="' . esc_attr($name) . '" value="' . esc_attr((int) $attachment_id) . '">';
        echo '<button type="button" class="button aieo-event-image-select">' . esc_html__('Select image', 'ai-eshop-optimizer') . '</button> ';
        echo '<button type="button" class="button-link aieo-event-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_event_meta_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['aieo_event_meta_nonce'])), 'aieo_event_meta')) { return; }
        if (!current_user_can('edit_post', $post_id)) { return; }

        $gf    = isset($_POST['aieo_event_gf']) ? (int) $_POST['aieo_event_gf'] : 0;
        $desc  = isset($_POST['aieo_event_desc']) ? sanitize_textarea_field(wp_unslash($_POST['aieo_event_desc'])) : '';
        $loc   = isset($_POST['aieo_event_location']) ? sanitize_text_field(wp_unslash($_POST['aieo_event_location'])) : '';
        $img_d = isset($_POST['aieo_event_img_desktop']) ? (int) $_POST['aieo_event_img_desktop'] : 0;
        $img_m = isset($_POST['aieo_event_img_mobile']) ? (int) $_POST['aieo_event_img_mobile'] : 0;
        $start = isset($_POST['aieo_event_start']) ? sanitize_text_field(wp_unslash($_POST['aieo_event_start'])) : '';
        $end   = isset($_POST['aieo_event_end'])   ? sanitize_text_field(wp_unslash($_POST['aieo_event_end']))   : '';
        $rsvp  = isset($_POST['aieo_event_rsvp_deadline']) ? sanitize_text_field(wp_unslash($_POST['aieo_event_rsvp_deadline'])) : '';

        $brands     = isset($_POST['aieo_event_brands'])     ? array_map('intval', (array) wp_unslash($_POST['aieo_event_brands']))     : array();
        $categories = isset($_POST['aieo_event_categories']) ? array_map('intval', (array) wp_unslash($_POST['aieo_event_categories'])) : array();
        $products   = class_exists('AIEO_DMM_Product_Picker')
            ? AIEO_DMM_Product_Picker::roll_up_to_parents(AIEO_DMM_Product_Picker::collect_ids('aieo_event_products'))
            : (isset($_POST['aieo_event_products']) ? array_map('intval', (array) wp_unslash($_POST['aieo_event_products'])) : array());
        $fee = isset($_POST['aieo_event_fee']) ? (float) $_POST['aieo_event_fee'] : 0;
        $cur = isset($_POST['aieo_event_currency']) ? sanitize_text_field(wp_unslash($_POST['aieo_event_currency'])) : '';

        self::persist_fields($post_id, $gf, $desc, $loc, $img_d, $img_m, $start, $end, $rsvp, $brands, $categories, $products, $fee, $cur);

        
        if (isset($_POST['aieo_event_invite_subject'])) {
            update_post_meta($post_id, self::META_INVITE_SUBJECT, sanitize_text_field(wp_unslash($_POST['aieo_event_invite_subject'])));
        }
        if (isset($_POST['aieo_event_invite_body'])) {
            update_post_meta($post_id, self::META_INVITE_BODY, wp_kses_post(wp_unslash($_POST['aieo_event_invite_body'])));
        }

        
        if (isset($_POST['aieo_event_map_url'])) {
            update_post_meta($post_id, self::META_MAP_URL, esc_url_raw(wp_unslash($_POST['aieo_event_map_url'])));
        }
    }

    
    public static function map_url($post_id) {
        $explicit = trim((string) get_post_meta($post_id, self::META_MAP_URL, true));
        if ($explicit !== '') { return $explicit; }
        $loc = trim((string) get_post_meta($post_id, self::META_LOCATION, true));
        if ($loc === '') { return ''; }
        return 'https://www.google.com/maps/search/?api=1&query=' . rawurlencode($loc);
    }

    
    public static function persist_fields($post_id, $gf_id, $short_desc, $location, $img_desktop, $img_mobile, $start = '', $end = '', $rsvp_deadline = null, $brands = array(), $categories = array(), $products = array(), $fee = 0, $currency = '') {
        $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);
        update_post_meta($post_id, self::META_LOCATION, (string) $location);
        $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 ($rsvp_deadline !== null) {
            $rsvp_deadline = self::normalize_dt($rsvp_deadline);
            if ($rsvp_deadline !== '') { update_post_meta($post_id, self::META_RSVP_DEADLINE, $rsvp_deadline); } else { delete_post_meta($post_id, self::META_RSVP_DEADLINE); }
        }

        
        $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); }

        
        $fee      = max(0, (float) $fee);
        $currency = strtoupper(preg_replace('/[^A-Za-z]/', '', (string) $currency));
        if ($fee > 0)        { update_post_meta($post_id, self::META_FEE, $fee); }           else { delete_post_meta($post_id, self::META_FEE); }
        if ($currency !== '') { update_post_meta($post_id, self::META_CURRENCY, $currency); } else { delete_post_meta($post_id, self::META_CURRENCY); }
    }

    
    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 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' => 'event'), $permalink);
        };
        return array(
            'facebook'  => 'https://www.facebook.com/sharer/sharer.php?u=' . rawurlencode($tag('facebook')),
            'tiktok'    => $tag('tiktok'),
            'instagram' => $tag('instagram'),
        );
    }
}
