<?php

namespace GriffinForms\Admin\Html\Modals;

class CreateForm extends \GriffinForms\Admin\Html\Modals\Format
{   
    protected $sql;
    protected $categories;
    protected $migration_sources = [];

    protected function setSql()
    {
        $this->sql = \GriffinForms\Admin\Sql\Forms::getInstance();
    }

    protected function setCategories()
    {
        $this->categories = $this->sql->getTemplateCategories();
    }

    protected function setMigrationSources()
    {
        $this->migration_sources = \GriffinForms\Includes\Migration\MigrationNotice::getInstance()->getDetectedSources();
    }

    protected function headerText()
    {
        $text = $this->lang->getText('create_form');
        return $text;
    }
    
    protected function modalContent()
    {
        $this->alertError();
        $this->createFormTabs();
    }

    protected function alertError()
    {
        echo '<div id="griffinforms-create-form-modal-error" class="gf-notice gf-notice-danger gf-is-dismissible small" role="alert" style="display: none;">';
        echo '<p></p>';
        echo '<button type="button" class="gf-dismiss-notice">&times;</button>';
        echo '</div>';
    }

    protected function warningAlert($content = '')
    {
        $img_url = $this->getImg('lightbulb', 'icon', 'url');
        echo '<div class="small mb-2 d-flex align-items-center fst-italic" role="alert">';
        echo '<div class="gf-icon-wrapper">';
        echo '<img src="' . esc_url($img_url) . '" alt="" class="gf-icon" style="width: 18px; height: 18px;">';
        echo '</div>';
        echo '<span class="ms-1">' . wp_kses_post($content) . '</span>';
        echo '</div>';
    }

    protected function createFormTabs()
    {
        echo '<nav><div class="nav nav-underline nav-fill border-bottom border-2" id="griffinforms-create-form-modal-tabs" role="tablist">';
        echo '<button class="nav-link active" id="griffinforms-create-form-modal-blank-form-tab" data-bs-toggle="tab" data-bs-target="#griffinforms-create-form-modal-blank-form" type="button" role="tab">' . esc_html(__('Blank Form', 'griffinforms-form-builder')) . '</button>';
        echo '<button class="nav-link" id="griffinforms-create-form-modal-choose-template-tab" data-bs-toggle="tab" data-bs-target="#griffinforms-create-form-modal-choose-template" type="button" role="tab">' . esc_html(__('Form Templates', 'griffinforms-form-builder')) . '</button>';
        echo '<button class="nav-link" id="griffinforms-create-form-modal-import-form-tab" data-bs-toggle="tab" data-bs-target="#griffinforms-create-form-modal-import-form" type="button" role="tab">' . esc_html(__('Import Form', 'griffinforms-form-builder')) . '</button>';
        if (!empty($this->migration_sources)) {
            echo '<button class="nav-link" id="griffinforms-create-form-modal-migrate-tab" data-bs-toggle="tab" data-bs-target="#griffinforms-create-form-modal-migrate" type="button" role="tab">' . esc_html(__('Import from Plugin', 'griffinforms-form-builder')) . '</button>';
        }
        echo '<button class="nav-link" id="griffinforms-create-form-modal-upload-template-tab" data-bs-toggle="tab" data-bs-target="#griffinforms-create-form-modal-upload-template" type="button" role="tab">' . esc_html(__('Import as Template', 'griffinforms-form-builder')) . '</button>';
        echo '<button class="nav-link" id="griffinforms-create-form-modal-butler-assist-tab" data-bs-toggle="tab" data-bs-target="#griffinforms-create-form-modal-butler-assist" type="button" role="tab">' . esc_html(__('Griffin Assist', 'griffinforms-form-builder')) . ' <span class="gf-ai-badge">AI</span></button>';
        echo '</div></nav>';
        echo '<div class="tab-content p-3" id="griffinforms-create-form-modal-content">';

        $this->renderTabsContent();

        echo '</div>';
    }

    protected function renderTabsContent()
    {
        echo '<div class="tab-pane fade show active" id="griffinforms-create-form-modal-blank-form" role="tabpanel">';
        $this->blankFormContent();
        echo '</div>';

        echo '<div class="tab-pane fade" id="griffinforms-create-form-modal-choose-template" role="tabpanel">';
        $this->chooseTemplateContent();
        echo '</div>';

        echo '<div class="tab-pane fade" id="griffinforms-create-form-modal-butler-assist" role="tabpanel">';
        $this->butlerAssistContent();
        echo '</div>';

        echo '<div class="tab-pane fade" id="griffinforms-create-form-modal-import-form" role="tabpanel">';
        $this->importFormContent();
        echo '</div>';

        echo '<div class="tab-pane fade" id="griffinforms-create-form-modal-upload-template" role="tabpanel">';
        $this->uploadTemplateContent();
        echo '</div>';

        if (!empty($this->migration_sources)) {
            echo '<div class="tab-pane fade" id="griffinforms-create-form-modal-migrate" role="tabpanel">';
            $this->migrateFromPluginContent();
            echo '</div>';
        }
    }

    protected function chooseTemplateContent()
    {
        echo '<div class="container-fluid">';
        $alert = __('Choose a pre-built template to start quickly. Templates are organized by category to help you find the best fit.', 'griffinforms-form-builder');
        $this->warningAlert($alert);
        $this->templateSearch();
        $this->categoryTabs();
        echo '</div>';
    }

    protected function templateSearch()
    {
        echo '<div class="d-flex align-items-center justify-content-end position-relative gf-create-form-template-search-row">';

        echo '<span id="griffinforms-create-form-modal-template-search-spinner" class="spinner position-relative me-2" style="visibility: visible; bottom: 8px;"></span>';
        
        echo '<div class="input-group input-group-sm mb-3 w-50" style="max-width: 300px;">';
        echo '<input type="text" class="form-control" id="griffinforms-create-form-modal-templates-search-input" placeholder="' . esc_attr__('Search templates...', 'griffinforms-form-builder') . '">';

        echo '</div>';

        echo '</div>';
    }

