<?php
if (!defined('ABSPATH')) {
	exit;
}

final class Aimogen_Snippets_Engine {

    const DB_VERSION = '1.4.0';
	const TABLE = 'aimogen_snippets';
	const NONCE_ACTION = 'aimogen_snippet_action';
	const NONCE_NAME = '_aimogen_snippet_nonce';

	private static $instance = null;
    private $condition_runtime_cache = [];
    private $request_data = [];

    private static $current_running_id = null;

	public static function instance() {
		if (!self::$instance) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	private function __construct() {
		add_action('admin_post_aimogen_create_snippet', [$this, 'handle_create']);
		add_action('admin_post_aimogen_toggle_snippet', [$this, 'handle_toggle']);
		add_action('template_redirect', [$this, 'execute_php_snippets'], 99);
		add_action('wp_enqueue_scripts', [$this, 'enqueue_assets']);
		add_action('admin_enqueue_scripts', [$this, 'enqueue_assets']);
        add_action('wp_ajax_aimogen_toggle_snippet_ajax', [$this,'ajax_toggle']);
        add_action('admin_post_aimogen_bulk_action', [$this, 'handle_bulk']);
        add_action('admin_post_aimogen_update_snippet', [$this, 'handle_update']);
        add_action('admin_post_aimogen_ai_edit_snippet', [$this, 'handle_ai_edit']);
        add_action('admin_post_aimogen_clone_snippet', [$this, 'handle_clone']);
        add_action('admin_post_aimogen_delete_snippet', [$this, 'handle_delete']);
        add_action('wp_ajax_aimogen_generate_conditions_ajax', [$this, 'ajax_generate_conditions']);

        if (is_admin()) {
            add_action('admin_init', [$this, 'maybe_upgrade']);
        }
        $this->register_fatal_guard();
	}

    private function set_running_snippet_id($id) {
        self::$current_running_id = $id ?: null;
    }

    private function register_fatal_guard() {
        static $registered = false;
        if ($registered) return;
        $registered = true;

        register_shutdown_function(function () {
            $err = error_get_last();
            if (!$err) {
                return;
            }

            $fatal_types = [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR];
            if (!in_array($err['type'], $fatal_types, true)) {
                return;
            }

            $id = self::$current_running_id ?? 0;
            if ($id > 0) {
                $message = $err['message'] . ' in ' . ($err['file'] ?? '') . ':' . ($err['line'] ?? 0);
                aiomatic_log_to_file('Aimogen fatal in snippet #' . $id . ': ' . $message);
                $this->mark_snippet_error($id, $err['message'] . ' in ' . ($err['file'] ?? '') . ':' . ($err['line'] ?? 0));
            }
        });
    }
    public function ajax_generate_conditions() {

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => 'Permission denied'], 403);
        }

        check_ajax_referer('aimogen_conditions_ai_nonce');

        $text = trim(wp_unslash($_POST['text'] ?? ''));
        if ($text === '') {
            wp_send_json_error(['message' => 'Empty request'], 400);
        }

        $assistant_id = sanitize_text_field($_POST['assistant_id'] ?? '');
        $ai_model = sanitize_text_field($_POST['ai_model'] ?? '');

        $json = $this->generate_ai_conditions_json($text, $ai_model ?: null, $assistant_id ?: null);

        if (!$json) {
            wp_send_json_error(['message' => 'AI returned empty output'], 500);
        }

        $decoded = json_decode($json, true);
        if (!is_array($decoded)) {
            wp_send_json_error(['message' => 'AI returned invalid JSON'], 422);
        }

        $validated = $this->validate_conditions_structure($decoded);
        if (!$validated['ok']) {
            wp_send_json_error(['message' => $validated['reason']], 422);
        }

        wp_send_json_success([
            'conditions' => wp_json_encode($decoded),
        ]);
    }
    private function generate_ai_conditions_json($user_text, $ai_model = null, $assistant_id = null) {

        $schema = $this->get_conditions_ai_schema();

        $instruction = "You generate execution conditions JSON for a WordPress snippets engine.

    Return ONLY strict JSON. No markdown. No explanations. No trailing comments.

    Format:
    [
    [
        {\"subject\":\"siteArea\",\"operator\":\"is\",\"object\":[\"frontend\"]}
    ]
    ]

    Rules:
    - Outer array = OR groups
    - Inner array = AND rules
    - Each rule must contain: subject, operator, object
    - object must ALWAYS be an array (even if one value)
    - Allowed subjects and operators are strictly defined below.
    - Do not invent new subjects or operators.
    - Keep values exactly as defined (case sensitive where shown).

    Allowed subjects and operators:
    " . $schema . "

    User intent:
    " . trim($user_text);

        $raw = $this->generate_ai_code($instruction, 'text', $ai_model, $assistant_id);
        $raw = trim((string)$raw);

        if ($raw === '') return '';

        $raw = preg_replace('/^\s*```[a-z]*\s*/i', '', $raw);
        $raw = preg_replace('/```$/', '', $raw);
        $raw = trim($raw);

        if ($raw !== '' && $raw[0] !== '[') {
            if (preg_match('/(\[\s*\[.*\]\s*\])/s', $raw, $m)) {
                $raw = trim($m[1]);
            }
        }

        return $raw;
    }

    private function get_conditions_ai_schema() {

        $map = [
            'siteArea'         => ['is','is not'],
            'currentQuery'     => ['is','is not'],
            'visitorLanguage'  => ['in','not in'],
            'currentTheme'     => ['in','not in'],
            'activePlugin'     => ['in','not in'],
            'debugEnabled'     => ['is','is not'],

            'post'             => ['in','not in'],
            'page'             => ['in','not in'],
            'postType'         => ['in','not in'],
            'tag'              => ['in','not in'],
            'category'         => ['in','not in'],
            'author'           => ['in','not in'],
            'postStatus'       => ['in','not in'],
            'postParent'       => ['in','not in'],

            'postPublished'    => ['before','after','between'],
            'postModified'     => ['before','after','between'],

            'authenticated'    => ['is','is not'],
            'user'             => ['in','not in'],
            'userRole'         => ['in','not in'],
            'userCap'          => ['in','not in'],
            'userLocale'       => ['in','not in'],
            'userRegistered'   => ['before','after','between'],

            'currentDate'      => ['before','after','between'],
            'timeOfDay'        => ['before','after','between'],
            'dayOfWeek'        => ['in','not in'],
        ];

        $out = [];
        foreach ($map as $subject => $ops) {
            $out[] = "- {$subject}: " . implode(', ', $ops);
        }
        return implode("\n", $out);
    }

    private function validate_conditions_structure($groups) {

        if ($groups === []) {
            return ['ok' => false, 'reason' => 'Conditions cannot be empty.'];
        }

        $allowed = $this->get_conditions_allowed_map();

        foreach ($groups as $g) {
            if (!is_array($g) || $g === []) {
                return ['ok' => false, 'reason' => 'Each OR group must be a non-empty array of rules.'];
            }

            foreach ($g as $rule) {
                if (!is_array($rule)) {
                    return ['ok' => false, 'reason' => 'Each rule must be an object.'];
                }

                $subject  = $rule['subject']  ?? '';
                $operator = $rule['operator'] ?? '';
                $object   = $rule['object']   ?? null;

                if (!is_string($subject) || $subject === '') {
                    return ['ok' => false, 'reason' => 'Rule subject missing or invalid.'];
                }
                if (!isset($allowed[$subject])) {
                    return ['ok' => false, 'reason' => 'Invalid subject: ' . $subject];
                }

                if (!is_string($operator) || $operator === '') {
                    return ['ok' => false, 'reason' => 'Rule operator missing or invalid.'];
                }
                if (!in_array($operator, $allowed[$subject], true)) {
                    return ['ok' => false, 'reason' => "Invalid operator '{$operator}' for subject '{$subject}'."];
                }

                if (!is_array($object)) {
                    return ['ok' => false, 'reason' => 'Rule object must be an array.'];
                }

                if ($operator === 'between' && count($object) !== 2) {
                    return ['ok' => false, 'reason' => 'Operator "between" requires exactly 2 values.'];
                }
            }
        }

        return ['ok' => true];
    }

    private function get_conditions_allowed_map() {
        return [
            'siteArea'         => ['is','is not'],
            'currentQuery'     => ['is','is not'],
            'visitorLanguage'  => ['in','not in'],
            'currentTheme'     => ['in','not in'],
            'activePlugin'     => ['in','not in'],
            'debugEnabled'     => ['is','is not'],

            'post'             => ['in','not in'],
            'page'             => ['in','not in'],
            'postType'         => ['in','not in'],
            'tag'              => ['in','not in'],
            'category'         => ['in','not in'],
            'author'           => ['in','not in'],
            'postStatus'       => ['in','not in'],
            'postParent'       => ['in','not in'],

            'postPublished'    => ['before','after','between'],
            'postModified'     => ['before','after','between'],

            'authenticated'    => ['is','is not'],
            'user'             => ['in','not in'],
            'userRole'         => ['in','not in'],
            'userCap'          => ['in','not in'],
            'userLocale'       => ['in','not in'],
            'userRegistered'   => ['before','after','between'],

            'currentDate'      => ['before','after','between'],
            'timeOfDay'        => ['before','after','between'],
            'dayOfWeek'        => ['in','not in'],
        ];
    }
    public function maybe_upgrade() {
        $installed = get_option('aimogen_snippets_db_version');

        if ($installed === self::DB_VERSION) {
            return;
        }

        $this->install_or_update_schema();

        update_option('aimogen_snippets_db_version', self::DB_VERSION);
        $this->flush_snippet_cache();
    }
    public function handle_delete() {

        if (!current_user_can('manage_options')) {
            wp_die('Permission denied');
        }

        check_admin_referer(self::NONCE_ACTION, self::NONCE_NAME);

        $id = absint($_GET['id'] ?? 0);
        if (!$id) {
            wp_die('Invalid snippet ID.');
        }

        global $wpdb;
        $table = $wpdb->prefix . self::TABLE;

        $wpdb->delete(
            $table,
            ['id' => $id],
            ['%d']
        );
        $this->flush_snippet_cache();
        wp_safe_redirect(
            add_query_arg(
                [
                    'page' => 'aiomatic_snippets_panel',
                    'deleted' => 1,
                ],
                admin_url('admin.php')
            )
        );
        exit;
    }
    private function mark_snippet_error($id, $message) {

        global $wpdb;

        $wpdb->update(
            $wpdb->prefix . self::TABLE,
            [
                'has_error' => 1,
                'last_error' => wp_strip_all_tags($message),
                'active' => 0
            ],
            ['id' => $id],
            ['%d','%s','%d'],
            ['%d']
        );

        $this->flush_snippet_cache();
    }
    public function handle_clone() {

        if (!current_user_can('manage_options')) {
            wp_die('Permission denied');
        }

        check_admin_referer(self::NONCE_ACTION, self::NONCE_NAME);

        $id = absint($_GET['id'] ?? 0);
        if (!$id) {
            wp_die('Invalid snippet ID.');
        }

        global $wpdb;
        $table = $wpdb->prefix . self::TABLE;

        $snippet = $wpdb->get_row(
            $wpdb->prepare("SELECT * FROM {$table} WHERE id=%d", $id)
        );

        if (!$snippet) {
            wp_die('Snippet not found.');
        }

        $new_title = $snippet->title . ' (Copy)';

        $result = $wpdb->insert(
            $table,
            [
                'title'        => $new_title,
                'type'         => $snippet->type,
                'code'         => $snippet->code,
                'conditions'   => $snippet->conditions,
                'ai_model'     => $snippet->ai_model,
                'assistant_id' => $snippet->assistant_id,
                'active'       => 0,
                'priority'     => $snippet->priority,
                'has_error'  => 0,
                'last_error' => null,
                'created_at'   => current_time('mysql'),
            ],
            ['%s','%s','%s','%s','%s','%s','%d','%d','%d','%s','%s']
        );
        if (!$result) {
            wp_die('Failed to create clone.');
        }
        $this->flush_snippet_cache();
        wp_safe_redirect(
            add_query_arg(
                [
                    'page' => 'aiomatic_snippets_panel',
                    'cloned' => 1,
                ],
                admin_url('admin.php')
            )
        );
        exit;
    }
    private function get_active_snippets() {

        $cache_key = 'aimogen_active_snippets_v1_' . get_current_blog_id();
        $cached = wp_cache_get($cache_key, 'aimogen');

        if ($cached !== false) {
            return $cached;
        }

        global $wpdb;
        $table = $wpdb->prefix . self::TABLE;

        $rows = $wpdb->get_results(
            "SELECT id, type, code, conditions, priority 
            FROM {$table}
            WHERE active=1 AND has_error=0
            ORDER BY priority ASC, id ASC"
        );

        wp_cache_set($cache_key, $rows, 'aimogen', 3600);

        return $rows;
    }
    public function handle_ai_edit() {

        if (!current_user_can('manage_options')) {
            wp_die('Permission denied');
        }

        check_admin_referer(self::NONCE_ACTION, self::NONCE_NAME);

        $id = absint($_POST['id'] ?? 0);
        $guidance = trim(wp_unslash($_POST['ai_guidance'] ?? ''));

        if (!$id || !$guidance) {
            wp_die('Invalid request.');
        }

        global $wpdb;

        $snippet = $wpdb->get_row(
            $wpdb->prepare(
                "SELECT * FROM {$wpdb->prefix}" . self::TABLE . " WHERE id=%d",
                $id
            )
        );

        if (!$snippet) {
            wp_die('Snippet not found.');
        }

        $edit_prompt = "You are editing an existing {$snippet->type} snippet.

    IMPORTANT:
    - Return ONLY the updated raw {$snippet->type} code.
    - No explanations.
    - No markdown fences.
    - Do not wrap in backticks.

    Current code:
    ----------------
    {$snippet->code}
    ----------------

    User modification request:
    {$guidance}
    ";

        $new_code = $this->generate_ai_code($edit_prompt, $snippet->type, $snippet->ai_model, $snippet->assistant_id);
        $new_code = $this->normalize_code($new_code, $snippet->type);

        $check = $this->validate_code($new_code, $snippet->type);
        if (!$check['ok']) {
            wp_die('AI modification rejected: ' . esc_html($check['reason']));
        }

        if ($snippet->type === 'php') {
            $strict = $this->strict_php_check($new_code);
            if (!$strict['ok']) {
                wp_die('AI modification rejected: ' . esc_html($strict['reason']));
            }
        }

        $wpdb->update(
            $wpdb->prefix . self::TABLE,
            [
                'code'       => $new_code,
                'has_error'  => 0,
                'last_error' => null,
            ],
            ['id' => $id],
            ['%s','%d','%s'],
            ['%d']
        );
        $this->flush_snippet_cache();
        wp_safe_redirect(
            add_query_arg(
                [
                    'page' => 'aiomatic_snippets_panel',
                    'edit' => $id,
                    'updated' => 1,
                    'ai_edited' => 1,
                ],
                admin_url('admin.php')
            )
        );
        exit;
    }
    public function handle_update() {

        if (!current_user_can('manage_options')) {
            wp_die('Permission denied');
        }

        check_admin_referer(self::NONCE_ACTION, self::NONCE_NAME);

        $id = absint($_POST['id'] ?? 0);
        if (!$id) {
            wp_die('Invalid snippet ID.');
        }

        $title = sanitize_text_field($_POST['title'] ?? '');
        $type  = sanitize_key($_POST['type'] ?? '');
        $code  = wp_unslash($_POST['code'] ?? '');
        $activate = isset($_POST['activate']);
        $conditions = trim(wp_unslash($_POST['conditions'] ?? ''));
        $assistant_id = sanitize_text_field($_POST['assistant_id'] ?? '');
        $ai_model = sanitize_text_field($_POST['ai_model'] ?? '');
        $priority = isset($_POST['priority']) ? intval($_POST['priority']) : 10;
        if (!$title || !$code || !in_array($type, ['php','js','css','html'], true)) {
            wp_die('Invalid input.');
        }

        if ($conditions !== '') {
            json_decode($conditions);
            if (json_last_error() !== JSON_ERROR_NONE) {
                wp_die('Invalid conditions JSON.');
            }
        }

        $code = $this->normalize_code($code, $type);

        $check = $this->validate_code($code, $type);
        if (!$check['ok']) {
            wp_die('Snippet rejected: ' . esc_html($check['reason']));
        }

        if ($type === 'php' && $activate) {
            $strict = $this->strict_php_check($code);
            if (!$strict['ok']) {
                $activate = false;
            }
        }

        global $wpdb;
        $wpdb->update(
            $wpdb->prefix . self::TABLE,
            [
                'title' => $title,
                'type' => $type,
                'code' => $code,
                'conditions' => $conditions ?: null,
                'ai_model' => $ai_model ?: null,
                'assistant_id' => $assistant_id ?: null,
                'priority' => $priority,
                'active' => $activate ? 1 : 0,
                'has_error' => 0,
                'last_error' => null,
            ],
            ['id' => $id],
            ['%s','%s','%s','%s','%s','%s','%d','%d','%d','%s'],
            ['%d']
        );
        $this->flush_snippet_cache();
        wp_safe_redirect(
            add_query_arg(
                [
                    'page' => 'aiomatic_snippets_panel',
                    'edit' => $id,
                    'updated' => 1,
                ],
                admin_url('admin.php')
            )
        );
        exit;
    }
    public function handle_bulk() {

        if (!current_user_can('manage_options')) {
            wp_die('Permission denied');
        }

        check_admin_referer('aimogen_bulk_action');

        $action = isset($_POST['bulk_action']) ? sanitize_key($_POST['bulk_action']) : '';
        $ids = isset($_POST['snippet_ids']) ? array_map('absint', (array)$_POST['snippet_ids']) : [];

        if (!$action || empty($ids)) {
            wp_safe_redirect(wp_get_referer() ?: admin_url('admin.php?page=aiomatic_snippets_panel'));
            exit;
        }

        global $wpdb;
        $table = $wpdb->prefix . self::TABLE;

        $ids_placeholder = implode(',', array_fill(0, count($ids), '%d'));

        switch ($action) {

            case 'activate':
                $snippets = $wpdb->get_results(
                    $wpdb->prepare(
                        "SELECT id, type, code FROM {$table} WHERE id IN ($ids_placeholder)",
                        $ids
                    )
                );

                $valid_ids = array();

                foreach ($snippets as $snippet) {
                    $check = $this->validate_code($snippet->code, $snippet->type);

                    if (!$check['ok']) {
                        $wpdb->update(
                            $table,
                            array(
                                'active'     => 0,
                                'has_error'  => 1,
                                'last_error' => $check['reason'],
                            ),
                            array('id' => absint($snippet->id)),
                            array('%d', '%d', '%s'),
                            array('%d')
                        );
                        continue;
                    }

                    if ($snippet->type === 'php') {
                        $strict = $this->strict_php_check($snippet->code);

                        if (!$strict['ok']) {
                            $wpdb->update(
                                $table,
                                array(
                                    'active'     => 0,
                                    'has_error'  => 1,
                                    'last_error' => $strict['reason'],
                                ),
                                array('id' => absint($snippet->id)),
                                array('%d', '%d', '%s'),
                                array('%d')
                            );
                            continue;
                        }
                    }

                    $valid_ids[] = absint($snippet->id);
                }

                if (!empty($valid_ids)) {
                    $valid_placeholder = implode(',', array_fill(0, count($valid_ids), '%d'));

                    $wpdb->query(
                        $wpdb->prepare(
                            "UPDATE {$table} SET active=1, has_error=0, last_error=NULL WHERE id IN ($valid_placeholder)",
                            $valid_ids
                        )
                    );
                }

                break;

            case 'deactivate':
                $wpdb->query(
                    $wpdb->prepare(
                        "UPDATE {$table} SET active=0 WHERE id IN ($ids_placeholder)",
                        $ids
                    )
                );
                break;

            case 'delete':
                $wpdb->query(
                    $wpdb->prepare(
                        "DELETE FROM {$table} WHERE id IN ($ids_placeholder)",
                        $ids
                    )
                );
                break;
        }
        $this->flush_snippet_cache();        
        wp_safe_redirect(admin_url('admin.php?page=aiomatic_snippets_panel'));
        exit;
    }
    public function ajax_toggle() {

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => 'Permission denied'], 403);
        }

        check_ajax_referer('aimogen_toggle_nonce');

        $id = isset($_POST['id']) ? absint($_POST['id']) : 0;
        $state = isset($_POST['state']) ? intval($_POST['state']) : 0;
        $state = $state ? 1 : 0;

        if ($id <= 0) {
            wp_send_json_error(['message' => 'Invalid snippet ID'], 400);
        }

        global $wpdb;
        $table = $wpdb->prefix . self::TABLE;

        $data = ['active' => $state];

        if ($state === 1) {
            $data['has_error'] = 0;
            $data['last_error'] = null;
        }

        $updated = $wpdb->update(
            $table,
            $data,
            ['id' => $id],
            $state === 1 ? ['%d','%d','%s'] : ['%d'],
            ['%d']
        );

        if ($updated === false) {
            wp_send_json_error(['message' => 'Database error'], 500);
        }
        $this->flush_snippet_cache();        
        wp_send_json_success([
            'id' => $id,
            'active' => $state
        ]);
    }

    private function infer_type_from_code($code) {

        $trim = ltrim($code);

        if (preg_match('/^\s*(function|\$|if|add_action|add_filter|wp_)/', $trim)) {
            return 'php';
        }

        if (preg_match('/^\s*<\/?[a-z]/i', $trim)) {
            return 'html';
        }

        if (preg_match('/\{[^}]*\}/', $trim) && strpos($trim, ';') === false) {
            return 'css';
        }

        if (strpos($trim, 'document.') !== false ||
            strpos($trim, 'window.') !== false ||
            strpos($trim, 'addEventListener') !== false) {
            return 'js';
        }

        return 'php';
    }
    private function detect_snippet_type($prompt, $ai_model = null, $assistant_id = null) {

        $instruction = "You are classifying a WordPress snippet request.

Choose exactly ONE type from:
- php  (server-side logic, hooks, filters, backend processing)
- js   (browser-side logic, DOM manipulation, event handling)
- css  (styling existing elements only, no element creation)
- html (creating or rendering markup elements)

Important rules:
- If the request involves creating, displaying, rendering, or outputting visible elements → choose html.
- If it only changes styles of existing elements → choose css.
- If it manipulates the DOM dynamically → choose js.
- If it uses WordPress hooks or backend logic → choose php.
- CSS must NOT be chosen if the request requires creating a new element.

Return ONLY one lowercase word: php, js, css, or html.
No explanation.

User request:
" . trim($prompt);


        $result = $this->generate_ai_code(
            $instruction,
            'text',
            $ai_model,
            $assistant_id
        );

        $result = strtolower(trim($result));

        if (!in_array($result, ['php','js','css','html'], true)) {
            return $this->infer_type_from_code($prompt); 
        }

        return $result;
    }            
	private function install_or_update_schema() {
        global $wpdb;

        $table = $wpdb->prefix . self::TABLE;
        $charset = $wpdb->get_charset_collate();

        require_once ABSPATH . 'wp-admin/includes/upgrade.php';

        $sql = "CREATE TABLE {$table} (
            id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
            title VARCHAR(255) NOT NULL,
            type VARCHAR(10) NOT NULL,
            code LONGTEXT NOT NULL,
            conditions LONGTEXT NULL,
            ai_model VARCHAR(100) NULL,
            assistant_id VARCHAR(100) NULL,
            priority INT NOT NULL DEFAULT 10,
            active TINYINT(1) DEFAULT 0,
            has_error TINYINT(1) DEFAULT 0,
            last_error TEXT NULL,
            created_at DATETIME NOT NULL,
            PRIMARY KEY (id),
            KEY type (type),
            KEY active (active),
            KEY priority (priority)
        ) {$charset};";


        dbDelta($sql);
    }

    public function load_admin_assets() {
    }
    public static function render_admin() {

        if (!current_user_can('manage_options')) {
            wp_die('Permission denied');
        }

        global $wpdb;
        $per_page = 10;
        $paged = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
        $offset = ($paged - 1) * $per_page;
        $current_type = isset($_GET['type']) ? sanitize_key($_GET['type']) : 'all';
        $current_status = isset($_GET['status']) ? sanitize_key($_GET['status']) : 'all';
        $counts = [];
        $types = ['php','js','css','html'];

        $table = $wpdb->prefix . self::TABLE;
        foreach ($types as $t) {
            $counts[$t] = (int)$wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM {$table} WHERE type=%s",
                $t
            ));
        }
        $editing_id = isset($_GET['edit']) ? absint($_GET['edit']) : 0;
        $editing_snippet = null;
        $aimogen_tooltips = [
            'title' => __('Internal label only. Helps you find snippets later.', 'aiomatic-automatic-ai-content-writer'),
            'type' => __('PHP runs on the frontend (template_redirect). JS/CSS/HTML are injected inline.', 'aiomatic-automatic-ai-content-writer'),
            'priority' => __('Lower runs earlier. Same priority falls back to ID order.', 'aiomatic-automatic-ai-content-writer'),
            'conditions' => __('Optional. If empty, the snippet runs on the frontend only (never in wp-admin). Groups are OR, rules inside a group are AND.', 'aiomatic-automatic-ai-content-writer'),
            'active' => __('If enabled, the snippet executes when conditions match. New snippets are saved inactive by default. PHP snippets failing strict checks may auto-disable.', 'aiomatic-automatic-ai-content-writer'),
            'assistant_id' => __('Pick an assistant to generate or edit. If set, model selection is ignored.', 'aiomatic-automatic-ai-content-writer'),
            'ai_model' => __('Used only when no assistant is selected.', 'aiomatic-automatic-ai-content-writer'),
            'creation_mode' => __('AI: generate from prompt. Manual: paste your own code (still validated).', 'aiomatic-automatic-ai-content-writer'),
            'prompt' => __('Describe what you want. The engine will generate raw code only.', 'aiomatic-automatic-ai-content-writer'),
            'code' => __('Raw snippet content. No PHP tags needed for PHP snippets.', 'aiomatic-automatic-ai-content-writer'),
            'ai_guidance' => __('Describe changes you want. AI returns only updated raw code.', 'aiomatic-automatic-ai-content-writer'),
            'activate_immediately' => __('If checked, the snippet is saved as active. Recommended to test inactive first. PHP snippets are validated before activation and may auto-disable if they fail strict safety checks.', 'aiomatic-automatic-ai-content-writer')
        ];
      
        if ($editing_id) {
            $editing_snippet = $wpdb->get_row(
                $wpdb->prepare(
                    "SELECT * FROM {$wpdb->prefix}" . self::TABLE . " WHERE id=%d",
                    $editing_id
                )
            );

            if (!$editing_snippet) {
                wp_die('Snippet not found.');
            }
        }
        $total_count = (int)$wpdb->get_var("SELECT COUNT(*) FROM {$table}");
        $active_count = (int)$wpdb->get_var("SELECT COUNT(*) FROM {$table} WHERE active=1 AND has_error=0");
        $inactive_count = $total_count - $active_count;
        $where = "1=1";

        if ($current_type !== 'all') {
            $where .= $wpdb->prepare(" AND type=%s", $current_type);
        }

        if ($current_status === 'active') {
            $where .= " AND active=1";
        } elseif ($current_status === 'inactive') {
            $where .= " AND active=0";
        }
        if (!empty($_GET['s'])) {
            $search = '%' . $wpdb->esc_like($_GET['s']) . '%';
            $where .= $wpdb->prepare(" AND (title LIKE %s OR code LIKE %s)", $search, $search);
        }
        $total_items = (int)$wpdb->get_var(
            "SELECT COUNT(*) FROM {$table} WHERE {$where}"
        );

        $total_pages = ceil($total_items / $per_page);
        $snippets = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT * FROM {$table} WHERE {$where} ORDER BY id DESC LIMIT %d OFFSET %d",
                $per_page,
                $offset
            )
        );
        if (!empty($_GET['ai_edited'])) {
            echo '<div class="notice notice-success is-dismissible"><p>Snippet modified by AI successfully.</p></div>';
        }
        if (!empty($_GET['updated'])) {
            echo '<div class="notice notice-success is-dismissible"><p>Snippet updated successfully.</p></div>';
        }
        if (!empty($_GET['cloned'])) {
            echo '<div class="notice notice-success is-dismissible"><p>Snippet cloned successfully.</p></div>';
        }
        if (!empty($_GET['deleted'])) {
            echo '<div class="notice notice-success is-dismissible"><p>Snippet deleted successfully.</p></div>';
        }
    ?>
    
    <div class="wp-header-end"></div>

    <div class="aiomatic-admin-shell">
    <div class="aiomatic-admin-hero">
        <div class="aiomatic-admin-identity">
            <div class="aiomatic-admin-logo">
                <img class="client-logo" src="<?php echo esc_url(plugins_url( '/images/ai.png', __FILE__ )); ?>" alt="Aimogen" />
            </div>
            <div class="aiomatic-admin-title">
                <div class="aiomatic-admin-title-sub">
                <?php esc_html_e('AI Momentum Generator', 'aiomatic-automatic-ai-content-writer'); ?>
                </div>
                <div class="aiomatic-admin-title-main">
                <?php esc_html_e('AI Snippets Engine', 'aiomatic-automatic-ai-content-writer'); ?>
                </div>
            </div>
        </div>
    </div>

    <div class="aiomatic-admin-layout">

    <aside class="aiomatic-admin-sidebar">
        <div class="aiomatic-admin-sidebar-inner">
            <div class="aiomatic-sidebar-heading">
                <?php esc_html_e('AI Snippets', 'aiomatic-automatic-ai-content-writer'); ?>
            </div>

            <div class="aiomatic-sidebar-nav">
                <nav class="nav-tab-wrapper">
                    <a href="#tab-0" class="aiomatic-nav-tab">
                        <span class="aiomatic-sidebar-label"><?php esc_html_e('Overview', 'aiomatic-automatic-ai-content-writer'); ?></span>
                    </a>
                    <a href="#tab-1" class="aiomatic-nav-tab">
                        <span class="aiomatic-sidebar-label"><?php esc_html_e('Create Snippet', 'aiomatic-automatic-ai-content-writer'); ?></span>
                    </a>
                    <a href="#tab-2" class="aiomatic-nav-tab">
                        <span class="aiomatic-sidebar-label"><?php esc_html_e('Manage Snippets', 'aiomatic-automatic-ai-content-writer'); ?></span>
                    </a>
                </nav>
            </div>
            <div class="aiomatic-sidebar-footer">
               <strong><?php esc_html_e( 'Need a quick start?', 'aiomatic-automatic-ai-content-writer' ); ?></strong>
               <span><?php esc_html_e( '1. Create your first snippet, start by adding a title.', 'aimogen' ); ?></span>
               <span><?php esc_html_e( '2. Set where it should be active, using conditions.', 'aimogen' ); ?></span>
               <span><?php esc_html_e( '3. Add a prompt based on which, the AI will create the snippet. You can also write the snippet manually.', 'aimogen' ); ?></span>
               <span><?php esc_html_e( '4. Create, verify and manage existing snippets.', 'aimogen' ); ?></span>
               <span>
                  <?php esc_html_e( 'Watch tutorials on', 'aiomatic-automatic-ai-content-writer' ); ?>
                  <a href="https://www.youtube.com/channel/UCVLIksvzyk-D_oEdHab2Lgg" target="_blank" rel="noopener noreferrer">CodeRevolutionTV</a>
               </span>
            </div>
        </div>
    </aside>

    <section class="aiomatic-admin-main">
    <div class="gs_popuptype_holder">

    <div id="tab-0" class="tab-content" style="display:block">
    <br/>

    <h3><?php esc_html_e('AI Snippets Engine Overview', 'aiomatic-automatic-ai-content-writer'); ?></h3>

