<?php

namespace GriffinForms\Admin\App\Html\Widgets\TitleBar;

final class CommandPalette extends \GriffinForms\Admin\App\Html\Widgets\TitleBar\Format
{
    public function getHtml()
    {
        $form_id   = $this->utility->getFormId();
        $form      = $this->utility->getForm();
        $form_name = ($form && $form_id) ? (string) $form->getProp('name') : '';

        if (!$form_id || !$form_name) {
            return;
        }

        $shortcut = PHP_OS_FAMILY === 'Darwin' ? '⌘⇧K' : 'Ctrl+Shift+O';

        echo '<div id="gf-command-palette" data-form-id="' . esc_attr((string) $form_id) . '">';

        // Resting pill
        echo '<button id="gf-palette-trigger" type="button" aria-label="' . esc_attr__('Search or switch form', 'griffinforms-form-builder') . '">';
        echo '<span id="gf-palette-form-name">' . esc_html($form_name) . '</span>';
        echo '<kbd class="gf-palette-shortcut">' . esc_html($shortcut) . '</kbd>';
        echo '</button>';

        // Active card: input + dropdown joined in one wrapper
        echo '<div id="gf-palette-card" style="display:none;">';
        echo '<div id="gf-palette-input-wrap">';
        echo '<input id="gf-palette-input" type="search" autocomplete="off" placeholder="' . esc_attr__('Search...', 'griffinforms-form-builder') . '" />';
        echo '</div>';
        echo '<div id="gf-palette-divider"></div>';
        echo '<div id="gf-palette-dropdown" role="listbox" aria-label="' . esc_attr__('Search results', 'griffinforms-form-builder') . '">';
        echo '<ul id="gf-palette-results" role="listbox"></ul>';
        echo '<div id="gf-palette-footer">';
        echo '<span>&#x2191;&#x2193; ' . esc_html__('Navigate', 'griffinforms-form-builder') . '</span>';
        echo '<span>&#x23CE; ' . esc_html__('Select', 'griffinforms-form-builder') . '</span>';
        echo '<span>ESC ' . esc_html__('Close', 'griffinforms-form-builder') . '</span>';
        echo '</div>';
        echo '</div>';
        echo '</div>';

        echo '</div>';
    }