    protected function categoryTabs()
    {
        $categories = $this->categories;
        $total_template_count = $this->sql->getTotalTemplateCount();

        if (empty($categories)) {
            esc_html_e('No template categories found.', 'griffinforms-form-builder');
            return;
        }

        $all_category = (object) [
            'category' => 'All',
            'template_count' => $total_template_count
        ];

        $search_category = (object) [
            'category' => 'Search',
            'template_count' => 0
        ];

        array_unshift($categories, $all_category, $search_category);

        $content_html = '';

        echo '<div class="gf-create-form-template-layout d-flex align-items-start">';
        echo '<div class="nav flex-column list-group small me-3" id="griffinforms-create-form-modal-category-list" role="tablist">';

        foreach ($categories as $key => $category) {

            $category_label = (string) $category->category;
            $category_slug  = sanitize_title($category_label);

            $pill_id = 'griffinforms-create-form-modal-category-' . $category_slug . '-tab';
            $content_id = 'griffinforms-create-form-modal-category-' . $category_slug . '-content';
            $active_pill = $key === 0 ? ' active' : '';
            $active_content = $key === 0 ? ' show active' : '';

            echo '<button class="griffinforms-templates-category-tab list-group-item list-group-item-action d-flex justify-content-between align-items-center' . esc_attr($active_pill) . '" data-gf-category="' . esc_attr($category_slug) . '" data-gf-category-label="' . esc_attr($category_label) . '" ';
            echo 'id="' . esc_attr($pill_id) . '" data-bs-toggle="pill" data-bs-target="#' . esc_attr($content_id) . '" type="button" role="tab">';
            echo esc_html($this->lang->formTemplatesCategory($category_label));
            echo '<span class="gf-wp-badge ms-3">' . absint($category->template_count) . '</span>';
            echo '</button>';

            $content_html .= '<div class="griffinforms-templates-category-tab-pane tab-pane fade pe-3' . esc_attr($active_content) . '" id="' . esc_attr($content_id) . '" role="tabpanel" tabindex="0">';
            $content_html .= '<div class="row row-cols-1 row-cols-md-4 g-3">';
            if ($category_slug === 'all') {
                $content_html .= $this->butlerQuickCardHtml();
                $content_html .= $this->blankTemplateQuickCardHtml();
            }
            $content_html .= '</div>';
            $content_html .= '<div class="griffinforms-templates-category-info text-center mt-3 small text-muted p-3" style="display: none;"></div>';
            $content_html .='</div>';
        }

        echo '</div>';

        echo '<div class="tab-content w-100" id="griffinforms-form-templates-container">';
        echo wp_kses_post($content_html);
        echo '</div>';
        echo '</div>';
    }

    protected function blankTemplateQuickCardHtml()
    {
        $html  = '<div class="col">';
        $html .= '<div class="griffinforms-form-template-card griffinforms-blank-template-card card small p-0 mt-0 position-relative overflow-hidden shadow-none" style="width: auto; height: 100%">';
        $html .= '<div class="griffinforms-template-preview mb-1 bg-light d-flex align-items-center justify-content-center">';
        $html .= '<span class="dashicons dashicons-plus-alt2 gf-blank-template-icon" aria-hidden="true"></span>';
        $html .= '</div>';
        $html .= '<div class="card-body p-2">';
        $html .= '<div class="card-title small fw-bold">' . esc_html__('Create Blank Form', 'griffinforms-form-builder') . '</div>';
        $blank_desc = __('Start from scratch with default starter settings.', 'griffinforms-form-builder');
        $html .= '<p class="card-text small text-muted" title="' . esc_attr($blank_desc) . '">' . esc_html($blank_desc) . '</p>';
        $html .= '<div class="text-center">';
        $html .= '<button type="button" class="griffinforms-create-blank-form-quick button button-secondary button-small text-center">';
        $html .= '<span>' . esc_html__('Create Form', 'griffinforms-form-builder') . '</span>';
        $html .= '</button>';
        $html .= '</div>';
        $html .= '</div>';
        $html .= '</div>';
        $html .= '</div>';

        return $html;
    }

    protected function importFormContent()
    {
        echo '<div class="mt-4">';
        $alert = __('Import a form from a JSON file to restore previous forms or bring in forms created outside of this site. Ensure your JSON file matches the required format for a smooth import.', 'griffinforms-form-builder');
        $this->warningAlert($alert);
        echo '</div>';

        echo '<div class="mt-2 w-50">';
        
        echo '<div class="mb-3">';
        echo '<label for="griffinforms-create-form-modal-import-form-file" class="form-label">' . esc_html($this->lang->getText('select_form_file')) . '</label>';
        echo '<input class="form-control" id="griffinforms-create-form-modal-import-form-file" type="file">';
        echo '</div>';
        
        echo '<div class="mb-3">';
        $this->buttons->wpBtn([
            'id'    => 'griffinforms-create-form-modal-import-form-btn',
            'class' => 'button button-primary',
            'label' => $this->lang->getText('import_form_file')
        ]);
        echo '</div>';
        
        echo '</div>';
    }

    protected function migrateFromPluginContent()
    {
        $migration_url = admin_url('admin.php?page=griffinforms-migration');

        echo '<div class="mt-4 text-center">';
        echo '<p class="text-muted mb-4 mx-auto" style="max-width: 460px;">' . esc_html__('Detected forms in the following plugins. Go to the Import Forms page to choose which forms to bring into GriffinForms.', 'griffinforms-form-builder') . '</p>';

        echo '<div class="d-flex align-items-center justify-content-center gap-3 mb-4">';
        foreach ($this->migration_sources as $source) {
            $logo_url = $source->getLogoUrl();
            $label    = esc_attr($source->getLabel());
            if ($logo_url) {
                echo '<img src="' . esc_url($logo_url) . '" alt="' . $label . '" title="' . $label . '" style="width: 36px; height: 36px; object-fit: contain;">';
            } else {
                echo '<span class="badge bg-secondary">' . esc_html($source->getLabel()) . '</span>';
            }
        }
        echo '</div>';

        echo '<a href="' . esc_url($migration_url) . '" class="button button-primary button-large">' . esc_html__('Go to Import Forms', 'griffinforms-form-builder') . '</a>';
        echo '</div>';
    }