<p>
<?php esc_html_e(
    'The AI Snippets Engine allows you to create, store, conditionally execute and safely manage custom PHP, JavaScript, CSS and HTML snippets directly inside WordPress.',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<hr/>

<h4><?php esc_html_e('Supported Snippet Types', 'aiomatic-automatic-ai-content-writer'); ?></h4>

<p>
<strong><?php esc_html_e('PHP', 'aiomatic-automatic-ai-content-writer'); ?></strong><br/>
<?php esc_html_e(
    'Executed on template_redirect (frontend only). Runs inside a sandboxed closure and is protected by runtime fatal error detection.',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<p>
<strong><?php esc_html_e('JavaScript', 'aiomatic-automatic-ai-content-writer'); ?></strong><br/>
<?php esc_html_e(
    'Injected inline in the footer via wp_add_inline_script().',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<p>
<strong><?php esc_html_e('CSS', 'aiomatic-automatic-ai-content-writer'); ?></strong><br/>
<?php esc_html_e(
    'Injected inline via wp_add_inline_style().',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<p>
<strong><?php esc_html_e('HTML', 'aiomatic-automatic-ai-content-writer'); ?></strong><br/>
<?php esc_html_e(
    'Printed in the frontend footer and sanitized with wp_kses_post().',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<hr/>

<h4><?php esc_html_e('Execution Order & Priority', 'aiomatic-automatic-ai-content-writer'); ?></h4>

<p>
<?php esc_html_e(
    'Snippets are executed in ascending priority order (lower number = earlier execution). If priorities match, execution falls back to ID order.',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<p>
<?php esc_html_e('Default priority: 10', 'aiomatic-automatic-ai-content-writer'); ?><br/>
<?php esc_html_e('Allowed range: -999 to 999', 'aiomatic-automatic-ai-content-writer'); ?>
</p>

<hr/>

<h4><?php esc_html_e('Conditional Execution', 'aiomatic-automatic-ai-content-writer'); ?></h4>
<p>
<?php esc_html_e(
    'If no conditions are defined, snippets run on the frontend only. They never execute inside wp-admin unless explicitly restricted to Admin.',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>
<p>
<?php esc_html_e(
    'Snippets can be restricted using condition groups:',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<ul>
<li><?php esc_html_e('Each group is evaluated as OR', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('Rules inside a group are evaluated as AND', 'aiomatic-automatic-ai-content-writer'); ?></li>
</ul>

<p><?php esc_html_e('Conditions support:', 'aiomatic-automatic-ai-content-writer'); ?></p>

<ul>
<li><?php esc_html_e('Site area (admin / frontend / global)', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('Query context (home, single, archive, search, 404, etc.)', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('Post type, author, category, tag', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('User state (logged in, role, capability, locale)', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('Date & time ranges', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('Theme, active plugin, debug mode', 'aiomatic-automatic-ai-content-writer'); ?></li>
</ul>

<p>
<?php esc_html_e(
    'Conditions are cached per request fingerprint for performance.',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<hr/>

<h4><?php esc_html_e('Security Model', 'aiomatic-automatic-ai-content-writer'); ?></h4>

<p>
<?php esc_html_e(
    'The engine includes multiple safety layers:',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<ul>
<li><?php esc_html_e('Snippets without conditions are restricted to frontend execution only', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('Token-based PHP validation (blocks unsafe function calls)', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('Direct database access via $wpdb is blocked', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('Dangerous functions like eval, exec, system, etc. are blocked', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('Automatic deactivation on fatal errors', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('Strict PHP activation check before enabling', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('HTML output sanitized', 'aiomatic-automatic-ai-content-writer'); ?></li>
</ul>

<p>
<?php esc_html_e(
    'If a PHP snippet throws a fatal error:',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<ul>
<li><?php esc_html_e('The snippet is automatically deactivated', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('The error message is stored', 'aiomatic-automatic-ai-content-writer'); ?></li>
<li><?php esc_html_e('The issue is logged (if logging is enabled)', 'aiomatic-automatic-ai-content-writer'); ?></li>
</ul>

<hr/>

<h4><?php esc_html_e('AI vs Manual Mode', 'aiomatic-automatic-ai-content-writer'); ?></h4>

<p><?php esc_html_e('Snippets can be created in two ways:', 'aiomatic-automatic-ai-content-writer'); ?></p>

<p>
<strong><?php esc_html_e('AI Mode', 'aiomatic-automatic-ai-content-writer'); ?></strong><br/>
<?php esc_html_e(
    'Code is generated using the selected AI model or assistant. Output is normalized, validated and stored inactive by default.',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<p>
<strong><?php esc_html_e('Manual Mode', 'aiomatic-automatic-ai-content-writer'); ?></strong><br/>
<?php esc_html_e(
    'You provide raw code directly. The same validation and safety checks apply.',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<hr/>

<h4><?php esc_html_e('Caching', 'aiomatic-automatic-ai-content-writer'); ?></h4>

<p>
<?php esc_html_e(
    'Active snippets are cached per blog ID for 60 seconds using WordPress object cache. Cache is automatically flushed when snippets are created, updated, deleted or toggled.',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<hr/>

<h4><?php esc_html_e('Emergency Disable', 'aiomatic-automatic-ai-content-writer'); ?></h4>

<p>
<?php esc_html_e(
    'To completely disable snippet execution, define:',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<pre><code>define('AIMOGEN_DISABLE_SNIPPETS', true);</code></pre>

<p>
<?php esc_html_e(
    'This prevents PHP execution and frontend injection without removing snippets.',
    'aiomatic-automatic-ai-content-writer'
); ?>
</p>

<p>
<?php esc_html_e(
    'Alternatively, you can install the official emergency kill-switch plugin:',
    'aiomatic-automatic-ai-content-writer'
); ?>
<br/>
<a href="https://github.com/CodeRevolutionPlugins/aimogen-emergency-disable-snippets" target="_blank" rel="noopener noreferrer">
    https://github.com/CodeRevolutionPlugins/aimogen-emergency-disable-snippets
</a>
</p>
<?php $aiomatic_Main_Settings = get_option('aiomatic_Main_Settings', false);
if(!isset($aiomatic_Main_Settings['hide_videos']) || trim($aiomatic_Main_Settings['hide_videos']) != 'on'){
?>
<h2><?php echo esc_html__("AI Snippets Tutorial Video", 'aiomatic-automatic-ai-content-writer');?></h2>
<p class="cr_center"><div class="embedtool"><iframe src="https://www.youtube.com/embed/E_3ff29AtsU" frameborder="0" allowfullscreen></iframe></div></p>
<?php
}
?>
</div>

    <div id="tab-1" class="tab-content" style="display:none">
        <br/>
        <?php 
        $all_models = aiomatic_get_all_models(true);
        $all_assistants = aiomatic_get_all_assistants(true);
        if ($editing_snippet): ?>
<script>
document.addEventListener('DOMContentLoaded', function() {
    localStorage.setItem('active-tab', 'tab-1');

    var tabLink = document.querySelector('.aiomatic-nav-tab[href="#tab-1"]');
    if (tabLink) {
        tabLink.click();
    }
});
</script>
<div style="display:flex;justify-content:space-between;align-items:center;">
    <h3 style="margin:0;"><?php esc_html_e(
    'Edit Snippet',
    'aiomatic-automatic-ai-content-writer'
); ?></h3>
    <a href="<?php echo esc_url(
        admin_url('admin.php?page=aiomatic_snippets_panel')
    ); ?>" class="button">
<?php esc_html_e('+ Create New', 'aiomatic-automatic-ai-content-writer'); ?>
    </a>
</div>
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
    <?php wp_nonce_field(self::NONCE_ACTION, self::NONCE_NAME); ?>
    <input type="hidden" name="action" value="aimogen_update_snippet">
    <input type="hidden" name="id" value="<?php echo esc_attr($editing_snippet->id); ?>">

    <table class="form-table">
        <tr>
            <th>
  <span class="aimogen-th">
    <?php esc_html_e('Title', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['title']); ?>">?</span>
  </span>
</th>
            <td>
                <input type="text" name="title" class="regular-text"
                       value="<?php echo esc_attr($editing_snippet->title); ?>" placeholder="Add a title for this snippet" required>
            </td>
        </tr>

        <tr>
            <th>
  <span class="aimogen-th">
    <?php esc_html_e('Type', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['type']); ?>">?</span>
  </span>
</th>
            <td>
                <select name="type">
                    <?php 
$types = [
    'php'  => 'PHP (Server-side executable code)',
    'js'   => 'JavaScript (Code which runs in the browser)',
    'css'  => 'CSS (Controls styling and layout)',
    'html' => 'HTML (Static markup structure)',
];
            foreach ($types as $value => $label): ?>
                <option value="<?php echo esc_attr($value); ?>"
                    <?php selected($editing_snippet->type, $value); ?>>
                    <?php echo esc_html__($label, 'aiomatic-automatic-ai-content-writer'); ?>
                </option>
            <?php endforeach; ?>
                </select>
            </td>
        </tr>
        <tr>
            <th>
  <span class="aimogen-th">
    <?php esc_html_e('Priority', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['priority']); ?>">?</span>
  </span>
</th>
            <td>
                <input type="number"
                    name="priority"
                    value="<?php echo intval($editing_snippet->priority ?? 10); ?>"
                    min="-999"
                    max="999"
                    step="1"
                    placeholder="10"
                    class="small-text">
                <p class="description">
                    <?php esc_html_e('Lower numbers execute earlier. Default is 10.', 'aiomatic-automatic-ai-content-writer'); ?>
                </p>
            </td>
        </tr>                
        <tr>
            <th>
  <span class="aimogen-th">
    <?php esc_html_e('Code *', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['code']); ?>">?</span>
  </span>
</th>
            <td>
                <textarea name="code" rows="14" class="large-text code" placeholder="Add the code for this snippet" required><?php
                    echo esc_textarea($editing_snippet->code);
                ?></textarea>
            </td>
        </tr> 
        <tr>
            <th>
  <span class="aimogen-th">
    <?php esc_html_e('Conditions', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['conditions']); ?>">?</span>
  </span>
</th>
            <td>
                <div id="aimogen-condition-builder"></div>
                <input type="hidden" name="conditions"
                       id="aimogen-conditions-json"
                       value='<?php echo esc_attr($editing_snippet->conditions ?? ''); ?>'>
                <button type="button" class="button" id="aimogen-add-group">
                    <?php esc_html_e('Manually Add Group (OR)', 'aiomatic-automatic-ai-content-writer'); ?>
                </button>
                <button type="button" class="button" id="aimogen-ai-conditions-btn">
                    <?php esc_html_e('Auto Generate Conditions Using AI', 'aiomatic-automatic-ai-content-writer'); ?>
                </button>
            </td>
        </tr>

        <tr>
            <th>
  <span class="aimogen-th">
    <?php esc_html_e('Active', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['active']); ?>">?</span>
  </span>
</th>
            <td>
                <label>
                    <input type="checkbox" name="activate" value="1"
                        <?php checked($editing_snippet->active,1); ?>>
                    <?php esc_html_e('Yes', 'aiomatic-automatic-ai-content-writer'); ?>
                </label>
            </td>
        </tr>
        <tr><td colspan="2"><hr/></td></tr>
        <tr><td colspan="2">
<div style="display:flex;justify-content:space-between;align-items:center;">
    <h3 style="margin:0;"><?php esc_html_e(
    'AI Snippet Editing',
    'aiomatic-automatic-ai-content-writer'
); ?></h3>
</div></td></tr>
        <tr>
    <th>
  <span class="aimogen-th">
    <?php esc_html_e('AI Assistant', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['assistant_id']); ?>">?</span>
  </span>
</th>
    <td>
        <select name="assistant_id" id="assistant_id" class="regular-text" onchange="assistantSnippetSelected();">
            <option value=""><?php esc_html_e('Use AI Model Instead', 'aiomatic-automatic-ai-content-writer'); ?></option>
            <?php
            if (is_array($all_assistants)) {
                foreach ($all_assistants as $assistant) {
                    echo '<option value="' . esc_attr($assistant->ID) . '"';
                    if ($editing_snippet && $editing_snippet->assistant_id == $assistant->ID) {
                        echo ' selected';
                    }
                    echo '>' . esc_html($assistant->post_title) . '</option>';
                }
            }
            ?>
        </select>
    </td>
</tr>

<tr>
    <th>
  <span class="aimogen-th">
    <?php esc_html_e('AI Model', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['ai_model']); ?>">?</span>
  </span>
</th>
    <td>
        <select name="ai_model" id="ai_model" class="regular-text aiomatic-disabled-model">
            <?php
            if (is_array($all_models)) {
                foreach ($all_models as $model) {
                    echo '<option value="' . esc_attr($model) . '"';
                    if ($editing_snippet && $editing_snippet->ai_model == $model) {
                        echo ' selected';
                    }
                    echo '>' . esc_html($model) . esc_html(aiomatic_get_model_provider($model)) . '</option>';
                }
            }
            ?>
        </select>
        <p class="description"><?php esc_html_e('Used only if no assistant is selected.', 'aiomatic-automatic-ai-content-writer'); ?></p>
    </td>
</tr>
        <tr>
            <th>
  <span class="aimogen-th">
    <?php esc_html_e('Edit Using AI Prompt', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['ai_guidance']); ?>">?</span>
  </span>
</th>
            <td>
                <textarea name="ai_guidance" rows="4" class="large-text"
                    placeholder="Describe what you want to change..."></textarea>

                <p style="margin-top:8px;">
                    <button type="submit"
                        name="action"
                        value="aimogen_ai_edit_snippet"
                        class="button">
                        <?php esc_html_e('Modify With AI', 'aiomatic-automatic-ai-content-writer'); ?>
                    </button>
                </p>
            </td>
        </tr>
               
    </table>

    <p>
        <input type="submit" class="button button-primary"
               value="Update Snippet">
    </p>
</form>

<?php else: ?>
        <h3><?php esc_html_e('Create AI Snippet', 'aiomatic-automatic-ai-content-writer'); ?></h3>

        <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
            <?php wp_nonce_field(self::NONCE_ACTION, self::NONCE_NAME); ?>
            <input type="hidden" name="action" value="aimogen_create_snippet">

            <table class="form-table">
                <tr>
                    <th>
  <span class="aimogen-th">
    <?php esc_html_e('Title *', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['title']); ?>">?</span>
  </span>
</th>
                    <td><input type="text" name="title" class="regular-text" placeholder="Add a title for this snippet" required></td>
                </tr>

                <tr>
                    <th>
  <span class="aimogen-th">
    <?php esc_html_e('Type', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['type']); ?>">?</span>
  </span>
</th>
                    <td>
                        <select name="type">
                            <option value="auto"><?php esc_html_e('Auto Detect', 'aiomatic-automatic-ai-content-writer'); ?></option>
                            <option value="php"><?php esc_html_e('PHP (Server-side executable code)', 'aiomatic-automatic-ai-content-writer'); ?></option>
                            <option value="js"><?php esc_html_e('JavaScript (Code which runs in the browser)', 'aiomatic-automatic-ai-content-writer'); ?></option>
                            <option value="css"><?php esc_html_e('CSS (Controls styling and layout)', 'aiomatic-automatic-ai-content-writer'); ?></option>
                            <option value="html"><?php esc_html_e('HTML (Static markup structure)', 'aiomatic-automatic-ai-content-writer'); ?></option>
                        </select>
                    </td>
                </tr>
                <tr>
                    <th>
  <span class="aimogen-th">
    <?php esc_html_e('Priority', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['priority']); ?>">?</span>
  </span>
</th>
                    <td>
                        <input type="number"
                            name="priority"
                            value="10"
                            min="-999"
                            max="999"
                            step="1"
                            placeholder="10" 
                            class="small-text">
                        <p class="description">
                            <?php esc_html_e('Lower numbers execute earlier. Default is 10.', 'aiomatic-automatic-ai-content-writer'); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th>
  <span class="aimogen-th">
    <?php esc_html_e('Conditions', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['conditions']); ?>">?</span>
  </span>
</th>
                    <td>
                        <div id="aimogen-condition-builder"></div>
                        <input type="hidden" name="conditions" id="aimogen-conditions-json">
                        <button type="button" class="button" id="aimogen-add-group">
                            <?php esc_html_e('Manually Add Group (OR)', 'aiomatic-automatic-ai-content-writer'); ?>
                        </button>
                        <button type="button" class="button" id="aimogen-ai-conditions-btn">
                            <?php esc_html_e('Auto Generate Conditions Using AI', 'aiomatic-automatic-ai-content-writer'); ?>
                        </button>
                        <p class="description"><?php esc_html_e('Each group is OR. Rules inside group are AND. Empty conditions run on frontend only. If you want to run on admin, explicitly define conditions.', 'aiomatic-automatic-ai-content-writer'); ?></p>
                    </td>
                </tr>
                <tr>
                    <th>
  <span class="aimogen-th">
    <?php esc_html_e('AI Assistant', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['assistant_id']); ?>">?</span>
  </span>
</th>
                    <td>
                        <select name="assistant_id" id="assistant_id2" class="regular-text" onchange="assistantSnippetSelected2();">
                            <option value=""><?php esc_html_e('Use AI Model Instead', 'aiomatic-automatic-ai-content-writer'); ?></option>
                            <?php
                            if (is_array($all_assistants)) {
                                foreach ($all_assistants as $assistant) {
                                    echo '<option value="' . esc_attr($assistant->ID) . '">' .
                                        esc_html($assistant->post_title) .
                                        '</option>';
                                }
                            }
                            ?>
                        </select>
                    </td>
                </tr>

                <tr>
                    <th>
  <span class="aimogen-th">
    <?php esc_html_e('AI Model', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['ai_model']); ?>">?</span>
  </span>
</th>
                    <td>
                        <select name="ai_model" id="ai_model2" class="regular-text aiomatic-disabled-model2">
                            <?php
                            if (is_array($all_models)) {
                                foreach ($all_models as $model) {
                                    echo '<option value="' . esc_attr($model) . '">' .
                                        esc_html($model) .
                                        esc_html(aiomatic_get_model_provider($model)) .
                                        '</option>';
                                }
                            }
                            ?>
                        </select>
                        <p class="description"><?php esc_html_e('Used only if no assistant is selected.', 'aiomatic-automatic-ai-content-writer'); ?></p>
                    </td>
                </tr>
                <tr>
                    <th>
  <span class="aimogen-th">
    <?php esc_html_e('Creation Mode', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['creation_mode']); ?>">?</span>
  </span>
</th>
                    <td>
                        <label>
                            <input type="radio" name="creation_mode" value="ai" checked>
                            <?php esc_html_e('Generate with AI', 'aiomatic-automatic-ai-content-writer'); ?>
                        </label>
                        <br>
                        <label>
                            <input type="radio" name="creation_mode" value="manual">
                            <?php esc_html_e('Write Code Manually', 'aiomatic-automatic-ai-content-writer'); ?>
                        </label>
                    </td>
                </tr>
                <tr class="aimogen-ai-field">
                    <th>
  <span class="aimogen-th">
    <?php esc_html_e('Prompt *', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['prompt']); ?>">?</span>
  </span>
</th>
                    <td>
                        <textarea name="prompt" rows="8" class="large-text" placeholder="Add the prompt based on which the AI will generate the content for this snippet"></textarea>
                    </td>
                </tr>
                <tr class="aimogen-manual-field" style="display:none;">
                    <th>
  <span class="aimogen-th">
    <?php esc_html_e('Code *', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['code']); ?>">?</span>
  </span>
</th>
                    <td>
                        <textarea name="code" rows="14" class="large-text code" placeholder="Add the code for this snippet" ></textarea>
                    </td>
                </tr>
                <tr>
                    <th>
  <span class="aimogen-th">
    <?php esc_html_e('Activate Immediately', 'aiomatic-automatic-ai-content-writer'); ?>
    <span class="aimogen-tip" tabindex="0"
      data-tip="<?php echo esc_attr($aimogen_tooltips['activate_immediately']); ?>">?</span>
  </span>
</th>
                    <td>
                        <label><input type="checkbox" name="activate" value="1"> <?php esc_html_e('Yes', 'aiomatic-automatic-ai-content-writer'); ?></label>
                    </td>
                </tr>
            </table>

            <p class="crsubmit">
                <input type="submit" class="button button-primary" value="<?php esc_html_e('Generate & Save', 'aiomatic-automatic-ai-content-writer'); ?>">
            </p>
        </form>
<script>
document.addEventListener('DOMContentLoaded', function() {
    document.querySelectorAll('input[name="creation_mode"]').forEach(el => {
        el.addEventListener('change', function() {
            const isAI = this.value === 'ai';
            document.querySelector('.aimogen-ai-field').style.display = isAI ? '' : 'none';
            document.querySelector('.aimogen-manual-field').style.display = isAI ? 'none' : '';
        });
    });
});
</script>
<?php endif; ?>
    </div>

    <div id="tab-2" class="tab-content" style="display:none">
        <br/>
        <h3><?php esc_html_e('Existing Snippets', 'aiomatic-automatic-ai-content-writer'); ?></h3>

    <?php if ($snippets): ?>
        <div class="aiomatic-snippet-tabs">

            <a href="<?php echo esc_url(admin_url('admin.php?page=aiomatic_snippets_panel')); ?>"
            class="<?php echo $current_type==='all' ? 'current' : ''; ?>">
            All (<?php echo $total_count; ?>)
            </a>

            <?php 
        $types = ['php','js','css','html'];
        foreach ($types as $t): ?>
            <a href="<?php echo esc_url(admin_url('admin.php?page=aiomatic_snippets_panel&type='.$t)); ?>"
            class="<?php echo $current_type===$t ? 'current' : ''; ?>">
            <?php echo strtoupper($t); ?> (<?php echo $counts[$t]; ?>)
            </a>
            <?php endforeach; ?>

            <span class="separator">|</span>

<?php
$base_url = admin_url('admin.php?page=aiomatic_snippets_panel');

$base_args = [
    'type' => $current_type !== 'all' ? $current_type : null,
];

$base_args = array_filter($base_args);
?>

<a href="<?php echo esc_url(add_query_arg(array_merge($base_args, ['status' => 'active']), $base_url)); ?>"
class="<?php echo $current_status==='active' ? 'current' : ''; ?>">
<?php esc_html_e('Active', 'aiomatic-automatic-ai-content-writer'); ?> (<?php echo $active_count; ?>)
</a>

<a href="<?php echo esc_url(add_query_arg(array_merge($base_args, ['status' => 'inactive']), $base_url)); ?>"
class="<?php echo $current_status==='inactive' ? 'current' : ''; ?>">
<?php esc_html_e('Inactive', 'aiomatic-automatic-ai-content-writer'); ?> (<?php echo $inactive_count; ?>)
</a>
</div>

<div class="aiomatic-toolbar">
    <form id="aimogen-bulk-form" method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" class="aiomatic-bulk-form">
        <?php wp_nonce_field('aimogen_bulk_action'); ?>
        <input type="hidden" name="action" value="aimogen_bulk_action">

        <select name="bulk_action">
            <option value=""><?php esc_html_e('Bulk actions', 'aiomatic-automatic-ai-content-writer'); ?></option>
            <option value="activate"><?php esc_html_e('Activate', 'aiomatic-automatic-ai-content-writer'); ?></option>
            <option value="deactivate"><?php esc_html_e('Deactivate', 'aiomatic-automatic-ai-content-writer'); ?></option>
            <option value="delete"><?php esc_html_e('Delete', 'aiomatic-automatic-ai-content-writer'); ?></option>
        </select>

        <button type="submit"><?php esc_html_e('Apply', 'aiomatic-automatic-ai-content-writer'); ?></button>
    </form>

    <!-- RIGHT: Search -->
    <form method="get" action="<?php echo esc_url(admin_url('admin.php')); ?>" class="aiomatic-search-form">
        <input type="hidden" name="page" value="aiomatic_snippets_panel">

        <?php if ($current_type !== 'all'): ?>
            <input type="hidden" name="type" value="<?php echo esc_attr($current_type); ?>">
        <?php endif; ?>

        <?php if ($current_status !== 'all'): ?>
            <input type="hidden" name="status" value="<?php echo esc_attr($current_status); ?>">
        <?php endif; ?>

        <input type="search"
               name="s"
               value="<?php echo isset($_GET['s']) ? esc_attr(wp_unslash($_GET['s'])) : ''; ?>"
               placeholder="Search snippets...">

        <button type="submit"><?php esc_html_e('Search', 'aiomatic-automatic-ai-content-writer'); ?></button>
</form>

</div>

<table class="aiomatic-table">
            <thead>
                <tr>
                    <th>
    <input type="checkbox" id="aimogen-select-all">
</th>
                    <th><?php esc_html_e('Title *', 'aiomatic-automatic-ai-content-writer'); ?></th>
                    <th><?php esc_html_e('Type', 'aiomatic-automatic-ai-content-writer'); ?></th>
                    <th><?php esc_html_e('Status', 'aiomatic-automatic-ai-content-writer'); ?></th>
                    <th><?php esc_html_e('Priority', 'aiomatic-automatic-ai-content-writer'); ?></th>
                    <th><?php esc_html_e('Actions', 'aiomatic-automatic-ai-content-writer'); ?></th>
                </tr>
            </thead>
            <tbody>
            <?php foreach ($snippets as $snippet): ?>
                <tr>
                    <td data-label="Select"><input type="checkbox" name="snippet_ids[]" value="<?php echo $snippet->id; ?>" form="aimogen-bulk-form"></td>
                    <td data-label="Title"><?php echo esc_html($snippet->title); ?></td>
                    <td data-label="Type"><span class="snippet-type-badge type-<?php echo esc_attr($snippet->type); ?>">
<?php echo strtoupper($snippet->type); ?>
</span></td>
                    <td data-label="Status">
<?php if (!empty($snippet->has_error)): ?>
    <span style="color:#dc2626;font-weight:600;" title="<?php echo esc_attr($snippet->last_error); ?>">
        Error
    </span>
<?php else: ?>
    <span class="<?php echo $snippet->active ? 'status-active' : 'status-inactive'; ?>">
        <?php echo $snippet->active ? 'Active' : 'Inactive'; ?>
    </span>
<?php endif; ?>
</td>
                    <td data-label="Priority"><?php echo intval($snippet->priority ?? 10); ?></td>
                    <td data-label="Actions">
    <div class="aiomatic-actions">
    <a href="<?php echo esc_url(
        add_query_arg(
            ['page' => 'aiomatic_snippets_panel', 'edit' => $snippet->id],
            admin_url('admin.php')
        )
    ); ?>" class="button button-small">
        <?php esc_html_e('Edit', 'aiomatic-automatic-ai-content-writer'); ?>
    </a>
<?php
$clone_url = wp_nonce_url(
    add_query_arg(
        [
            'action' => 'aimogen_clone_snippet',
            'id'     => $snippet->id,
        ],
        admin_url('admin-post.php')
    ),
    self::NONCE_ACTION,
    self::NONCE_NAME
);
$delete_url = wp_nonce_url(
    add_query_arg(
        [
            'action' => 'aimogen_delete_snippet',
            'id'     => $snippet->id,
        ],
        admin_url('admin-post.php')
    ),
    self::NONCE_ACTION,
    self::NONCE_NAME
);
?>
<a href="<?php echo esc_url($clone_url); ?>" class="button button-small" style="margin-left:6px;">
    <?php esc_html_e('Clone', 'aiomatic-automatic-ai-content-writer'); ?>
</a>
<a href="<?php echo esc_url($delete_url); ?>"
       class="button button-small"
       style="margin-left:6px;"
       onclick="return confirm('<?php echo esc_js(__('Are you sure you want to delete this snippet?', 'aiomatic-automatic-ai-content-writer')); ?>');">
        <?php esc_html_e('Delete', 'aiomatic-automatic-ai-content-writer'); ?>
    </a>
    <label class="aiomatic-switch" style="margin-left:8px;">
        <input type="checkbox"
               data-id="<?php echo intval($snippet->id); ?>"
               class="toggle-snippet"
               <?php checked($snippet->active,1); ?>>
        <span class="slider"></span>
    </label>
    </div>
</td>
                </tr>
            <?php endforeach; ?>
            </tbody>
        </table>

<?php if ($total_pages > 1): ?>

<div class="aiomatic-pagination">

    <?php
    $base_url = admin_url('admin.php?page=aiomatic_snippets_panel');

    $query_args = [
        'type'   => $current_type !== 'all' ? $current_type : null,
        'status' => $current_status !== 'all' ? $current_status : null,
        's'      => !empty($_GET['s']) ? $_GET['s'] : null,
    ];

    $query_args = array_filter($query_args);

    for ($i = 1; $i <= $total_pages; $i++):
        $url = add_query_arg(array_merge($query_args, ['paged' => $i]), $base_url);
    ?>

        <a href="<?php echo esc_url($url); ?>"
           class="<?php echo $i == $paged ? 'current' : ''; ?>">
           <?php echo $i; ?>
        </a>

    <?php endfor; ?>

</div>

<?php endif; ?>
    <?php else: ?>

    <?php if (!empty($_GET['s']) || $current_type !== 'all' || $current_status !== 'all'): ?>

        <div class="aiomatic-empty">
            <strong><?php esc_html_e('No matching snippets found.', 'aiomatic-automatic-ai-content-writer'); ?></strong>
            <p>
                <?php esc_html_e('Your filters or search did not return any results.', 'aiomatic-automatic-ai-content-writer'); ?>
            </p>
            <a class="button" href="<?php echo esc_url(admin_url('admin.php?page=aiomatic_snippets_panel')); ?>">
                <?php esc_html_e('Clear Filters', 'aiomatic-automatic-ai-content-writer'); ?>
            </a>
        </div>

    <?php else: ?>

        <div class="aiomatic-empty">
            <strong><?php esc_html_e('No snippets created yet.', 'aiomatic-automatic-ai-content-writer'); ?></strong>
            <p><?php esc_html_e('Create your first AI snippet from the “Create Snippet” tab.', 'aiomatic-automatic-ai-content-writer'); ?></p>
        </div>

    <?php endif; ?>

<?php endif; ?>
    </div>

    </div>
    </section>
<div id="aimogen-ai-conditions-modal" style="display:none;">
    <div class="aimogen-ai-conditions-backdrop"></div>
    <div class="aimogen-ai-conditions-panel" role="dialog" aria-modal="true" aria-labelledby="aimogen-ai-conditions-title">
        <h3 id="aimogen-ai-conditions-title" style="margin-top:0;">
            <?php esc_html_e('Describe when this should run', 'aiomatic-automatic-ai-content-writer'); ?>
        </h3>

        <textarea id="aimogen-ai-conditions-text" rows="5" class="large-text"
            placeholder="<?php echo esc_attr__('Example: Only on single posts for logged-in editors on weekdays', 'aiomatic-automatic-ai-content-writer'); ?>"></textarea>

        <div style="display:flex;gap:10px;justify-content:flex-end;margin-top:12px;">
            <button type="button" class="button" id="aimogen-ai-conditions-cancel">
                <?php esc_html_e('Cancel', 'aiomatic-automatic-ai-content-writer'); ?>
            </button>
            <button type="button" class="button button-primary" id="aimogen-ai-conditions-generate">
                <?php esc_html_e('Generate', 'aiomatic-automatic-ai-content-writer'); ?>
            </button>
        </div>

        <div id="aimogen-ai-conditions-status" style="margin-top:10px;font-size:13px;"></div>
    </div>
</div>
    </div>
    </div>
<style>
.aimogen-ai-conditions-backdrop{
    position:fixed;inset:0;background:rgba(15,23,42,.55);z-index:100000;
}
.aimogen-ai-conditions-panel{
    position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);
    width:min(720px,calc(100% - 30px));
    background:#fff;border-radius:14px;padding:18px 18px 16px;
    box-shadow:0 20px 60px rgba(0,0,0,.25);
    z-index:100001;
}
.aimogen-tip {
    display:inline-flex;
    align-items:center;
    justify-content:center;
    width:18px;
    height:18px;
    margin-left:8px;
    border-radius:999px;
    background:#e2e8f0;
    color:#334155;
    font-size:12px;
    font-weight:700;
    line-height:1;
    cursor:help;
    user-select:none;
    position:relative;
}
.aimogen-tip[data-tip]:hover::after,
.aimogen-tip[data-tip]:focus::after {
    content: attr(data-tip);
    position:absolute;
    left: 0;
    top: calc(100% + 8px);
    background:#0f172a;
    color:#fff;
    padding:8px 10px;
    border-radius:10px;
    white-space:normal;
    width:max-content;
    max-width:320px;
    box-shadow:0 10px 30px rgba(0,0,0,0.25);
    z-index:9999;
    font-weight:500;
    font-size:12px;
}
.aimogen-tip[data-tip]:hover::before,
.aimogen-tip[data-tip]:focus::before {
    content:"";
    position:absolute;
    left: 10px;
    top: calc(100% + 2px);
    border:6px solid transparent;
    border-bottom-color:#0f172a;
}
.aimogen-th {
    display:inline-flex;
    align-items:center;
}
.aimogen-rule button,
.aimogen-group button {
    background:#fee2e2;
    border-color:#fca5a5;
}
.aiomatic-pagination {
    margin-top: 20px;
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}
.aiomatic-pagination a {
    display: inline-block;
    min-width: 34px;
    text-align: center;
    padding: 6px 10px;
    border-radius: 8px;
    background: #e2e8f0;
    color: #1e293b;
    text-decoration: none;
    font-weight: 500;
    font-size: 13px;
    transition: all .2s ease;
}
.aiomatic-pagination a:hover {
    background: #cbd5e1;
}
.aiomatic-pagination a.current {
    background: #1f2a44;
    color: #fff;
}
.snippet-type-badge {
    padding:4px 8px;
    border-radius:4px;
    font-size:12px;
    font-weight:600;
    color:#fff;
}
.type-php { background:#2271b1; }
.type-js { background:#f7df1e; color:#000; }
.type-css { background:#563d7c; }
.type-html { background:#e34c26; }
.aiomatic-admin-main {
    background: #f4f6f9;
    padding: 24px;
    border-radius: 14px;
}
.tab-content h3 {
    margin-bottom: 16px;
    font-size: 18px;
    font-weight: 600;
}
.aiomatic-snippet-tabs {
    margin-bottom: 18px;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}
.aiomatic-snippet-tabs a {
    padding: 6px 12px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
    background: #e9edf3;
    color: #2c3e50;
    transition: all .2s ease;
}
.aiomatic-snippet-tabs a:hover {
    background: #d8e2f1;
}
.aiomatic-snippet-tabs a.current {
    background: #1f2a44;
    color: #fff;
}
.aiomatic-snippet-tabs .separator {
    margin: 0 6px;
    color: #9aa3af;
}
.aiomatic-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
    flex-wrap: wrap;
    gap: 10px;
}
.aiomatic-toolbar select,
.aiomatic-toolbar input[type="search"] {
    height: 34px;
    padding: 0 10px;
    border-radius: 8px;
    border: 1px solid #d1d5db;
    background: #fff;
    font-size: 13px;
}
.aiomatic-toolbar button {
    height: 34px;
    padding: 0 14px;
    border-radius: 8px;
    border: none;
    background: #1f2a44;
    color: #fff;
    font-weight: 500;
    cursor: pointer;
    transition: background .2s ease;
}
.aiomatic-toolbar button:hover {
    background: #0f172a;
}
.aiomatic-table {
    width: 100%;
    border-collapse: collapse;
    background: #fff;
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 8px 20px rgba(0,0,0,0.04);
}
.aiomatic-table thead {
    background: #f8fafc;
}
.aiomatic-table th {
    text-align: left;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .5px;
    padding: 14px 16px;
    color: #64748b;
}
.aiomatic-table td {
    padding: 16px;
    border-top: 1px solid #f1f5f9;
    font-size: 14px;
    color: #1e293b;
}
.aiomatic-table tbody tr:hover {
    background: #f9fafb;
}
.snippet-type-badge {
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .4px;
}
.type-php  { background:#e0f2fe; color:#0369a1; }
.type-js   { background:#fef9c3; color:#92400e; }
.type-css  { background:#ede9fe; color:#6b21a8; }
.type-html { background:#fee2e2; color:#b91c1c; }
.status-active {
    color: #16a34a;
    font-weight: 600;
}
.status-inactive {
    color: #94a3b8;
    font-weight: 500;
}
.aiomatic-switch {
    position: relative;
    display: inline-block;
    width: 42px;
    height: 22px;
}
.aiomatic-switch input {
    opacity: 0;
    width: 0;
    height: 0;
}
.aiomatic-switch .slider {
    position: absolute;
    cursor: pointer;
    inset: 0;
    background-color: #cbd5e1;
    border-radius: 999px;
    transition: .25s;
}
.aiomatic-switch .slider:before {
    content: "";
    position: absolute;
    height: 18px;
    width: 18px;
    left: 2px;
    bottom: 2px;
    background-color: #fff;
    border-radius: 50%;
    transition: .25s;
}
.aiomatic-switch input:checked + .slider {
    background-color: #22c55e;
}
.aiomatic-switch input:checked + .slider:before {
    transform: translateX(20px);
}
.aiomatic-empty {
    padding: 40px;
    text-align: center;
    color: #64748b;
}
.aimogen-group {
    background:#f8fafc;
    padding:12px;
    border-radius:8px;
    margin-bottom:12px;
}
.aimogen-rule {
    display:flex;
    gap:10px;
    margin-bottom:10px;
}
.aiomatic-table {
    width: 100%;
    table-layout: fixed;
}
.aiomatic-table th:nth-child(1),
.aiomatic-table td:nth-child(1) {
    width: 50px;
    text-align: center;
}
.aiomatic-table th:nth-child(2),
.aiomatic-table td:nth-child(2) {
    width: auto;
}
.aiomatic-table th:nth-child(3),
.aiomatic-table td:nth-child(3) {
    width: 100px;
    text-align: center;
}
.aiomatic-table th:nth-child(4),
.aiomatic-table td:nth-child(4) {
    width: 110px;
}
.aiomatic-table th:nth-child(5),
.aiomatic-table td:nth-child(5) {
    width: 80px;
    text-align:center;
}
.aiomatic-table th:nth-child(6),
.aiomatic-table td:nth-child(6) {
    width: 220px;
    white-space: nowrap;
}
.aiomatic-table td:nth-child(2) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.aiomatic-actions {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.aiomatic-actions .aiomatic-switch {
    margin-left: 6px;
}
.aiomatic-table {
    width: 100%;
    table-layout: auto;
}
.aiomatic-table th:nth-child(1),
.aiomatic-table td:nth-child(1) {
    width: 40px;
    text-align: center;
}
.aiomatic-table th:nth-child(3),
.aiomatic-table td:nth-child(3) {
    width: 90px;
    text-align: center;
}
.aiomatic-table th:nth-child(4),
.aiomatic-table td:nth-child(4) {
    width: 100px;
}
.aiomatic-table th:nth-child(5),
.aiomatic-table td:nth-child(5) {
    width: 80px;
    text-align:center;
}
.aiomatic-table th:nth-child(6),
.aiomatic-table td:nth-child(6) {
    width: 200px;
    white-space: nowrap;
}
.aiomatic-table td:nth-child(2) {
    max-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
@media (max-width: 782px) {
    .aiomatic-table {
        table-layout: auto;
        font-size: 13px;
    }
    .aiomatic-table th:nth-child(3),
    .aiomatic-table td:nth-child(3) {
        display: none;
    }
    .aiomatic-table th:nth-child(4),
    .aiomatic-table td:nth-child(4) {
        display: none;
    }
    .aiomatic-table th:nth-child(5),
    .aiomatic-table td:nth-child(5) {
        display: none;
    }
    .aiomatic-table td:nth-child(6) {
        width: auto;
    }
    .aiomatic-table td:nth-child(6) .button {
        padding: 4px 8px;
        font-size: 12px;
    }
    .aiomatic-switch {
        transform: scale(.9);
    }
}
.aiomatic-bulk-form {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: nowrap;
}
.aiomatic-bulk-form select {
    margin: 0;
}
.aiomatic-bulk-form button {
    margin: 0;
}
    </style>
    <script>
document.addEventListener('DOMContentLoaded', function() {
    const modal = document.getElementById('aimogen-ai-conditions-modal');
    const btn = document.getElementById('aimogen-ai-conditions-btn');

    if (!modal || !btn) return;

    const cancel = document.getElementById('aimogen-ai-conditions-cancel');
    const gen = document.getElementById('aimogen-ai-conditions-generate');
    const text = document.getElementById('aimogen-ai-conditions-text');
    const status = document.getElementById('aimogen-ai-conditions-status');

    const openModal = () => {
        status.textContent = '';
        modal.style.display = 'block';
        setTimeout(() => text && text.focus(), 50);
    };

    const closeModal = () => {
        modal.style.display = 'none';
    };

    btn.addEventListener('click', openModal);
    cancel.addEventListener('click', closeModal);

    modal.addEventListener('click', function(e) {
        if (e.target && e.target.classList.contains('aimogen-ai-conditions-backdrop')) {
            closeModal();
        }
    });

    gen.addEventListener('click', function() {

        const v = (text.value || '').trim();
        if (!v) {
            status.textContent = 'Write a short description first.';
            return;
        }

        status.textContent = 'Generating…';
        gen.disabled = true;

        const assistantEl = document.getElementById('assistant_id') || document.getElementById('assistant_id2');
        const modelEl = document.getElementById('ai_model') || document.getElementById('ai_model2');

        fetch(ajaxurl, {
            method: 'POST',
            body: new URLSearchParams({
                action: 'aimogen_generate_conditions_ajax',
                text: v,
                assistant_id: assistantEl ? assistantEl.value : '',
                ai_model: modelEl ? modelEl.value : '',
                _ajax_nonce: '<?php echo wp_create_nonce("aimogen_conditions_ai_nonce"); ?>'
            })
        })
        .then(r => r.json())
        .then(res => {

            if (!res || !res.success) {
                const msg = res && res.data && res.data.message ? res.data.message : 'Failed to generate conditions.';
                status.textContent = msg;
                return;
            }

            const json = res.data.conditions || '';
            if (!json) {
                status.textContent = 'Empty conditions.';
                return;
            }

            const hidden = document.getElementById('aimogen-conditions-json');
            if (hidden) hidden.value = json;

            try {
                const parsed = JSON.parse(json);
                groups = parsed.map(group => {
                    if (Array.isArray(group)) return { rules: group };
                    if (group && group.rules) return group;
                    return { rules: [] };
                }).filter(g => g.rules && g.rules.length);

                renderBuilder();
            } catch (e) {
                status.textContent = 'Generated JSON could not be parsed.';
                return;
            }

            status.textContent = 'Applied. You can still edit it manually.';
            setTimeout(closeModal, 350);
        })
        .catch(() => {
            status.textContent = 'Request failed.';
        })
        .finally(() => {
            gen.disabled = false;
        });
    });
});
function assistantSnippetSelected()
{
    if(jQuery('#assistant_id').val() == '')
    {
        jQuery('.aiomatic-disabled-model').find('option').removeAttr('disabled');
    }
    else
    {
        jQuery('.aiomatic-disabled-model').find('option').attr('disabled', 'disabled');
    }
}
function assistantSnippetSelected2()
{
    if(jQuery('#assistant_id2').val() == '')
    {
        jQuery('.aiomatic-disabled-model2').find('option').removeAttr('disabled');
    }
    else
    {
        jQuery('.aiomatic-disabled-model2').find('option').attr('disabled', 'disabled');
    }
}
document.addEventListener('DOMContentLoaded', function() {
    assistantSnippetSelected();
    const master = document.getElementById('aimogen-select-all');
    if (!master) return;

    const getItems = () =>
        document.querySelectorAll('input[name="snippet_ids[]"]');

    master.addEventListener('change', function() {
        getItems().forEach(cb => {
            cb.checked = master.checked;
        });
    });

    document.addEventListener('change', function(e) {
        if (!e.target.matches('input[name="snippet_ids[]"]')) return;

        const items = getItems();
        const checked = document.querySelectorAll('input[name="snippet_ids[]"]:checked');

        master.checked = items.length > 0 && items.length === checked.length;
    });

});
document.addEventListener('DOMContentLoaded', function() {
    (function(){
        const tabs = document.querySelectorAll('.nav-tab-wrapper .aiomatic-nav-tab');
        const contents = document.querySelectorAll('.tab-content');

        tabs.forEach(tab => tab.addEventListener('click', function(e){
            e.preventDefault();
            tabs.forEach(t => t.classList.remove('nav-tab-active'));
            this.classList.add('nav-tab-active');
            contents.forEach(c => c.style.display = 'none');
            const target = document.querySelector(this.getAttribute('href'));
            if (target) target.style.display = 'block';
        }));
    })();
    document.querySelectorAll('.toggle-snippet').forEach(el => {
        el.addEventListener('change', function(){
            const id = this.dataset.id;
            fetch(ajaxurl, {
                method:'POST',
                body:new URLSearchParams({
                    action:'aimogen_toggle_snippet_ajax',
                    id:id,
                    state:this.checked ? 1 : 0,
                    _ajax_nonce:'<?php echo wp_create_nonce("aimogen_toggle_nonce"); ?>'
                })
            });
        });
    });
});
<?php

$aimogen_roles = [];
$wp_roles = wp_roles();
if ($wp_roles && !empty($wp_roles->roles)) {
    foreach ($wp_roles->roles as $role_key => $role_data) {
        $aimogen_roles[] = [
            'value' => $role_key,
            'label' => translate_user_role($role_data['name']),
        ];
    }
}

$aimogen_post_types = [];
$post_types = get_post_types(['public' => true], 'objects');
foreach ($post_types as $pt) {
    $aimogen_post_types[] = [
        'value' => $pt->name,
        'label' => $pt->labels->singular_name ?: $pt->label ?: $pt->name,
    ];
}

$aimogen_users = [];
$users = get_users(['fields' => ['ID','display_name']]);
foreach ($users as $u) {
    $aimogen_users[] = [
        'value' => $u->ID,
        'label' => $u->display_name,
    ];
}

$aimogen_themes = [
    ['value'=>get_stylesheet(),'label'=>'Current Stylesheet'],
    ['value'=>get_template(),'label'=>'Current Template']
];

?>
const AIMOGEN_DYNAMIC_ROLES = <?php echo wp_json_encode($aimogen_roles); ?>;
const AIMOGEN_DYNAMIC_POST_TYPES = <?php echo wp_json_encode($aimogen_post_types); ?>;
const AIMOGEN_DYNAMIC_USERS = <?php echo wp_json_encode($aimogen_users); ?>;
const AIMOGEN_DYNAMIC_THEMES = <?php echo wp_json_encode($aimogen_themes); ?>;
const AIMOGEN_CONDITION_SCHEMA = {

    siteArea: {
        label: 'Site Area',
        operators: ['is','is not'],
        multiple: false,
        objects: [
            {value:'global',label:'Global'},
            {value:'frontend',label:'Frontend'},
            {value:'admin',label:'Admin'}
        ]
    },

    currentQuery: {
        label: 'Current Query',
        operators: ['is','is not'],
        multiple: true,
        objects: [
            {value:'home',label:'Home'},
            {value:'frontpage',label:'Front Page'},
            {value:'single',label:'Single'},
            {value:'page',label:'Page'},
            {value:'archive',label:'Archive'},
            {value:'search',label:'Search'},
            {value:'404',label:'404'},
            {value:'postTypeArchive',label:'Post Type Archive'}
        ]
    },

    visitorLanguage: {
        label: 'Visitor Language',
        operators: ['in','not in'],
        multiple: true,
        input: 'text'
    },

    currentTheme: {
        label: 'Current Theme',
        operators: ['in','not in'],
        multiple: true,
        objects: AIMOGEN_DYNAMIC_THEMES
    },

    activePlugin: {
        label: 'Active Plugin',
        operators: ['in','not in'],
        multiple: true,
        input: 'text'
    },

    debugEnabled: {
        label: 'Debug Enabled',
        operators: ['is','is not'],
        multiple: false,
        objects: [
            {value:'true',label:'True'}
        ]
    },

    post: {
        label: 'Post',
        operators: ['in','not in'],
        multiple: true,
        input: 'number'
    },

    page: {
        label: 'Page',
        operators: ['in','not in'],
        multiple: true,
        input: 'number'
    },

    postType: {
        label: 'Post Type',
        operators: ['in','not in'],
        multiple: true,
        objects: AIMOGEN_DYNAMIC_POST_TYPES
    },

    tag: {
        label: 'Tag',
        operators: ['in','not in'],
        multiple: true,
        input: 'text'
    },

    category: {
        label: 'Category',
        operators: ['in','not in'],
        multiple: true,
        input: 'text'
    },

    author: {
        label: 'Author',
        operators: ['in','not in'],
        multiple: true,
        objects: AIMOGEN_DYNAMIC_USERS
    },

    postStatus: {
        label: 'Post Status',
        operators: ['in','not in'],
        multiple: true,
        objects: [
            {value:'publish',label:'Published'},
            {value:'draft',label:'Draft'},
            {value:'pending',label:'Pending'},
            {value:'private',label:'Private'}
        ]
    },

    postParent: {
        label: 'Post Parent',
        operators: ['in','not in'],
        multiple: true,
        input:'number'
    },

    postPublished: {
        label: 'Post Published Date',
        operators:['before','after','between'],
        input:'date'
    },

    postModified: {
        label: 'Post Modified Date',
        operators:['before','after','between'],
        input:'date'
    },

    authenticated: {
        label:'User Logged In',
        operators:['is','is not'],
        multiple:false,
        objects:[
            {value:'true',label:'Yes'},
            {value:'false',label:'No'}
        ]
    },

    user: {
        label:'User',
        operators:['in','not in'],
        multiple:true,
        objects:AIMOGEN_DYNAMIC_USERS
    },

    userRole: {
        label:'User Role',
        operators:['in','not in'],
        multiple:true,
        objects:AIMOGEN_DYNAMIC_ROLES
    },

    userCap: {
        label:'User Capability',
        operators:['in','not in'],
        multiple:true,
        input:'text'
    },

    userLocale:{
        label:'User Locale',
        operators:['in','not in'],
        multiple:true,
        input:'text'
    },

    userRegistered:{
        label:'User Registered Date',
        operators:['before','after','between'],
        input:'date'
    },

    currentDate:{
        label:'Current Date',
        operators:['before','after','between'],
        input:'date'
    },

    timeOfDay:{
        label:'Time of Day',
        operators:['before','after','between'],
        input:'time'
    },

    dayOfWeek:{
        label:'Day of Week',
        operators:['in','not in'],
        multiple:true,
        objects:[
            {value:'Mon',label:'Monday'},
            {value:'Tue',label:'Tuesday'},
            {value:'Wed',label:'Wednesday'},
            {value:'Thu',label:'Thursday'},
            {value:'Fri',label:'Friday'},
            {value:'Sat',label:'Saturday'},
            {value:'Sun',label:'Sunday'}
        ]
    }

};
    let groups = [];

    function renderBuilder() {
        const container = document.getElementById('aimogen-condition-builder');
        container.innerHTML = '';

        groups.forEach((group, gIndex) => {

            const groupEl = document.createElement('div');
            groupEl.className = 'aimogen-group';

            const groupHeader = document.createElement('div');
            groupHeader.style.display = 'flex';
            groupHeader.style.justifyContent = 'space-between';
            groupHeader.style.alignItems = 'center';
            groupHeader.style.marginBottom = '8px';

            const groupLabel = document.createElement('strong');
            groupLabel.textContent = 'Group (AND rules)';
            groupHeader.appendChild(groupLabel);

            const deleteGroupBtn = document.createElement('button');
            deleteGroupBtn.type = 'button';
            deleteGroupBtn.className = 'button';
            deleteGroupBtn.textContent = 'Delete Group';
            deleteGroupBtn.onclick = () => {
                groups.splice(gIndex, 1);
                renderBuilder();
            };
            groupHeader.appendChild(deleteGroupBtn);

            groupEl.appendChild(groupHeader);

            (group.rules || []).forEach((rule, rIndex) => {
                groupEl.appendChild(renderRule(gIndex, rIndex, rule));
            });

            const addRuleBtn = document.createElement('button');
            addRuleBtn.type = 'button';
            addRuleBtn.className = 'button';
            addRuleBtn.textContent = 'AND';
            addRuleBtn.onclick = () => {
                group.rules.push({});
                renderBuilder();
            };

            groupEl.appendChild(addRuleBtn);
            container.appendChild(groupEl);

            if (gIndex < groups.length - 1) {
                const orLabel = document.createElement('div');
                orLabel.textContent = 'OR';
                orLabel.style.margin = '10px 0';
                container.appendChild(orLabel);
            }
        });

        updateJSON();
    }

    function renderRule(gIndex, rIndex, rule) {

        const wrap = document.createElement('div');
        wrap.className = 'aimogen-rule';

        const subjectSelect = document.createElement('select');
        subjectSelect.innerHTML =
            `<option value="">Select...</option>` +
            Object.keys(AIMOGEN_CONDITION_SCHEMA)
                .map(k => `<option value="${k}">${AIMOGEN_CONDITION_SCHEMA[k].label}</option>`)
                .join('');

        subjectSelect.value = rule.subject || '';

        subjectSelect.onchange = function () {

            const subj = this.value;

            if (!subj) {
                groups[gIndex].rules[rIndex] = {};
                renderBuilder();
                return;
            }

            const schema = AIMOGEN_CONDITION_SCHEMA[subj];
            const ops = Array.isArray(schema.operators) ? schema.operators : ['is'];

            groups[gIndex].rules[rIndex] = {
                subject: subj,
                operator: ops[0],
                object: []
            };

            renderBuilder();
        };

        wrap.appendChild(subjectSelect);

        if (rule.subject && AIMOGEN_CONDITION_SCHEMA[rule.subject]) {

            const schema = AIMOGEN_CONDITION_SCHEMA[rule.subject];
            const ops = Array.isArray(schema.operators) ? schema.operators : ['is'];

            const operatorSelect = document.createElement('select');
            operatorSelect.innerHTML = ops
                .map(op => `<option value="${op}">${op}</option>`)
                .join('');

            operatorSelect.value = rule.operator || ops[0];

            operatorSelect.onchange = function () {
                groups[gIndex].rules[rIndex].operator = this.value;
                renderBuilder(); 
            };

            wrap.appendChild(operatorSelect);

            const current = Array.isArray(rule.object) ? rule.object : [];

            const setObjects = (vals) => {
                groups[gIndex].rules[rIndex].object =
                    vals.filter(v => v !== undefined && v !== null && v !== '');
                updateJSON();
            };

            if (schema.objects) {

                const objectSelect = document.createElement('select');

                if (schema.multiple) {
                    objectSelect.multiple = true;
                    objectSelect.size = Math.min(8, Math.max(3, schema.objects.length));
                }

                objectSelect.innerHTML = schema.objects
                    .map(o => `<option value="${o.value}">${o.label}</option>`)
                    .join('');

                Array.from(objectSelect.options).forEach(opt => {
                    opt.selected = current.map(String).includes(String(opt.value));
                });

                objectSelect.onchange = function () {
                    setObjects(
                        Array.from(this.selectedOptions).map(o => o.value)
                    );
                };

                wrap.appendChild(objectSelect);
            }

            else if (schema.input) {

                const inputType =
                    schema.input === 'number' ? 'number' :
                    schema.input === 'date' ? 'date' :
                    schema.input === 'time' ? 'time' : 'text';

                if (rule.operator === 'between' && (inputType === 'date' || inputType === 'time')) {

                    const inputA = document.createElement('input');
                    inputA.type = inputType;
                    inputA.value = current[0] || '';

                    const inputB = document.createElement('input');
                    inputB.type = inputType;
                    inputB.value = current[1] || '';

                    inputA.onchange = () => setObjects([inputA.value, inputB.value]);
                    inputB.onchange = () => setObjects([inputA.value, inputB.value]);

                    wrap.appendChild(inputA);
                    wrap.appendChild(inputB);
                }

                else {

                    const input = document.createElement('input');
                    input.type = inputType;
                    input.value = schema.multiple
                        ? (current || []).join(', ')
                        : (current[0] || '');

                    input.onchange = function () {

                        if (schema.multiple) {
                            const parts = String(this.value || '')
                                .split(',')
                                .map(s => s.trim())
                                .filter(Boolean);

                            setObjects(parts);
                        } else {
                            setObjects([this.value]);
                        }
                    };

                    wrap.appendChild(input);
                }
            }
        }

        const deleteRuleBtn = document.createElement('button');
        deleteRuleBtn.type = 'button';
        deleteRuleBtn.className = 'button';
        deleteRuleBtn.textContent = 'X';
        deleteRuleBtn.style.marginLeft = '6px';

        deleteRuleBtn.onclick = () => {

            groups[gIndex].rules.splice(rIndex, 1);

            if (!groups[gIndex].rules.length) {
                groups.splice(gIndex, 1);
            }

            renderBuilder();
        };

        wrap.appendChild(deleteRuleBtn);

        return wrap;
    }

    function updateJSON() {
        const clean = groups
            .map(g => g.rules.filter(r => r.subject))
            .filter(g => g.length);

        document.getElementById('aimogen-conditions-json').value =
            clean.length ? JSON.stringify(clean) : '';
    }
    document.addEventListener('DOMContentLoaded', function() {    
        document.getElementById('aimogen-add-group').addEventListener('click', () => {
            groups.push({rules:[{}]});
            renderBuilder();
        });
    });
    document.addEventListener('DOMContentLoaded', function() {

        const hidden = document.getElementById('aimogen-conditions-json');
        if (!hidden) return;

        if (hidden.value) {
            try {
                const parsed = JSON.parse(hidden.value);

                groups = parsed.map(group => {
                    if (Array.isArray(group)) {
                        return { rules: group };
                    }
                    if (group.rules) {
                        return group;
                    }
                    return { rules: [] };
                });

            } catch (e) {
                groups = [];
            }
        }

        if (!groups.length) {
            groups = [];
        }

        renderBuilder();
    });
    </script>
    <?php
    }

	public function handle_create() {
		if (!current_user_can('manage_options')) {
			wp_die('Permission denied');
		}

		check_admin_referer(self::NONCE_ACTION, self::NONCE_NAME);

		$title = sanitize_text_field($_POST['title'] ?? '');
		$type  = sanitize_key($_POST['type'] ?? '');
		$prompt = trim($_POST['prompt'] ?? '');
		$activate = isset($_POST['activate']);
        $conditions = wp_unslash($_POST['conditions'] ?? '');
        $conditions = trim($conditions);
        $assistant_id = sanitize_text_field($_POST['assistant_id'] ?? '');
        $ai_model = sanitize_text_field($_POST['ai_model'] ?? '');
        $priority = isset($_POST['priority']) ? intval($_POST['priority']) : 10;
        if ($conditions !== '') {
            json_decode($conditions);
            if (json_last_error() !== JSON_ERROR_NONE) {
                wp_die('Invalid conditions JSON.');
            }
        }
        $mode = sanitize_key($_POST['creation_mode'] ?? 'ai');
        $prompt = trim($_POST['prompt'] ?? '');
        $manual_code = wp_unslash($_POST['code'] ?? '');
		if (!$title) {
            wp_die('Invalid input.');
        }

        if ($mode === 'ai') {

            if ($type === 'auto') {
                $type = $this->detect_snippet_type($prompt, $ai_model, $assistant_id);
            }

            if (!in_array($type, ['php','js','css','html'], true)) {
                wp_die('Invalid snippet type.');
            }
        } else {
            if ($type === 'auto') {
                $type = $this->detect_snippet_type($manual_code, $ai_model, $assistant_id);
            }
            if (!in_array($type, ['php','js','css','html'], true)) {
                wp_die('Invalid snippet type.');
            }
        }

        if ($mode === 'ai' && !$prompt) {
            wp_die('Prompt required.');
        }

        if ($mode === 'manual' && !$manual_code) {
            wp_die('Code required.');
        }
        if ($mode === 'ai') {
		    $code = $this->generate_ai_code($prompt, $type, $ai_model, $assistant_id);
        } else {
            $assistant_id = null;
            $ai_model = null;
            $code = $manual_code;
        }
        if (!$code) 
            wp_die('Empty output.');
		$code = $this->normalize_code($code, $type);

		$check = $this->validate_code($code, $type);
		if (!$check['ok']) {
			wp_die('Snippet rejected: ' . esc_html($check['reason']));
		}

		if ($type === 'php' && $activate) {
			$strict = $this->strict_php_check($code);
			if (!$strict['ok']) {
				$activate = false;
			}
		}

		global $wpdb;
		$wpdb->insert(
			$wpdb->prefix . self::TABLE,
			[
				'title' => $title,
				'type' => $type,
				'code' => $code,
                'ai_model' => $ai_model ?: null,
                'assistant_id' => $assistant_id ?: null,
                'conditions' => $conditions ?: null,
				'active' => $activate ? 1 : 0,
                'priority' => $priority,
                'has_error' => 0,
                'last_error' => null,
				'created_at' => current_time('mysql')
			],
			['%s','%s','%s','%s','%s','%s','%d','%d','%d','%s','%s']
		);
        $this->flush_snippet_cache();
		$url = add_query_arg(
            [
                'page'    => 'aiomatic_snippets_panel',
                'created' => 1,
            ],
            admin_url('admin.php')
        );

        wp_safe_redirect($url . '#tab-2');
		exit;
	}
    private function get_request_fingerprint() {

        static $fp = null;
        if ($fp !== null) {
            return $fp;
        }

        $parts = [
            is_admin() ? 'admin' : 'frontend',
            get_queried_object_id(),
            is_user_logged_in() ? get_current_user_id() : 0,
            wp_date('Y-m-d'),
            wp_date('H'),
        ];

        return $fp = implode('|', $parts);
    }

    private function evaluate_condition($json) {
        $fingerprint = $this->get_request_fingerprint();
        $key = md5($json . '|' . $fingerprint);

        if (isset($this->condition_runtime_cache[$key])) {
            return $this->condition_runtime_cache[$key];
        }

        $groups = json_decode($json, false);

        if (empty($groups) || !is_array($groups)) {
            return $this->condition_runtime_cache[$key] = false;
        }

        foreach ($groups as $group) {
            $group_valid = true;

            foreach ($group as $rule) {
                $rule_array = is_object($rule)
                    ? get_object_vars($rule)
                    : (array)$rule;

                if (!$this->evaluate_rule($rule_array)) {
                    $group_valid = false;
                    break;
                }
            }

            if ($group_valid) {
                return $this->condition_runtime_cache[$key] = true;
            }
        }

        return $this->condition_runtime_cache[$key] = false;
    }
    private function evaluate_rule($rule) {

        $subject  = $rule['subject']  ?? null;
        $operator = $rule['operator'] ?? null;
        $objects  = $rule['object']   ?? [];

        if (!is_array($objects)) {
            $objects = [$objects];
        }

        $result = $this->evaluate_clause($subject, $operator, $objects);

        if (is_wp_error($result)) {
            return false;
        }

        if (in_array($operator, ['not', 'not in', 'is not', 'false'], true)) {
            return !$result;
        }

        return (bool)$result;
    }
    private function evaluate_clause(?string $subject, ?string $operator, array $objects) {

        switch ($subject) {

            case 'siteArea':
                $object = $objects[0] ?? null;
                return 'global' === $object ||
                    ('admin' === $object && is_admin()) ||
                    ('frontend' === $object && !is_admin());

            case 'currentQuery':
                foreach ($objects as $obj) {
                    switch ($obj) {
                        case 'home': if (is_home()) return true; break;
                        case 'frontpage': if (is_front_page()) return true; break;
                        case 'search': if (is_search()) return true; break;
                        case 'archive': if (is_archive()) return true; break;
                        case '404': if (is_404()) return true; break;
                        case 'single': if (is_single()) return true; break;
                        case 'page': if (is_page()) return true; break;
                        case 'postTypeArchive': if (is_post_type_archive()) return true; break;
                    }
                }
                return false;

            case 'visitorLanguage':
                $raw = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '';
                if (!$raw) return false;

                $primary = strtolower(trim(explode(',', $raw)[0]));
                $short = explode('-', $primary)[0];

                $objects = array_map('strtolower', $objects);

                return in_array($primary, $objects, true)
                    || in_array($short, $objects, true);

            case 'currentTheme':
                return in_array(get_stylesheet(), $objects, true)
                    || in_array(get_template(), $objects, true);

            case 'activePlugin':
                if (!isset($this->request_data['active_plugins'])) {
                    $this->request_data['active_plugins'] = (array)get_option('active_plugins', []);
                }
                $active = $this->request_data['active_plugins'];
                $sitewide = is_multisite()
                    ? (array)get_site_option('active_sitewide_plugins', [])
                    : [];
                return !empty(array_intersect($active, $objects))
                    || !empty(array_intersect(array_keys($sitewide), $objects));

            case 'debugEnabled':
                return defined('WP_DEBUG') && WP_DEBUG;

            case 'post':
                return is_single($objects);

            case 'page':
                return is_page($objects);

            case 'postType':
                if (!isset($this->request_data['post'])) {
                    $this->request_data['post'] = get_post();
                }
                $post = $this->request_data['post'];
                return $post && in_array($post->post_type, $objects, true);

            case 'tag':
                return has_term($objects, 'post_tag');
            case 'category':
                return has_term($objects, 'category');

            case 'author':
                if (!isset($this->request_data['post'])) {
                    $this->request_data['post'] = get_post();
                }
                $post = $this->request_data['post'];
                return $post && in_array((int)$post->post_author, $objects, true);

            case 'postStatus':
                if (!isset($this->request_data['post'])) {
                    $this->request_data['post'] = get_post();
                }
                $post = $this->request_data['post'];
                return $post && in_array($post->post_status, $objects, true);

            case 'postParent':
                if (!isset($this->request_data['post'])) {
                    $this->request_data['post'] = get_post();
                }
                $post = $this->request_data['post'];
                return $post && in_array($post->post_parent, $objects, true);

            case 'postPublished':
                $dt = get_post_datetime();
                return $dt && $this->is_within_date_range($dt, $operator, $objects);

            case 'postModified':
                $dt = get_post_datetime(null, 'modified');
                return $dt && $this->is_within_date_range($dt, $operator, $objects);

            case 'authenticated':
                $expected = filter_var($objects[0] ?? true, FILTER_VALIDATE_BOOLEAN);
                return $expected ? is_user_logged_in() : !is_user_logged_in();

            case 'user':
                if (!isset($this->request_data['user'])) {
                    $this->request_data['user'] = wp_get_current_user();
                }
                $user = $this->request_data['user'];
                return $user && in_array($user->ID, $objects, true);

            case 'userRole':
                if (!isset($this->request_data['user'])) {
                    $this->request_data['user'] = wp_get_current_user();
                }
                $user = $this->request_data['user'];
                return $user && !empty(array_intersect($user->roles, $objects));

            case 'userCap':
                foreach ($objects as $cap) {
                    if (current_user_can($cap)) {
                        return true;
                    }
                }
                return false;

            case 'userLocale':
                return in_array(get_user_locale(), $objects, true);

            case 'userRegistered':
                if (!isset($this->request_data['user'])) {
                    $this->request_data['user'] = wp_get_current_user();
                }
                $user = $this->request_data['user'];
                $dt = $user ? $this->safe_parse_datetime($user->user_registered) : null;
                return $dt && $this->is_within_date_range($dt, $operator, $objects);

            case 'timeOfDay':
            case 'currentDate':
                return $this->is_within_date_range(
                    new \DateTimeImmutable( 'now', wp_timezone() ),
                    $operator,
                    $objects
                );

            case 'dayOfWeek':
                return in_array(
                    wp_date('D'),
                    $objects,
                    true
                );


            default:
                return new \WP_Error("Invalid condition subject: $subject");
        }
    }

	public function handle_toggle() {
		check_admin_referer(self::NONCE_ACTION, self::NONCE_NAME);

		global $wpdb;
		$id = intval($_POST['id']);
		$state = intval($_POST['state']);

		$wpdb->update(
			$wpdb->prefix . self::TABLE,
			[
                'active' => $state,
                'has_error' => 0,
                'last_error' => null
            ],
			['id' => $id],
			['%d','%d','%s'],
			['%d']
		);
        $this->flush_snippet_cache();        
		wp_safe_redirect(admin_url('admin.php?page=aiomatic_snippets_panel'));
		exit;
	}
    private function safe_parse_datetime($datetime) {
        try {
            return $datetime ? new \DateTimeImmutable($datetime) : null;
        } catch (\Exception $e) {
            return null;
        }
    }

    private function is_within_date_range(
        $date,
        $operator,
        $objects
    ) {

        switch ($operator) {

            case 'before':
                $end = isset($objects[0]) ? $this->safe_parse_datetime($objects[0]) : null;
                return $end && $date < $end;

            case 'after':
                $start = isset($objects[0]) ? $this->safe_parse_datetime($objects[0]) : null;
                return $start && $date > $start;

            case 'between':
                $start = isset($objects[0]) ? $this->safe_parse_datetime($objects[0]) : null;
                $end   = isset($objects[1]) ? $this->safe_parse_datetime($objects[1]) : null;
                return $start && $end && $start <= $date && $date <= $end;
        }

        return false;
    }

	public function execute_php_snippets() {
		if (is_admin()) return;

        if (defined('AIMOGEN_DISABLE_SNIPPETS') && AIMOGEN_DISABLE_SNIPPETS) {
            return;
        }

        $snippets = $this->get_active_snippets();

        foreach ($snippets as $snippet) {

            if ($snippet->type !== 'php') continue;

            $conditions = $snippet->conditions;
            if (empty($conditions)) {
                if (is_admin()) {
                    continue;
                }
            } else {
                if (!$this->evaluate_condition($conditions)) {
                    continue;
                }
            }

            try {
                $this->set_running_snippet_id((int)$snippet->id);
                $this->sandbox_eval($snippet->code);
            } catch (\Throwable $e) {
                $this->mark_snippet_error((int)$snippet->id, $e->getMessage());
                aiomatic_log_to_file(
                    'Aimogen snippet #' . $snippet->id . ' error: ' . $e->getMessage()
                );
            }
        }
	}
    private function flush_snippet_cache() {
        wp_cache_delete('aimogen_active_snippets_v1_' . get_current_blog_id(), 'aimogen');
    }            
	public function enqueue_assets() {
        if (defined('AIMOGEN_DISABLE_SNIPPETS') && AIMOGEN_DISABLE_SNIPPETS) {
            return;
        }
        $snippets = $this->get_active_snippets();

        $css = [];
        $js  = [];
        $html = [];

        foreach ($snippets as $snippet) {

            $conditions = $snippet->conditions;
            if (empty($conditions)) {
                if (is_admin()) {
                    continue;
                }
            } else {
                if (!$this->evaluate_condition($conditions)) {
                    continue;
                }
            }

            switch ($snippet->type) {
                case 'css':  $css[] = $snippet->code; break;
                case 'js':   $js[]  = $snippet->code; break;
                case 'html': $html[] = $snippet->code; break;
            }
        }
        
		if ($css) {
			wp_register_style('aimogen-inline', false);
			wp_enqueue_style('aimogen-inline');
			wp_add_inline_style('aimogen-inline', implode("\n", $css));
		}
		if ($js) {
			wp_register_script('aimogen-inline', '', [], false, true);
			wp_enqueue_script('aimogen-inline');
			wp_add_inline_script('aimogen-inline', implode("\n", $js));
		}
        if ($html) {
            add_action('wp_footer', function() use ($html) {
                if ( current_user_can( 'unfiltered_html' ) ) {
                    echo implode("\n", $html);
                } else {
                    $allowed = wp_kses_allowed_html( 'post' );
                    $allowed['*']['style'] = true;
                    $allowed['script'] = array(
                        'type' => true,
                        'src'  => true,
                    );
                    $allowed['style'] = array(
                        'type' => true,
                    );
                    $za_sanitized = implode("\n", $html);
                    $za_sanitized = wp_kses( $za_sanitized, $allowed );
                    echo $za_sanitized;
                }
            });
        }
	}

	private function sandbox_eval($code) {
        $runner = static function () use ($code) {

            $initialLevel = ob_get_level();
            ob_start();
            if ( ! function_exists('wp_tempnam') ) {
                require_once ABSPATH . 'wp-admin/includes/file.php';
            }
            $tmp = wp_tempnam('aimogen_snippet_');
            global $wp_filesystem;
            if ( ! is_a( $wp_filesystem, 'WP_Filesystem_Base') ){
                include_once(ABSPATH . 'wp-admin/includes/file.php');$creds = request_filesystem_credentials( site_url() );
                wp_filesystem($creds);
            }
            $wp_filesystem->put_contents($tmp, "<?php\n" . $code);
            try {
                include $tmp;
            } finally {
                @unlink($tmp);
                while (ob_get_level() > $initialLevel) {
                    ob_end_clean();
                }
            }
        };

        $runner();
    }
	private function normalize_code($code, $type) {
		$code = trim($code);
		$code = preg_replace('/^\s*```[a-z]*\s*/i', '', $code);
		$code = preg_replace('/```$/', '', $code);

		if ($type === 'php') {
			$code = preg_replace('/^\s*<\?(php)?/i', '', $code);
			$code = preg_replace('/\?>$/', '', $code);
		}
		return trim($code);
	}

	private function validate_code($code, $type) {
        if (!$code) {
            return ['ok'=>false,'reason'=>'Empty output'];
        }

        if ($type === 'php') {
            return $this->validate_php_tokens($code);
        }

        return ['ok'=>true];
    }
    private function next_non_whitespace_token(array $tokens, int $i) {
        for ($j = $i + 1, $n = count($tokens); $j < $n; $j++) {
            $t = $tokens[$j];
            if (is_array($t)) {
                if ($t[0] === T_WHITESPACE || $t[0] === T_COMMENT || $t[0] === T_DOC_COMMENT) continue;
                return $t[1];
            }
            return $t;
        }
        return null;
    }
    private function prev_non_whitespace_token(array $tokens, int $i) {
        for ($j = $i - 1; $j >= 0; $j--) {
            $t = $tokens[$j];
            if (is_array($t)) {
                if ($t[0] === T_WHITESPACE || $t[0] === T_COMMENT || $t[0] === T_DOC_COMMENT) continue;
                return $t[1];
            }
            return $t;
        }
        return null;
    }
    private function validate_php_tokens($code) {

        if (preg_match('/\$\w+\s*\(/', $code)) {
            return ['ok'=>false,'reason'=>'Variable function calls are not allowed'];
        }

        $tokens = token_get_all("<?php\n" . $code);

        $blocked = array_fill_keys([
            'eval','exec','shell_exec','passthru','proc_open','popen','system','assert',
            'base64_decode','gzinflate','gzuncompress',
            'file_put_contents','fopen','fwrite','unlink','rename','copy','chmod','chown',
            'curl_exec','curl_multi_exec',
            'wp_remote_get','wp_remote_post','wp_remote_request',
            'update_option','add_option','delete_option',
            'wp_insert_user','wp_create_user','add_role','remove_role'
        ], true);

        for ($i = 0, $n = count($tokens); $i < $n; $i++) {

            $t = $tokens[$i];

            if (is_array($t) && $t[0] === T_VARIABLE && strtolower($t[1]) === '$wpdb') {
                return ['ok'=>false,'reason'=>'Direct database access is not allowed'];
            }
            if (is_array($t) && in_array($t[0], [T_REQUIRE, T_REQUIRE_ONCE, T_INCLUDE, T_INCLUDE_ONCE], true)) {
                return ['ok'=>false,'reason'=>'Including external files is not allowed'];
            }
            if (!is_array($t) || $t[0] !== T_STRING) {
                continue;
            }

            $name = strtolower($t[1]);

            $prev = $this->prev_non_whitespace_token($tokens, $i);
            if ($prev === '->' || $prev === '::') {
                continue;
            }

            $next = $this->next_non_whitespace_token($tokens, $i);
            if ($next !== '(') {
                continue;
            }

            if (isset($blocked[$name])) {
                return ['ok'=>false,'reason'=>'Unsafe call detected: ' . $name];
            }
        }

        return ['ok'=>true];
    }
            
	private function strict_php_check($code) {
		if (preg_match('/\bfile_put_contents\s*\(/i', $code)) {
			return ['ok'=>false,'reason'=>'File writes not allowed'];
		}
		return ['ok'=>true];
	}

	private function generate_ai_code($prompt, $type, $ai_model = null, $assistant_id_override = null) {

        $aiomatic_Main_Settings = get_option('aiomatic_Main_Settings', false);

        if (empty($aiomatic_Main_Settings['app_id'])) {
            return '';
        }

        $appids = preg_split('/\r\n|\r|\n/', trim($aiomatic_Main_Settings['app_id']));
        $appids = array_filter($appids);
        if(empty($appids))
        {
            return '';
        }
        $token = $appids[array_rand($appids)];
        $token = apply_filters('aimogen_openai_api_key', $token);
        $token = apply_filters('aiomatic_openai_api_key', $token);
        $model = $ai_model ?: (defined('AIMOGEN_DEFAULT_MODEL') ? AIMOGEN_DEFAULT_MODEL : 'gpt-4o-mini');
        $assistant_id = $assistant_id_override !== null ? $assistant_id_override : '';
        $temperature = 0.2;
        $thread_id = '';
        $max_p = 1;
        $presence_penalty = 0;
        $frequency_penalty = 0;

        $max_tokens = aimogenpro_get_max_tokens($model);

        $type_instruction = '';

        switch ($type) {
            case 'php':
                $type_instruction = "Generate ONLY raw PHP code. Do NOT include <?php tags. Do NOT include explanations. Do NOT wrap in markdown. Return valid WordPress-compatible PHP.";
                break;

            case 'js':
                $type_instruction = "Generate ONLY raw JavaScript code. No explanations. No markdown fences. No HTML. Pure JS.";
                break;

            case 'css':
                $type_instruction = "Generate ONLY raw CSS. No explanations. No markdown fences. Pure CSS rules.";
                break;

            case 'html':
                $type_instruction = "Generate ONLY raw HTML markup. No explanations. No markdown fences.";
                break;
        }

        $prompt_now = $type_instruction . "\n\nUser request:\n" . trim($prompt);

        $query_token_count = count(aiomatic_encode($prompt_now));
        $available_tokens = aiomatic_compute_available_tokens(
            $model,
            $max_tokens,
            $prompt_now,
            $query_token_count
        );

        if ($available_tokens <= AIMOGEN_MINIMUM_TOKENS_FOR_COMPLETIONS) {

            $string_len = aiomatic_strlen($prompt_now);
            $string_len = intval($string_len / 2);
            $prompt_now = aiomatic_substr($prompt_now, 0, $string_len);
            $prompt_now = trim($prompt_now);

            $query_token_count = count(aiomatic_encode($prompt_now));
            $available_tokens = $max_tokens - $query_token_count;
        }

        $aierror = '';
        $finish_reason = '';

        if (isset($aiomatic_Main_Settings['enable_detailed_logging'])) {
            $api_service = aiomatic_get_api_service($token, $model);
            aiomatic_log_to_file('Calling ' . $api_service . ' (' . $assistant_id . '/' . $model . ') for Snippet Generator');
            aiomatic_log_to_file('Prompt: ' . $prompt_now);
        }

        $generated_text = aiomatic_generate_text(
            $token,
            $model,
            $prompt_now,
            $available_tokens,
            $temperature,
            $max_p,
            $presence_penalty,
            $frequency_penalty,
            false,
            'snippetGenerator',
            0,
            $finish_reason,
            $aierror,
            false,
            false,
            false,
            '',
            '',
            'user',
            $assistant_id,
            $thread_id,
            '',
            'disabled',
            '',
            false,
            false,
            array(),
            '', 
            '', 
            ''
        );

        if ($generated_text === false) {

            if (!empty($aierror)) {
                aiomatic_log_to_file('Aimogen Snippet AI Error: ' . $aierror);
            }

            return '';
        }

        $generated_text = trim($generated_text);

        $generated_text = preg_replace('/^\s*```[a-z]*\s*/i', '', $generated_text);
        $generated_text = preg_replace('/```$/', '', $generated_text);

        if ($type === 'php') {
            $generated_text = preg_replace('/^\s*<\?(php)?/i', '', $generated_text);
            $generated_text = preg_replace('/\?>$/', '', $generated_text);
        }

        return trim($generated_text);
    }

}

Aimogen_Snippets_Engine::instance();

?>