    protected function widgetJs()
    {
        $form_id = (int) $this->utility->getFormId();
        if (!$form_id) {
            return;
        }

        $nonce        = wp_create_nonce('wp_rest');
        $rest_base    = esc_js(rest_url('griffinforms/v1'));
        $quick_url    = esc_js(rest_url('griffinforms/v1/palette/quick'));
        $query_url    = esc_js(rest_url('griffinforms/v1/palette/query'));

        $i18n_frequently_used = esc_js(__('Frequently Used', 'griffinforms-form-builder'));
        $i18n_recent_forms    = esc_js(__('Recent Forms', 'griffinforms-form-builder'));
        $i18n_results         = esc_js(__('Results', 'griffinforms-form-builder'));
        $i18n_no_results      = esc_js(__('No results found.', 'griffinforms-form-builder'));

        echo "
(function() {
    const formId      = " . $form_id . ";
    const restNonce   = '" . esc_js($nonce) . "';
    const quickUrl    = '" . $quick_url . "';
    const queryUrl    = '" . $query_url . "';

    const palette     = document.getElementById('gf-command-palette');
    const trigger     = document.getElementById('gf-palette-trigger');
    const card        = document.getElementById('gf-palette-card');
    const input       = document.getElementById('gf-palette-input');
    const dropdown    = document.getElementById('gf-palette-dropdown');
    const resultsList = document.getElementById('gf-palette-results');

    if (!palette || !trigger || !card || !input) { return; }

    let debounceTimer   = null;
    let currentResults  = [];
    let selectedIndex   = -1;
    let isOpen          = false;

    // ── Frequency store (localStorage) ───────────────────────────
    const FREQ_KEY      = 'gf_palette_freq_v2';
    const FREQ_DATA_KEY = 'gf_palette_freq_data_v2';
    const FREQ_MAX      = 50;
    const FREQ_SURFACE  = 5;

    function freqLoad() {
        try { return JSON.parse(localStorage.getItem(FREQ_KEY) || '{}'); } catch(e) { return {}; }
    }

    function freqDataLoad() {
        try { return JSON.parse(localStorage.getItem(FREQ_DATA_KEY) || '{}'); } catch(e) { return {}; }
    }

    function freqRecord(item) {
        try {
            var store = freqLoad();
            var data  = freqDataLoad();
            var key   = item.result_id;
            store[key] = (store[key] || 0) + 1;
            data[key]  = { result_id: item.result_id, label: item.label, description: item.description, icon: item.icon, action_type: item.action_type, action_payload: item.action_payload };
            // Prune to FREQ_MAX by evicting lowest-count entries
            var keys = Object.keys(store);
            if (keys.length > FREQ_MAX) {
                keys.sort(function(a, b) { return store[a] - store[b]; });
                keys.slice(0, keys.length - FREQ_MAX).forEach(function(k) { delete store[k]; delete data[k]; });
            }
            localStorage.setItem(FREQ_KEY, JSON.stringify(store));
            localStorage.setItem(FREQ_DATA_KEY, JSON.stringify(data));
        } catch(e) {}
    }

    function freqSort(items) {
        var store    = freqLoad();
        var data     = freqDataLoad();
        var seen     = {};
        var frequent = [];

        // Items already in the quick-items pool — preserve live data
        items.forEach(function(it) {
            if ((store[it.result_id] || 0) > 0) {
                seen[it.result_id] = true;
                frequent.push({ item: it, count: store[it.result_id] });
            }
        });

        // Items only in the stored data (e.g. theme actions, search results)
        Object.keys(store).forEach(function(id) {
            if (!seen[id] && data[id]) {
                frequent.push({ item: data[id], count: store[id] });
            }
        });

        return frequent
            .sort(function(a, b) { return b.count - a.count; })
            .slice(0, FREQ_SURFACE)
            .map(function(e) { return e.item; });
    }

    // ── Open / Close ──────────────────────────────────────────────

    function gfPaletteOpen() {
        if (isOpen) { return; }
        isOpen = true;
        trigger.style.display = 'none';
        card.style.display    = '';
        palette.classList.add('is-open');
        input.value = '';
        input.focus();
        gfPaletteLoadQuickItems();
    }

    function gfPaletteClose() {
        if (!isOpen) { return; }
        isOpen = false;
        palette.classList.remove('is-open');
        card.style.display    = 'none';
        trigger.style.display = '';
        clearResults();
        selectedIndex = -1;
    }

    // ── Results rendering ─────────────────────────────────────────

    const iconSvgs = {
        form:            '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/><path d=\'M14 2v6h6M16 13H8M16 17H8M10 9H8\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/></svg>',
        theme:           '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><circle cx=\'12\' cy=\'12\' r=\'10\' stroke=\'currentColor\' stroke-width=\'1.5\'/><circle cx=\'8\' cy=\'14\' r=\'2\' fill=\'currentColor\'/><circle cx=\'12\' cy=\'9\' r=\'2\' fill=\'currentColor\'/><circle cx=\'16\' cy=\'14\' r=\'2\' fill=\'currentColor\'/></svg>',
        nav_forms:       '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><rect x=\'3\' y=\'3\' width=\'7\' height=\'7\' rx=\'1\' stroke=\'currentColor\' stroke-width=\'1.5\'/><rect x=\'14\' y=\'3\' width=\'7\' height=\'7\' rx=\'1\' stroke=\'currentColor\' stroke-width=\'1.5\'/><rect x=\'3\' y=\'14\' width=\'7\' height=\'7\' rx=\'1\' stroke=\'currentColor\' stroke-width=\'1.5\'/><rect x=\'14\' y=\'14\' width=\'7\' height=\'7\' rx=\'1\' stroke=\'currentColor\' stroke-width=\'1.5\'/></svg>',
        nav_submissions: '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/></svg>',
        nav_unread:      '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/><circle cx=\'18\' cy=\'5\' r=\'3\' fill=\'currentColor\'/></svg>',
        nav_files:       '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/></svg>',
        nav_messages:    '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/><polyline points=\'22,6 12,13 2,6\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/></svg>',
        nav_themes:      '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><circle cx=\'12\' cy=\'12\' r=\'10\' stroke=\'currentColor\' stroke-width=\'1.5\'/><circle cx=\'8\' cy=\'14\' r=\'2\' fill=\'currentColor\'/><circle cx=\'12\' cy=\'9\' r=\'2\' fill=\'currentColor\'/><circle cx=\'16\' cy=\'14\' r=\'2\' fill=\'currentColor\'/></svg>',
        nav_logs:        '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/><path d=\'M14 2v6h6M8 13h8M8 17h5\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/></svg>',
        folder:          '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linejoin=\'round\'/></svg>',
        option:          '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><line x1=\'4\' y1=\'6\' x2=\'20\' y2=\'6\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\'/><line x1=\'4\' y1=\'12\' x2=\'20\' y2=\'12\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\'/><line x1=\'4\' y1=\'18\' x2=\'20\' y2=\'18\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\'/><circle cx=\'9\' cy=\'6\' r=\'2\' fill=\'white\' stroke=\'currentColor\' stroke-width=\'1.5\'/><circle cx=\'15\' cy=\'12\' r=\'2\' fill=\'white\' stroke=\'currentColor\' stroke-width=\'1.5\'/><circle cx=\'9\' cy=\'18\' r=\'2\' fill=\'white\' stroke=\'currentColor\' stroke-width=\'1.5\'/></svg>',
        notification:    '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/><path d=\'M13.73 21a2 2 0 0 1-3.46 0\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/></svg>',
        accounts:        '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'M16 21v-2a4 4 0 0 0-4-4H7a4 4 0 0 0-4 4v2\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/><circle cx=\'9.5\' cy=\'7\' r=\'4\' stroke=\'currentColor\' stroke-width=\'1.5\'/><path d=\'M19 8v6M16 11h6\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/></svg>',
        setting:         '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><circle cx=\'12\' cy=\'12\' r=\'3\' stroke=\'currentColor\' stroke-width=\'1.5\'/><path d=\'M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z\' stroke=\'currentColor\' stroke-width=\'1.5\'/></svg>',
        keyword:             '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><circle cx=\'11\' cy=\'11\' r=\'8\' stroke=\'currentColor\' stroke-width=\'1.5\'/><path d=\'m21 21-4.35-4.35\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\'/></svg>',
        conditional_logic:   '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'M3 12h4m0 0c0-3.5 2-6 6-6h8M7 12c0 3.5 2 6 6 6h8\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/><path d=\'m17 4 4 2-4 2M17 16l4 2-4 2\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/></svg>',
        theme_tab:       '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><rect x=\'3\' y=\'3\' width=\'7\' height=\'7\' rx=\'1\' stroke=\'currentColor\' stroke-width=\'1.5\'/><rect x=\'14\' y=\'3\' width=\'7\' height=\'7\' rx=\'1\' stroke=\'currentColor\' stroke-width=\'1.5\'/><rect x=\'3\' y=\'14\' width=\'7\' height=\'7\' rx=\'1\' stroke=\'currentColor\' stroke-width=\'1.5\'/><rect x=\'14\' y=\'14\' width=\'7\' height=\'7\' rx=\'1\' stroke=\'currentColor\' stroke-width=\'1.5\'/></svg>',
        theme_action:    '<svg class=\'gf-palette-result-icon\' viewBox=\'0 0 24 24\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><path d=\'M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/><path d=\'M3 3v5h5\' stroke=\'currentColor\' stroke-width=\'1.5\' stroke-linecap=\'round\' stroke-linejoin=\'round\'/></svg>',
    };

    function clearResults() {
        resultsList.innerHTML = '';
        currentResults = [];
        selectedIndex  = -1;
    }

    function appendSectionLabel(text) {
        var lbl = document.createElement('li');
        lbl.className   = 'gf-palette-section-label';
        lbl.textContent = text;
        resultsList.appendChild(lbl);
    }

    function renderResults(items, sectionTitle, frequentItems) {
        clearResults();

        var allItems = [];

        if (frequentItems && frequentItems.length > 0) {
            appendSectionLabel('" . $i18n_frequently_used . "');
            frequentItems.forEach(function(it) { allItems.push(it); });
            renderItemRows(frequentItems, 0);
        }

        if (items.length > 0) {
            appendSectionLabel(sectionTitle || '');
            var offset = allItems.length;
            items.forEach(function(it) { allItems.push(it); });
            renderItemRows(items, offset);
        }

        currentResults = allItems;

        if (allItems.length === 0) {
            const li = document.createElement('li');
            li.className = 'gf-palette-empty';
            li.textContent = '" . $i18n_no_results . "';
            resultsList.appendChild(li);
            return;
        }

    }

    function renderItemRows(items, indexOffset) {
        items.forEach(function(item, i) {
            var idx = indexOffset + i;
            var li  = document.createElement('li');
            li.className = 'gf-palette-result-item';
            li.role      = 'option';
            li.setAttribute('aria-selected', 'false');
            li.dataset.index = idx;

            var label = document.createElement('span');
            label.className   = 'gf-palette-result-label';
            label.textContent = item.label;
            li.appendChild(label);

            if (item.description) {
                li.classList.add('has-description');
                var desc = document.createElement('span');
                desc.className   = 'gf-palette-result-description';
                desc.textContent = item.description;
                li.appendChild(desc);
            }

            var iconWrap = document.createElement('span');
            if (item.icon && (item.icon.startsWith('http://') || item.icon.startsWith('https://'))) {
                var img = document.createElement('img');
                img.src       = item.icon;
                img.className = 'gf-palette-result-icon';
                img.alt       = '';
                img.setAttribute('aria-hidden', 'true');
                iconWrap.appendChild(img);
            } else {
                iconWrap.innerHTML = iconSvgs[item.icon] || iconSvgs['form'];
            }
            li.appendChild(iconWrap);

            li.addEventListener('mousedown', function(e) {
                e.preventDefault();
                gfPaletteExecuteAction(item.action_type, item.action_payload, e.shiftKey, item);
            });

            li.addEventListener('mousemove', function() {
                setSelected(idx);
            });

            resultsList.appendChild(li);
        });
    }

    function setSelected(index) {
        const items = resultsList.querySelectorAll('.gf-palette-result-item[role=option]');
        items.forEach(function(el, i) {
            el.setAttribute('aria-selected', i === index ? 'true' : 'false');
        });
        selectedIndex = index;
    }

    // ── Data fetching ─────────────────────────────────────────────

    function gfPaletteLoadQuickItems() {
        fetch(quickUrl + '?form_id=' + formId, {
            headers: { 'X-WP-Nonce': restNonce }
        })
        .then(function(r) { return r.ok ? r.json() : []; })
        .then(function(items) {
            var normalised = Array.isArray(items) ? items : [];
            renderResults(normalised, '" . $i18n_recent_forms . "', freqSort(normalised));
        })
        .catch(function() {});
    }

    function gfPaletteSearch(query) {
        fetch(queryUrl + '?query=' + encodeURIComponent(query) + '&form_id=' + formId, {
            headers: { 'X-WP-Nonce': restNonce }
        })
        .then(function(r) { return r.ok ? r.json() : []; })
        .then(function(items) {
            renderResults(Array.isArray(items) ? items : [], '" . $i18n_results . "');
        })
        .catch(function() {});
    }

    // ── Action executor ───────────────────────────────────────────

    function gfPaletteExecuteAction(actionType, actionPayload, shiftKey, item) {
        if (item) { freqRecord(item); }
        gfPaletteClose();
        switch (actionType) {
            case 'open_modal':
                var el = document.getElementById(actionPayload.modal_id);
                if (el) { bootstrap.Modal.getOrCreateInstance(el).show(); }
                break;
            case 'open_modal_with_context':
                document.dispatchEvent(new CustomEvent('gf-palette-modal-context', {
                    detail: { modal_id: actionPayload.modal_id, context: actionPayload.context }
                }));
                var el2 = document.getElementById(actionPayload.modal_id);
                if (el2) { bootstrap.Modal.getOrCreateInstance(el2).show(); }
                break;
            case 'navigate_url':
                if (shiftKey) {
                    window.open(actionPayload.url, '_blank', 'noopener');
                } else {
                    window.location.href = actionPayload.url;
                }
                break;
            case 'navigate_url_new_tab':
                window.open(actionPayload.url, '_blank', 'noopener');
                break;
            case 'create_blank_form':
                if (window.gfPaletteCreateBlankFormInFlight) {
                    return;
                }
                window.gfPaletteCreateBlankFormInFlight = true;
                jQuery.post(ajaxurl, {
                    action: 'createBlankForm',
                    form_name: actionPayload.form_name || 'New Form',
                    starter_fields: [],
                    nonce: actionPayload.nonce || ''
                })
                .done(function(response) {
                    if (response && response.success && response.data && response.data.form_id) {
                        var redirectBase = actionPayload.redirect_url || '" . esc_js(admin_url('admin.php?page=griffinforms-app&form_id=')) . "';
                        window.location.href = redirectBase + String(response.data.form_id);
                        return;
                    }

                    var message = (response && response.data)
                        ? (typeof response.data === 'string' ? response.data : (response.data.message || 'Failed to create form.'))
                        : 'Failed to create form.';
                    if (typeof statusbarMsg === 'function') {
                        statusbarMsg('danger', message);
                    } else {
                        alert(message);
                    }
                })
                .fail(function() {
                    var message = 'Failed to create form.';
                    if (typeof statusbarMsg === 'function') {
                        statusbarMsg('danger', message);
                    } else {
                        alert(message);
                    }
                })
                .always(function() {
                    window.gfPaletteCreateBlankFormInFlight = false;
                });
                break;
            case 'apply_theme':
                if (typeof griffinformsApplyFormTheme === 'function' && formId) {
                    griffinformsApplyFormTheme(formId, actionPayload.theme_id || 0)
                        .done(function(response) {
                            if (response && response.success) {
                                var msg = (response.data && response.data.message) || 'Theme updated.';
                                if (typeof statusbarMsg === 'function') { statusbarMsg('success', msg); }
                                try { document.dispatchEvent(new Event('form-layout')); } catch(e) {}
                                try { document.dispatchEvent(new CustomEvent('form-theme-applied', { detail: { formId: formId, themeId: actionPayload.theme_id || 0 } })); } catch(e) {}
                            }
                        });
                }
                break;
        }
    }

    // ── Event bindings ────────────────────────────────────────────

    trigger.addEventListener('click', function() { gfPaletteOpen(); });

    input.addEventListener('input', function() {
        clearTimeout(debounceTimer);
        const q = input.value.trim();
        if (q === '') {
            gfPaletteLoadQuickItems();
            return;
        }
        debounceTimer = setTimeout(function() { gfPaletteSearch(q); }, 200);
    });

    input.addEventListener('blur', function() {
        setTimeout(function() {
            if (isOpen && !card.contains(document.activeElement)) {
                gfPaletteClose();
            }
        }, 150);
    });

    document.addEventListener('keydown', function(e) {
        // Open shortcut: ⌘⇧K (Mac) or Ctrl+Shift+O (Windows/Linux)
        // Avoids ⌘K conflict with WP7 global palette; Ctrl+Shift+K is claimed by Firefox console
        if ((e.metaKey && e.shiftKey && e.key.toLowerCase() === 'k') || (e.ctrlKey && e.shiftKey && !e.metaKey && e.key.toLowerCase() === 'o')) {
            e.preventDefault();
            if (isOpen) { gfPaletteClose(); } else { gfPaletteOpen(); }
            return;
        }

        if (!isOpen) { return; }

        const items = resultsList.querySelectorAll('.gf-palette-result-item[role=option]');

        if (e.key === 'Escape') {
            e.preventDefault();
            gfPaletteClose();
            return;
        }

        if (e.key === 'ArrowDown') {
            e.preventDefault();
            const next = items.length === 0 ? -1 : (selectedIndex + 1) % items.length;
            setSelected(next);
            return;
        }

        if (e.key === 'ArrowUp') {
            e.preventDefault();
            const prev = items.length === 0 ? -1 : (selectedIndex - 1 + items.length) % items.length;
            setSelected(prev);
            return;
        }

        if (e.key === 'Enter') {
            e.preventDefault();
            if (selectedIndex >= 0 && currentResults[selectedIndex]) {
                const item = currentResults[selectedIndex];
                gfPaletteExecuteAction(item.action_type, item.action_payload, e.shiftKey, item);
            }
            return;
        }
    });

    document.addEventListener('click', function(e) {
        if (isOpen && palette && !palette.contains(e.target)) {
            gfPaletteClose();
        }
    });

    document.addEventListener('form-updated', function(e) {
        if (!e.detail || e.detail.type !== 'name' || e.detail.itemType !== 'form') { return; }
        var nameEl = document.getElementById('gf-palette-form-name');
        if (nameEl && e.detail.value) { nameEl.textContent = e.detail.value; }
    });
})();
";
    }
}