    protected function blankFormContent()
    {
        echo '<div class="mt-4">';
        $alert = __('Create a new, blank form from scratch. Add fields, customize your layout, and build a form that meets your specific requirements.', 'griffinforms-form-builder');
        $this->warningAlert($alert);
        echo '</div>';

        echo '<div class="mt-2 w-50">';
        echo '<div class="ms-1 mb-3">';
        echo '<label for="griffinforms-create-form-modal-blank-form-name" class="form-label">' . esc_html($this->lang->getText('blank_form_name')) . '</label><br>';
        echo '<input class="w-100" id="griffinforms-create-form-modal-blank-form-name" type="text">';
        echo '</div>';

        $starter_catalog = \GriffinForms\Includes\Onboarding\StarterCatalog::getInstance();
        $starter_fields = $starter_catalog->getBlankFormStarterFieldOptions();
        if (!empty($starter_fields)) {
            echo '<div class="ms-1 mb-3">';
            echo '<div class="small fw-semibold mb-2">' . esc_html__('Optional starter fields', 'griffinforms-form-builder') . '</div>';
            echo '<div class="row row-cols-1 row-cols-md-2 g-2">';
            foreach ($starter_fields as $field_key => $field_data) {
                $field_key = sanitize_key((string) $field_key);
                $field_label = (string) ($field_data['label'] ?? $field_key);
                $field_description = (string) ($field_data['description'] ?? '');
                $input_id = 'griffinforms-create-form-modal-blank-form-starter-field-' . $field_key;

                echo '<div class="col">';
                echo '<div class="border rounded-3 px-3 py-2 h-100 bg-white d-flex align-items-start gap-2">';
                echo '<input class="griffinforms-create-form-modal-blank-form-starter-field mt-1" type="checkbox" value="' . esc_attr($field_key) . '" id="' . esc_attr($input_id) . '">';
                echo '<div class="flex-grow-1">';
                echo '<label class="fw-semibold small mb-0 d-block" for="' . esc_attr($input_id) . '">' . esc_html($field_label) . '</label>';
                if ($field_description !== '') {
                    echo '<div class="small text-muted mt-1">' . esc_html($field_description) . '</div>';
                }
                echo '</div>';
                echo '</div>';
                echo '</div>';
            }
            echo '</div>';
            echo '</div>';
        }
        
        echo '<div class="ms-1 mb-3">';
        $this->buttons->wpBtn([
            'id'    => 'griffinforms-create-form-modal-blank-form-btn',
            'class' => 'button button-primary',
            'label' => $this->lang->getText('create_form')
        ]);
        echo '</div>';
        
        echo '</div>';
    }

    protected function uploadTemplateContent()
    {

        echo '<div class="mt-4">';
        $alert = __('Save a form as a reusable template. Enter the template details and upload a JSON file to add it to the template library for future use.', 'griffinforms-form-builder');
        $this->warningAlert($alert);
        echo '</div>';

        echo '<div class="mt-2 w-50">';
        
        // Template Name Input
        echo '<div class="ms-1 mb-3">';
        echo '<label for="griffinforms-upload-template-name" class="form-label">' . esc_html__('Template Name (required)', 'griffinforms-form-builder') . '</label><br>';
        echo '<input class="w-100" id="griffinforms-upload-template-name" type="text">';
        echo '</div>';
        
        // Template Description Input
        echo '<div class="ms-1 mb-3">';
        echo '<label for="griffinforms-upload-template-description" class="form-label">' . esc_html__('Template Description', 'griffinforms-form-builder') . '</label><br>';
        echo '<textarea class="w-100" id="griffinforms-upload-template-description" rows="5"></textarea>';
        echo '</div>';
        
        // Template Category Dropdown
        echo '<div class="ms-1 mb-3">';
        echo '<label for="griffinforms-upload-template-category" class="form-label">' . esc_html__('Category', 'griffinforms-form-builder') . '</label><br>';
        echo '<select class="w-100" id="griffinforms-upload-template-category">';
        foreach ($this->categories as $category) {
            echo '<option value="' . esc_attr($category->category) . '">' . esc_html($this->lang->formTemplatesCategory($category->category)) . '</option>';
        }
        echo '</select>';
        echo '</div>';
        
        // Template JSON File Upload
        echo '<div class="mb-3">';
        echo '<label for="griffinforms-upload-template-file" class="form-label">' . esc_html__('Upload Template JSON (required)', 'griffinforms-form-builder') . '</label><br>';
        echo '<input class="form-control w-100" id="griffinforms-upload-template-file" type="file">';
        echo '</div>';
        
        // Submit Button
        echo '<div class="">';
        $this->buttons->wpBtn([
            'id'    => 'griffinforms-upload-template-btn',
            'class' => 'button button-primary',
            'label' => __('Upload Template', 'griffinforms-form-builder')
        ]);
        echo '</div>';
        echo '</div>';
    }
    
    protected function modalFooter()
    {   
    }
    
    public function modalJs()
    {
        $js  = 'jQuery(document).ready(function($){' . PHP_EOL;
        $js .= 'const blankFormDefaultName = "' . esc_js(sprintf(__('Form #%d', 'griffinforms-form-builder'), $this->sql->getNextFormNumber())) . '";' . PHP_EOL;
        $js .= 'const blankFormCardHtml = ' . wp_json_encode($this->blankTemplateQuickCardHtml()) . ';' . PHP_EOL;
        $js .= 'const getTemplatesNonce = "' . esc_js(wp_create_nonce('get_form_templates')) . '";' . PHP_EOL;
        $js .= 'const formFromTemplateNonce = "' . esc_js(wp_create_nonce('form_from_template')) . '";' . PHP_EOL;
        $js .= 'const uploadTemplateNonce = "' . esc_js(wp_create_nonce('upload_template')) . '";' . PHP_EOL;
        $js .= 'const searchTemplatesNonce = "' . esc_js(wp_create_nonce('search_templates')) . '";' . PHP_EOL;
        // Previews are now rendered server-side within the template cards
        $js .= 'const ajaxFailMsg = "' . esc_js(__('Network request failed. Try again later.', 'griffinforms-form-builder')) . '";' . PHP_EOL;
        $js .= $this->showErrorMessageJs() . PHP_EOL;
        $js .= $this->slidingNavAccentJs() . PHP_EOL;
        $js .= $this->hideErrorsOnTabSwitchJs() . PHP_EOL;
        $js .= $this->fetchTemplatesJs() . PHP_EOL;
        $js .= $this->loadInitialTemplatesJs() . PHP_EOL;
        $js .= $this->templateCategorySwitchJs() . PHP_EOL;
        $js .= $this->createFormFromTemplateJs() . PHP_EOL;
        $js .= $this->createBlankFormJs() . PHP_EOL;
        $js .= $this->importFormFileJs() . PHP_EOL;
        $js .= $this->uploadTemplateJs() . PHP_EOL;
        $js .= $this->goToTemplatesTab() . PHP_EOL;
        $js .= $this->templateSearchJs() . PHP_EOL;
        $js .= $this->resetTemplateSearchJs() . PHP_EOL;
        $js .= $this->butlerDraftJs() . PHP_EOL;
        // No client-side preview fetching required
        $js .= '});' . PHP_EOL;

        wp_add_inline_script('griffinforms-global-js', $js);
    }

    protected function showErrorMessageJs()
    {
        return '
        function showErrorMessage(message = "") {
            $("#griffinforms-create-form-modal-error").show();
            $("#griffinforms-create-form-modal-error").html(message);
        }
        
        function clearErrorMessage() {
            $("#griffinforms-create-form-modal-error").hide();
            $("#griffinforms-create-form-modal-error").html("");
        }
        ';
    }

    protected function slidingNavAccentJs()
    {
        return '
        const tabsNav = document.getElementById("griffinforms-create-form-modal-tabs");
        const createFormModalEl = document.getElementById("' . esc_attr($this->id) . '");
        let navAccent = null;

        function ensureNavAccent() {
            if (!tabsNav) {
                return null;
            }
            if (!navAccent) {
                navAccent = tabsNav.querySelector(".gf-create-form-nav-accent");
            }
            if (!navAccent) {
                navAccent = document.createElement("span");
                navAccent.className = "gf-create-form-nav-accent";
                tabsNav.appendChild(navAccent);
            }
            return navAccent;
        }

        function moveNavAccentTo(button) {
            const accent = ensureNavAccent();
            if (!accent || !button || !tabsNav.contains(button)) {
                return false;
            }

            const navRect = tabsNav.getBoundingClientRect();
            const btnRect = button.getBoundingClientRect();
            if (navRect.width < 20 || btnRect.width < 20 || btnRect.height < 20) {
                accent.style.opacity = "0";
                return false;
            }
            const inset = Math.max(8, Math.floor(btnRect.width * 0.12));
            const width = Math.max(24, Math.floor(btnRect.width - (inset * 2)));
            const x = Math.floor(btnRect.left - navRect.left + inset);

            accent.style.width = width + "px";
            accent.style.transform = "translateX(" + x + "px)";
            accent.style.opacity = "1";
            return true;
        }

        function moveNavAccentToActive() {
            const activeBtn = tabsNav ? tabsNav.querySelector(".nav-link.active") : null;
            if (activeBtn) {
                const moved = moveNavAccentTo(activeBtn);
                if (!moved) {
                    setTimeout(function () {
                        moveNavAccentTo(activeBtn);
                    }, 80);
                }
            }
        }

        if (tabsNav) {
            ensureNavAccent();
            moveNavAccentToActive();

            tabsNav.querySelectorAll(".nav-link").forEach((btn) => {
                btn.addEventListener("mouseenter", function() {
                    moveNavAccentTo(btn);
                });
                btn.addEventListener("focus", function() {
                    moveNavAccentTo(btn);
                });
            });

            tabsNav.addEventListener("mouseleave", function() {
                moveNavAccentToActive();
            });

            $(document).on("shown.bs.tab", "#griffinforms-create-form-modal-tabs button", function (e) {
                if (e && e.target) {
                    moveNavAccentTo(e.target);
                } else {
                    moveNavAccentToActive();
                }
            });

            window.addEventListener("resize", function () {
                moveNavAccentToActive();
            });

            if (createFormModalEl) {
                createFormModalEl.addEventListener("shown.bs.modal", function () {
                    moveNavAccentToActive();
                    setTimeout(moveNavAccentToActive, 80);
                });
            }
        }
        ';
    }

    protected function hideErrorsOnTabSwitchJs()
    {
        return '
        document.querySelectorAll("#griffinforms-create-form-modal-tabs button").forEach(tabButton => {
            tabButton.addEventListener("shown.bs.tab", function () {
                clearErrorMessage();
            });
        });
        ';
    }

    protected function fetchTemplatesJs()
    {
        return '
        const limit = 10;
        const offsets = {};
        const ended = {};
        const loading = {};

        function skeletonCardsHtml(count = 8) {
            let cards = "";
            for (let i = 0; i < count; i++) {
                cards += "<div class=\"col\">" +
                    "<div class=\"gf-template-skeleton-card card small p-0 mt-0 position-relative overflow-hidden shadow-none\" style=\"width: auto; height: 100%\">" +
                        "<div class=\"gf-template-skeleton-preview\"></div>" +
                        "<div class=\"card-body p-2\">" +
                            "<div class=\"gf-template-skeleton-line gf-template-skeleton-line-title\"></div>" +
                            "<div class=\"gf-template-skeleton-line gf-template-skeleton-line-body\"></div>" +
                            "<div class=\"gf-template-skeleton-line gf-template-skeleton-line-body short\"></div>" +
                            "<div class=\"gf-template-skeleton-button\"></div>" +
                        "</div>" +
                    "</div>" +
                "</div>";
            }
            return cards;
        }

        function fetchTemplates(categorySlug = "all", categoryLabel = "All", isInitialLoad = false) {
            // Initialize tracking for this category
            if (offsets[categorySlug] === undefined) offsets[categorySlug] = 0;
            if (ended[categorySlug] === undefined) ended[categorySlug] = false;
            if (loading[categorySlug] === undefined) loading[categorySlug] = false;

            // Reset offset and template container on initial load
            if (isInitialLoad) {
                offsets[categorySlug] = 0;
                ended[categorySlug] = false;
                const pane = $("#griffinforms-create-form-modal-category-" + categorySlug + "-content");
                const gridRow = pane.children(".row").first();
                gridRow.html(""); // Clear existing templates in target pane
                if (categorySlug === "all") {
                    gridRow.append(blankFormCardHtml);
                }
                gridRow.append(skeletonCardsHtml());
            }

            // Stop if finished or currently loading
            if (ended[categorySlug] || loading[categorySlug]) return;
            loading[categorySlug] = true;

            // Display loading spinner
            $("#griffinforms-create-form-modal-template-search-spinner").css("visibility", "visible");

            $.ajax({
                url: ajaxurl,
                type: "POST",
                data: {
                    action: "getFormTemplates",
                    category: categoryLabel,
                    offset: offsets[categorySlug],
                    limit: limit,
                    nonce: getTemplatesNonce
                },
                success: function(response) {
                    const pane = $("#griffinforms-create-form-modal-category-" + categorySlug + "-content");
                    const gridRow = pane.children(".row").first();
                    if (isInitialLoad) {
                        gridRow.html("");
                        if (categorySlug === "all") {
                            gridRow.append(blankFormCardHtml);
                        }
                    }
                    if (response.success) {
                        gridRow.append(response.data); // Append new templates with server-rendered previews
                        // Increment offset for the next fetch
                        offsets[categorySlug] += limit;
                    } else {
                        if (!response.data || !response.data.empty) {
                            showErrorMessage(response.data && response.data.message ? response.data.message : (response.data || ""));
                        } else {
                            pane.find(".griffinforms-templates-category-info").text(response.data.message).show();
                            ended[categorySlug] = true;
                        }
                    }
                },
                complete: function() {
                    loading[categorySlug] = false;
                    $("#griffinforms-create-form-modal-template-search-spinner").css("visibility", "hidden"); // Hide spinner
                }
            });
        }

        function maybeFetchMore($scroller) {
            const currentScroll = $scroller.scrollTop();
            const innerHeight = $scroller.innerHeight();
            const scrollHeight = $scroller.get(0) ? $scroller.get(0).scrollHeight : 0;

            // Fetch when near bottom; loading/ended guards prevent duplicate fetches.
            if (currentScroll + innerHeight >= scrollHeight - 120) {
                const activeTab = $(".griffinforms-templates-category-tab.active");
                const categorySlug = activeTab.attr("data-gf-category") || "all";
                const categoryLabel = activeTab.attr("data-gf-category-label") || "All";
                if (categorySlug === "search") return; // Do not auto-load in Search tab
                fetchTemplates(categorySlug, categoryLabel);
            }
        }

        // Main infinite-load listener (templates container is the scroll owner).
        $("#griffinforms-form-templates-container").on("scroll", function () {
            maybeFetchMore($(this));
        });
        ';
    }

    protected function templateCategorySwitchJs()
    {
        return '
        $(".griffinforms-templates-category-tab").click(function() {
            const categorySlug = $(this).attr("data-gf-category");
            const categoryLabel = $(this).attr("data-gf-category-label");
            if (categorySlug === "search") return; // Search is populated via its own AJAX
            fetchTemplates(categorySlug, categoryLabel, true);
            resetTemplateSearch();
            clearErrorMessage();
        });';
    }

    protected function loadInitialTemplatesJs()
    {
        return '
        const createFormModal = document.getElementById("' . esc_attr($this->id) . '");
        if (createFormModal) {
            createFormModal.addEventListener("show.bs.modal", (event) => {
                $("#griffinforms-create-form-modal-blank-form-tab").tab("show");
                $("#griffinforms-create-form-modal-blank-form-name").val(blankFormDefaultName);
                $(".griffinforms-create-form-modal-blank-form-starter-field").prop("checked", false);
                resetTemplateSearch();
                clearErrorMessage();
            });

            $("#griffinforms-create-form-modal-choose-template-tab").on("shown.bs.tab", function () {
                const allBtn = $("#griffinforms-create-form-modal-category-all-tab");
                if (allBtn.length) {
                    allBtn.tab("show");
                    const slug = allBtn.attr("data-gf-category") || "all";
                    const label = allBtn.attr("data-gf-category-label") || "All";
                    fetchTemplates(slug, label, true);
                }
            });
        }
        ';
    }

    protected function createBlankFormJs() {
        $js = '
        let blankCreateInFlight = false;

        function setBlankCreateButtonsDisabled(isDisabled) {
            const blankBtn = $("#griffinforms-create-form-modal-blank-form-btn");
            const quickBtn = $("#griffinforms-form-templates-container .griffinforms-create-blank-form-quick");
            if (isDisabled) {
                blankBtn.attr("disabled", true);
                quickBtn.attr("disabled", true);
            } else {
                blankBtn.removeAttr("disabled");
                quickBtn.removeAttr("disabled");
            }
        }

        function submitBlankForm(formName) {
            const starterFields = $(".griffinforms-create-form-modal-blank-form-starter-field:checked").map(function() {
                return $(this).val();
            }).get();

            if (blankCreateInFlight) {
                return;
            }

            clearErrorMessage();

            if (!formName || !formName.trim()) {
                formName = blankFormDefaultName;
            }

            blankCreateInFlight = true;
            setBlankCreateButtonsDisabled(true);

            const data = {
                action: "createBlankForm",
                form_name: formName,
                starter_fields: starterFields,
                nonce: "' . esc_js(wp_create_nonce('create_blank_form')) . '"
            };
    
            $.post(ajaxurl, data, function(response) {
                if (response.success) {
                    let newFormId = response.data.form_id;
                    sessionStorage.setItem("highlightItemId", newFormId);
                    location.reload(); // Reload the page to show the new form
                } else {
                    showErrorMessage(response.data);
                    blankCreateInFlight = false;
                    setBlankCreateButtonsDisabled(false);
                }
            }).fail(function() {
                showErrorMessage("' . esc_js(__('Network request failed. Try again later.', 'griffinforms-form-builder')) . '");
                blankCreateInFlight = false;
                setBlankCreateButtonsDisabled(false);
            });
        }

        $("#griffinforms-create-form-modal-blank-form-btn").click(function() {
            let formName = $("#griffinforms-create-form-modal-blank-form-name").val();

            if (!formName || !formName.trim()) {
                formName = blankFormDefaultName;
                $("#griffinforms-create-form-modal-blank-form-name").val(formName);
            }

            submitBlankForm(formName);
        });

        $("#griffinforms-form-templates-container").on("click", ".griffinforms-create-blank-form-quick", function() {
            submitBlankForm(blankFormDefaultName);
        });
        ';
        return $js;
    }

    protected function createFormFromTemplateJs()
    {
        $js = '
        let templateCreateInFlight = false;

        $("#griffinforms-form-templates-container").on("click", ".griffinforms-create-form-from-template", function() {
            if (templateCreateInFlight) {
                return;
            }
            templateCreateInFlight = true;
            clearErrorMessage();
            let templateId = $(this).attr("data-gf-templateid");
            const data = {
                action: "createFormFromTemplate",
                template_id: templateId,
                nonce: formFromTemplateNonce
            };

            // Disable all buttons with the class to prevent multiple submissions
            $(".griffinforms-create-form-from-template").attr("disabled", true);

            // Show spinner
            $("#griffinforms-create-form-modal-template-search-spinner").css("visibility", "visible");

            // Perform AJAX request
            $.post(ajaxurl, data, function(response) {
                if (response.success) {
                    let importedFormId = response.data;
                    sessionStorage.setItem("highlightItemId", importedFormId);
                    location.reload(); // Reload the page to show the new form
                } else {
                    showErrorMessage(response.data);
                }
            }).fail(function() {
                showErrorMessage(ajaxFailMsg);
            }).always(function() {
                // Re-enable all buttons after the request completes
                $(".griffinforms-create-form-from-template").removeAttr("disabled");
                // Hide spinner
                $("#griffinforms-create-form-modal-template-search-spinner").css("visibility", "hidden");
                templateCreateInFlight = false;
            });
        });
        ';

        return $js;
    }

    protected function importFormFileJs()
    {
        $js = '
        $("#griffinforms-create-form-modal-import-form-btn").click(function(e) {
                e.preventDefault();

                var fileInput = document.getElementById("griffinforms-create-form-modal-import-form-file");
                var file = fileInput.files[0];

                clearErrorMessage();
    
                if (file) {
                    var reader = new FileReader();
                    reader.onload = function(event) {
                        try {
                            var jsonData = JSON.parse(event.target.result);    
                            $.ajax({
                                url: ajaxurl,
                                type: "POST",
                                data: {
                                    action: "importForm",
                                    json_data: jsonData,
                                    nonce: "' . esc_js(wp_create_nonce("import_form")) . '"
                                },
                                success: function(response) {
                                    if (response.success) {
                                        var importedFormId = response.data.form_id;
                                        sessionStorage.setItem("highlightItemId", importedFormId);
                                        location.reload();
                                    } else {
                                        alert("' . esc_html__('Error:', 'griffinforms-form-builder') . ' " + response.data);
                                    }
                                },
                                error: function(xhr, status, error) {
                                    alert("' . esc_html__('An error occurred:', 'griffinforms-form-builder') . ' " + error);
                                }
                            });
                        } catch (e) {
                            alert("' . esc_html__('Invalid JSON file', 'griffinforms-form-builder') . '");
                        }
                    };
    
                    reader.readAsText(file);
                } else {
                    alert("' . esc_html__('Please select a JSON file.', 'griffinforms-form-builder') . '");
                }
            });
        ';

        return $js;
    }

    protected function uploadTemplateJs()
    {
        return '
        $("#griffinforms-upload-template-btn").click(function(e) {
            e.preventDefault();

            clearErrorMessage();
            let templateName = $("#griffinforms-upload-template-name").val();
            let templateDescription = $("#griffinforms-upload-template-description").val();
            let templateCategory = $("#griffinforms-upload-template-category").val();
            let fileInput = document.getElementById("griffinforms-upload-template-file");
            let file = fileInput.files[0];

            if (!templateName || !file) {
                showErrorMessage("Template name and JSON file are required.");
                return;
            }

            let reader = new FileReader();
            reader.onload = function(event) {

                try {
                    let jsonData = JSON.parse(event.target.result);

                    $.ajax({
                        url: ajaxurl,
                        type: "POST",
                        data: {
                            action: "uploadTemplate",
                            template_name: templateName,
                            template_description: templateDescription,
                            template_category: templateCategory,
                            form_data: jsonData,
                            nonce: uploadTemplateNonce
                        },
                        success: function(response) {
                            if (response.success) {
                                $("#griffinforms-upload-template-name").val("");
                                $("#griffinforms-upload-template-description").val("");
                                $("#griffinforms-upload-template-category").val("");
                                $("#griffinforms-upload-template-file").val("");
                                
                                goToTemplatesTab(response.data.template_id);
                                
                            } else {
                                showErrorMessage(response.data);
                            }
                        },
                        error: function(xhr, status, error) {
                            showErrorMessage(ajaxFailMsg + " : " + error);
                        }
                    });
                } catch (e) {
                    showErrorMessage("' . esc_html__('Invalid JSON file.', 'griffinforms-form-builder') . '");
                }
            };

            reader.readAsText(file);
        });
        ';
    }

    protected function goToTemplatesTab()
    {
        return '
        function goToTemplatesTab(templateId) {
            
            $("#griffinforms-create-form-modal-tabs button#griffinforms-create-form-modal-choose-template-tab").tab("show");
            const allBtn = $("#griffinforms-create-form-modal-category-all-tab");
            if (allBtn.length) {
                allBtn.tab("show");
                const slug = allBtn.attr("data-gf-category") || "all";
                const label = allBtn.attr("data-gf-category-label") || "All";
                fetchTemplates(slug, label, true);
            }

            setTimeout(() => {
                const newTemplateCard = $("#griffinforms-form-templates-container").find("[data-gf-templateid=" + templateId + "]");
                if (newTemplateCard.length) {
                    
                    newTemplateCard.addClass("griffinforms-card-popin-animation");

                    setTimeout(() => {
                        newTemplateCard.removeClass("griffinforms-card-popin-animation");
                    }, 2000);

                }
            }, 300); // Delay to ensure templates are loaded
        }
        ';
    }

    protected function templateSearchJs()
    {
        return '
        const minSearchChars = 3;
        const minSearchMsg = "' . esc_js(__('Type at least 3 characters to search templates.', 'griffinforms-form-builder')) . '";

        function showSearchHint(message) {
            const searchTab = $("#griffinforms-create-form-modal-category-search-tab");
            searchTab.removeClass("d-none");
            searchTab.tab("show");
            const searchPane = $("#griffinforms-create-form-modal-category-search-content");
            const gridRow = searchPane.children(".row").first();
            gridRow.html("");
            searchPane.find(".griffinforms-templates-category-info").text(message).show();
            $("#griffinforms-create-form-modal-category-search-tab .badge").html(0);
        }

        function clearSearchHint() {
            const searchPane = $("#griffinforms-create-form-modal-category-search-content");
            searchPane.find(".griffinforms-templates-category-info").hide().text("");
        }

        let debounceTimer;
        $("#griffinforms-create-form-modal-templates-search-input").on("input", function() {
            clearTimeout(debounceTimer);

            clearErrorMessage();

            const searchText = $(this).val().trim().toLowerCase();
            
            if (searchText.length === 0) {
                clearSearchHint();
                const searchPane = $("#griffinforms-create-form-modal-category-search-content");
                const gridRow = searchPane.children(".row").first();
                gridRow.html("");
                $("#griffinforms-create-form-modal-category-search-tab .badge").html(0);
                return;
            }

            // Only proceed with AJAX if search text is 3 or more characters
            if (searchText.length < minSearchChars) {
                showSearchHint(minSearchMsg);
                return;
            }
            
            $("#griffinforms-create-form-modal-template-search-spinner").css("visibility", "visible");
            
            debounceTimer = setTimeout(function() {
                $.ajax({
                    url: ajaxurl,
                    type: "POST",
                    data: {
                        action: "searchTemplates",
                        search_term: searchText,
                        nonce: searchTemplatesNonce
                    },
                    success: function(response) {
                        if (response.success) {
                            clearErrorMessage();
                            clearSearchHint();
                            $("#griffinforms-create-form-modal-category-search-tab").removeClass("d-none").tab("show");
                            const searchPane = $("#griffinforms-create-form-modal-category-search-content");
                            const gridRow = searchPane.children(".row").first();
                            gridRow.html(response.data.html); // HTML includes previews
                            $("#griffinforms-create-form-modal-category-search-tab .badge").html(response.data.count);
                        } else {
                            const searchPane = $("#griffinforms-create-form-modal-category-search-content");
                            const gridRow = searchPane.children(".row").first();
                            gridRow.html("");
                            showErrorMessage(response.data);
                        }
                    },
                    error: function(xhr, status, error) {
                        showErrorMessage("' . esc_html__('An error occurred:', 'griffinforms-form-builder') . ' " + error);
                    }
                });

                $("#griffinforms-create-form-modal-template-search-spinner").css("visibility", "hidden");
                
            }, 300); // Debounce delay in milliseconds
        });

        $("#griffinforms-create-form-modal-templates-search-input").on("blur", function() {
            const value = $(this).val().trim();
            if (value.length > 0) {
                return;
            }

            resetTemplateSearch();
            clearErrorMessage();
            clearSearchHint();

            const allBtn = $("#griffinforms-create-form-modal-category-all-tab");
            if (allBtn.length) {
                allBtn.removeClass("d-none").tab("show");
                fetchTemplates("all", "All", true);
            }
        });
        ';
    }

    protected function resetTemplateSearchJs()
    {
        return '
        function resetTemplateSearch() {
            $("#griffinforms-create-form-modal-templates-search-input").val("");
            $("#griffinforms-create-form-modal-category-search-tab").addClass("d-none");
            const searchPane = $("#griffinforms-create-form-modal-category-search-content");
            const gridRow = searchPane.children(".row").first();
            gridRow.html("");
        }';
    }

    protected function butlerAssistContent()
    {
        $ai_state = new \GriffinForms\Includes\Ai\AiAvailabilityState();
        $assist_active = $ai_state->isActive();
        $has_connector_providers = !empty($ai_state->getAvailableConnectorProviders());
        $can_proceed = $assist_active || $has_connector_providers;
        $settings_url = admin_url('admin.php?page=griffinforms-settings-ai');
        echo '<div class="mt-4 text-center">';
        $assist_icon = trailingslashit($this->config->getRootUrl()) . 'admin/images/butler/icons/griffin-assist.png';
        echo '<div class="gf-butler-avatar-large mb-4">';
        echo '<img src="' . esc_url($assist_icon) . '" alt="" style="width: 80px; height: 80px; border-radius: 50%;">';
        echo '</div>';

        echo '<h3 class="mb-3">' . esc_html__('Draft with Griffin Assist', 'griffinforms-form-builder') . '</h3>';
        echo '<p class="text-muted mb-4 mx-auto" style="max-width: 450px;">' . esc_html__('Tell Griffin Assist what kind of form you need, and it will draft a structure for you in seconds. You can then refine it in the builder.', 'griffinforms-form-builder') . '</p>';
        echo '<div class="mx-auto" style="max-width: 500px;">';
        if (!$can_proceed) {
            $notice = $ai_state->isProviderMapped()
                ? __('Griffin Assist needs an API key before you can draft a form.', 'griffinforms-form-builder')
                : __('Griffin Assist needs an AI provider selected before you can draft a form.', 'griffinforms-form-builder');
            echo '<div class="gf-notice gf-notice-warning mb-3 text-start w-100" role="alert">';
            echo '<p class="mb-0">' . esc_html($notice) . ' ';
            echo '<a href="' . esc_url($settings_url) . '">' . esc_html__('Open Griffin Assist settings', 'griffinforms-form-builder') . '</a>';
            echo '</p>';
            echo '</div>';
        }
        echo '<textarea id="griffinforms-butler-initial-prompt" class="form-control mb-3" rows="4" placeholder="' . esc_attr__('e.g., I need a patient registration form with contact details, medical history table, and insurance upload...', 'griffinforms-form-builder') . '"' . ($can_proceed ? '' : ' disabled="disabled"') . '></textarea>';

        echo '<div class="d-flex justify-content-center gap-2">';
        $this->buttons->wpBtn([
            'id'    => 'griffinforms-butler-draft-btn',
            'class' => 'button button-primary button-large gf-btn-butler-sparkle',
            'label' => __('Generate AI Draft', 'griffinforms-form-builder'),
            'disabled' => !$can_proceed,
        ]);
        echo '</div>';
        echo '</div>';
        
        echo '</div>';
    }

    protected function butlerQuickCardHtml()
    {
        $html  = '<div class="col">';
        $html .= '<div class="griffinforms-form-template-card griffinforms-butler-template-card card small p-0 mt-0 position-relative overflow-hidden shadow-none" style="width: auto; height: 100%; border: 1px dashed #6a5acd; background: rgba(106, 90, 205, 0.02);">';
        $html .= '<div class="griffinforms-template-preview mb-1 d-flex align-items-center justify-content-center" style="background: linear-gradient(135deg, rgba(106, 90, 205, 0.1), rgba(138, 43, 226, 0.1));">';
        $html .= '<span class="dashicons dashicons-admin-appearance gf-butler-template-icon" style="color: #6a5acd; font-size: 32px;" aria-hidden="true"></span>';
        $html .= '</div>';
        $html .= '<div class="card-body p-2">';
        $html .= '<div class="card-title small fw-bold" style="color: #6a5acd;">' . esc_html__('Draft with AI', 'griffinforms-form-builder') . '</div>';
        $desc = __('Use Griffin Assist to draft your form from a prompt.', 'griffinforms-form-builder');
        $html .= '<p class="card-text small text-muted" title="' . esc_attr($desc) . '">' . esc_html($desc) . '</p>';
        $html .= '<div class="text-center">';
        $html .= '<button type="button" class="griffinforms-butler-quick-btn button button-secondary button-small text-center" style="border-color: #6a5acd; color: #6a5acd;">';
        $html .= '<span>' . esc_html__('Open Assist', 'griffinforms-form-builder') . '</span>';
        $html .= '</button>';
        $html .= '</div>';
        $html .= '</div>';
        $html .= '</div>';
        $html .= '</div>';

        return $html;
    }

    protected function butlerDraftJs()
    {
        return '
        let butlerCreateInFlight = false;

        function submitButlerDraft(prompt) {
            if (butlerCreateInFlight) return;
            if (!prompt || !prompt.trim()) {
                showErrorMessage("' . esc_js(__('Please enter a prompt for Griffin Assist.', 'griffinforms-form-builder')) . '");
                return;
            }

            butlerCreateInFlight = true;
            clearErrorMessage();
            $("#griffinforms-butler-draft-btn").attr("disabled", true).addClass("gf-loading");
            $("#griffinforms-create-form-modal-template-search-spinner").css("visibility", "visible");

            const data = {
                action: "initialize_ai_draft",
                prompt: prompt,
                nonce: "' . esc_js(wp_create_nonce('initialize_ai_draft')) . '"
            };

            $.post(ajaxurl, data, function(response) {
                if (response.success && response.data.redirect_url) {
                    location.href = response.data.redirect_url;
                } else {
                    const message = response && response.data && typeof response.data === "object"
                        ? (response.data.message || "Unknown Error")
                        : (response && response.data ? response.data : "Unknown Error");
                    showErrorMessage(message);
                    butlerCreateInFlight = false;
                    $("#griffinforms-butler-draft-btn").removeAttr("disabled").removeClass("gf-loading");
                }
            }).fail(function() {
                showErrorMessage(ajaxFailMsg);
                butlerCreateInFlight = false;
                $("#griffinforms-butler-draft-btn").removeAttr("disabled").removeClass("gf-loading");
            }).always(function() {
                $("#griffinforms-create-form-modal-template-search-spinner").css("visibility", "hidden");
            });
        }

        $("#griffinforms-butler-draft-btn").click(function() {
            submitButlerDraft($("#griffinforms-butler-initial-prompt").val());
        });

        $("#griffinforms-form-templates-container").on("click", ".griffinforms-butler-quick-btn", function() {
            $("#griffinforms-create-form-modal-butler-assist-tab").tab("show");
        });
        ';
    }
}
