(function ($) {
    'use strict';


    const jsonData = {
        SourceLink: "https://prod1.agileticketing.net/websales/feed.ashx?guid=987654321&format=json&v=latest&showsList=true&CPdata=true&fullDescription=true&withmedia=true",
        LastUpdated: "2025-01-29T10:05:18",
        UpdateFrequencyMinutes: 10,
        ArrayOfShows: [
            {
                ID: 1234,
                ExternalID: "1234",
                CorpOrgID: 15389,
                CorpOrgName: "Example Historic Theater",
                OrgID: 9876,
                Folder: "Events",
                Name: "APOCALYPSE NOW: THE FINAL CUT",
                Duration: "147",
                Type: "Repertory Film",
                Distributor: "Lionsgate",
                DistributorID: "37",
                ShortDescription: "Dir. Francis Ford Coppola | USA | 1979 | 147 min. | R | DCP",
                FullDescription: "At the height of the Vietnam war, Captain Benjamin Willard is sent on a dangerous mission that, officially, \"does not exist, nor will it ever exist.\" His goal is to locate - and eliminate - a mysterious Green Beret Colonel named Walter Kurtz, who has been leading his personal army on illegal guerrilla missions into enemy territory.",
                DisplayColor: "EB5854",
                EventImage: "https://prod1.agileticketing.net/images/user/test_54321/apocalypse-now-final-cut.jpg",
                ThumbImage: "https://prod1.agileticketing.net/images/user/test_54321/apocalypse-now-final-cut-thumb.jpg",
                InfoLink: "https://ticketing.dummyTheater.org/websales/pages/info.aspx?evtinfo=1234~987654321&",
                StreamingEnabled: false,
                ModifiedDate: "2025-05-27T13:47:25",
                CurrentShowings: [
                    {
                        ID: 456789,
                        DateTBD: false,
                        StartDate: "2025-02-23T13:00:00",
                        EndDate: "2025-02-23T15:27:00",
                        DisplayDate: "2025-02-23T13:00:00",
                        Duration: "147",
                        Type: "Standard programming",
                        ShortDescription: "At the height of the Vie...s into enemy territory.",
                        SalesMessage: "Buy Tickets",
                        SalesState: "DuringSales",
                        LegacyPurchaseLink: "https://ticketing.dummyTheater.org/websales/pages/ticketsearchcriteria.aspx?evtinfo=123456~654321-1111-2222-3333-444455556666&",
                        ContentDelivery: "InPerson",
                        Venue: {
                            VenueID: 4321,
                            Name: "Example Cinema",
                            Short: "EC",
                            Address1: "1234 E Example St",
                            City: "Nashville",
                            State: "TN",
                            Zip: "11111"
                        }
                    }
                ],
                RelatedEvents: [],
                CustomProperties: [
                    {
                        Name: "imdb",
                        Group: "Film Info",
                        Sequence: 7,
                        Hidden: false,
                        Value: "https://www.imdb.com/title/tt32149731",
                        CustomPropertyID: 2875
                    },
                    {
                        Name: "Language",
                        Group: "Film Info",
                        Sequence: 9,
                        Hidden: false,
                        Value: "English",
                        CustomPropertyID: 2873
                    },
                    {
                        Name: "Production Country",
                        Group: "Film Info",
                        Sequence: 10,
                        Hidden: false,
                        Value: "USA",
                        CustomPropertyID: 2872
                    },
                    {
                        Name: "Rating",
                        Group: "Film Info",
                        Sequence: 12,
                        Hidden: false,
                        Value: "R",
                        CustomPropertyID: 2865
                    },
                    {
                        Name: "Release Year",
                        Group: "Film Info",
                        Sequence: 13,
                        Hidden: false,
                        Value: "2024",
                        CustomPropertyID: 2867
                    },
                ],
                AdditionalMedia:[
                    {
                        Caption: "",
                        MainDuplicate:	true,   
                        Sequence: 0,
                        Type: "Image",
                        Value: "https://qa.agiletix.com/images/user/bct_10583/3-apocalypse-now-final-cut.jpg",
                        MediaEmbed:	'<img src="https://qa.agiletix.com/images/user/bct_10583/3-apocalypse-now-final-cut.jpg" />'
                    }
                ]
            }
        ]
    };

    function initExplainerToggle(explainerId, bodyId) {
        const explainer = document.getElementById(explainerId);
        if (explainer) {
            const newExplainer = explainer.cloneNode(true);
            explainer.parentNode.replaceChild(newExplainer, explainer);
            
            newExplainer.addEventListener('click', function () {
                $(bodyId).toggle();
            });
        }
    }

    function initExplainers(explainerPairs) {
        explainerPairs.forEach(pair => {
            initExplainerToggle(pair.explainerId, pair.bodyId);
        });
    }

    function makeAjaxCall(action, data, callbacks) {
        const defaultCallbacks = {
            beforeSend: null,
            success: null,
            error: null,
            complete: null
        };
        const mergedCallbacks = Object.assign({}, defaultCallbacks, callbacks);

        $.ajax({
            url: agileAjax.ajaxurl,
            type: 'POST',
            data: Object.assign({ action: action }, data),
            beforeSend: mergedCallbacks.beforeSend,
            success: mergedCallbacks.success,
            error: mergedCallbacks.error,
            complete: mergedCallbacks.complete
        });
    }

    function setButtonState($button, disabled, text, className) {
        $button.prop('disabled', disabled);
        if (text) {
            $button.find('.agile-refresh-text, .agile-webhook-button-text').text(text);
        }
        if (className) {
            $button.removeClass('agile-webhook-button-activate agile-webhook-button-deactivate refreshing');
            $button.addClass(className);
        }
    }

    function initComingSoonFeedToggle() {
        function toggleComingSoonFields() {
            let isEnabled = $('#agile_field_use_coming_soon_feed').is(':checked');
            // Toggle fields with the agile_coming_soon_field class (GUID and EPG ID, but not the checkbox)
            $('.agile_coming_soon_field').each(function() {
                let $field = $(this);
                // Find the closest table row or table containing this field
                let $row = $field.closest('tr');
                if ($row.length > 0) {
                    $row.toggle(isEnabled);
                } else {
                    // If in card structure, toggle the table containing the field
                    $field.closest('table').toggle(isEnabled);
                }
            });
            
            // Toggle required attribute on coming soon fields (GUID and EPG ID)
            let $comingSoonGuid = $('#agile_field_coming_soon_guid');
            let $comingSoonEpgID = $('#agile_field_coming_soon_epgID');
            if (isEnabled) {
                $comingSoonGuid.prop('required', true);
                $comingSoonEpgID.prop('required', true);
            } else {
                $comingSoonGuid.prop('required', false);
                $comingSoonEpgID.prop('required', false);
            }
        }
        
        // Initial toggle after a short delay to ensure DOM is ready
        setTimeout(function() {
            toggleComingSoonFields();
        }, 100);
        
        $(document).off('change', '#agile_field_use_coming_soon_feed').on('change', '#agile_field_use_coming_soon_feed', toggleComingSoonFields);
    }

    function initCredentialsTab() {
        initPasswordToggle();
        initCredentialsExplainers();
        initComingSoonFeedToggle();
        $("#agile_credentials_activate_webhook").on('click', function (e) {
            e.preventDefault();
            let button = $(this);
            let $buttonText = button.find('.agile-webhook-button-text');
            let isActivation = $buttonText.text().trim() === 'Activate';
            
            makeAjaxCall('agile_activate_webhook', { is_activation: isActivation ? 1 : 0 }, {
                beforeSend: function () {
                    setButtonState(button, true, isActivation ? 'Activating...' : 'Deactivating...', 'processing');
                },
                success: function () {
                    button.removeClass('agile-webhook-button-activate agile-webhook-button-deactivate');
                    if (isActivation) {
                        button.addClass('agile-webhook-button-deactivate');
                        button.find('.agile-webhook-icon').html('<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" fill="currentColor"/>');
                        $buttonText.text('Deactivate');
                    } else {
                        button.addClass('agile-webhook-button-activate');
                        button.find('.agile-webhook-icon').html('<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" fill="currentColor"/>');
                        $buttonText.text('Activate');
                    }
                },
                complete: function () {
                    setButtonState(button, false, null, null);
                    button.removeClass('processing');
                }
            });
        });
    }

    function initStyleTab() {
        const styleEditor = ace.edit("ace-editor");
        styleEditor.setTheme("ace/theme/monokai");
        styleEditor.session.setMode("ace/mode/css");
        styleEditor.renderer.setShowGutter(true);

        styleEditor.session.on("change", function () {
            $("#ace-editor-hidden").val(styleEditor.getValue());
        });

        function loadStylePreset(presetName) {
            if (presetName === 'none') {
                clearStyleEditor();
                return;
            }

            makeAjaxCall('agile_get_style_preset', { preset: presetName }, {
                beforeSend: function () {
                    $('.agile-preset-btn').prop('disabled', true);
                },
                success: function (response) {
                    if (response.success && response.data && response.data.content) {
                        styleEditor.setValue(response.data.content, -1);
                        $("#ace-editor-hidden").val(response.data.content);
                    } else {
                        alert('Failed to load preset: ' + (response.data || 'Unknown error'));
                    }
                },
                error: function (xhr, status, error) {
                    alert('Error loading preset: ' + error);
                },
                complete: function () {
                    $('.agile-preset-btn').prop('disabled', false);
                }
            });
        }

        function clearStyleEditor() {
            styleEditor.setValue('', -1);
            $("#ace-editor-hidden").val('');
        }

        function addCustomStyleButton(slotNumber, presetName) {
            const existingBtn = $('.agile-preset-btn[data-preset="' + presetName + '"]');
            if (existingBtn.length > 0) {
                return; // Button already exists
            }

            const saveBtn1 = $('#agile-save-preset-btn-1');
            const newBtn = $('<button>')
                .attr('type', 'button')
                .addClass('button agile-preset-btn')
                .attr('data-preset', presetName)
                .text('Custom Style ' + slotNumber);
            
            saveBtn1.before(newBtn);
        }

        $(document).on('click', '.agile-preset-btn', function () {
            const presetName = $(this).data('preset');
            if (presetName) {
                loadStylePreset(presetName);
            }
        });

        // Handle Save button clicks - use event delegation for both buttons
        $(document).on('click', '.agile-save-preset-btn', function () {
            const cssContent = styleEditor.getValue();
            const cssContentTrimmed = cssContent.trim();

            // Validate content is non-empty
            if (!cssContentTrimmed) {
                alert('Cannot save empty CSS. Please add some CSS content before saving.');
                return;
            }

            const targetSlot = $(this).data('slot');
            if (!targetSlot) {
                alert('Error: Could not determine target slot.');
                return;
            }

            const $saveBtn = $(this);
            $saveBtn.prop('disabled', true);
            const originalText = $saveBtn.text();
            $saveBtn.text('Saving...');

            makeAjaxCall('agile_save_custom_style_preset', { 
                css_content: cssContent,
                target_slot: targetSlot
            }, {
                success: function (response) {
                    if (response.success && response.data) {
                        const slotNumber = response.data.slot;
                        const presetName = response.data.preset_name;
                        
                        // Add the custom style button if it doesn't exist
                        addCustomStyleButton(slotNumber, presetName);
                        
                        alert(response.data.message || 'Custom Style ' + slotNumber + ' saved successfully!');
                    } else {
                        alert('Failed to save preset: ' + (response.data || 'Unknown error'));
                    }
                },
                error: function (xhr, status, error) {
                    alert('Error saving preset: ' + error);
                },
                complete: function () {
                    $saveBtn.prop('disabled', false);
                    $saveBtn.text(originalText);
                }
            });
        });
    }

    function initThemeTab() {
        initExplainers([
            { explainerId: 'agile_theme_explainer', bodyId: '#agile_theme_explainer_body' },
            { explainerId: 'agile_custom_fields_explainer', bodyId: '#agile_custom_fields_explainer_body' },
            { explainerId: 'agile_post_terms_explainer', bodyId: '#agile_post_terms_explainer_body' },
            { explainerId: 'agile_function_editor_explainer', bodyId: '#agile_function_editor_explainer_body' },
            { explainerId: 'agile_mapping_fields_explainer', bodyId: '#agile_mapping_fields_explainer_body' }
        ]);

        initThemeIntegrationHandler();

        let taxonomyCache = {};

        function updateTaxonomyDatalists(taxonomies) {
            $(".taxonomy-input").each(function () {
                let input = $(this);
                let datalistId = input.attr("list");
                let datalist = $("#" + datalistId);

                datalist.empty();
                $.each(taxonomies, function (index, taxonomy) {
                    datalist.append($("<option>").val(taxonomy));
                });
            });
        }

        $("#agile_field_theme_custom_map_post_type").on("change", function () {
            let postType = $(this).val();
            if (!postType) return;

            if (taxonomyCache[postType]) {
                updateTaxonomyDatalists(taxonomyCache[postType]);
            } else {
                makeAjaxCall('agile_get_tax_by_post_type', { PostType: postType }, {
                    success: function (response) {
                        if (response.success) {
                            taxonomyCache[postType] = response.data;
                            updateTaxonomyDatalists(response.data);
                        } else {
                            console.error("Error fetching taxonomies:", response.data);
                        }
                    }
                });
            }
        });

        initTermFields();
        $('#agile_field_config_integration_type').trigger("change");

        const exampleEditor1 = ace.edit("json_editor");
        exampleEditor1.session.setMode("ace/mode/json");
        exampleEditor1.setTheme("ace/theme/monokai");
        exampleEditor1.setValue(JSON.stringify(jsonData, null, 2));
        exampleEditor1.setReadOnly(true);

        const function_editor = ace.edit("function-editor-textarea");
        function_editor.session.setMode("ace/mode/php");
        function_editor.setTheme("ace/theme/monokai");
        const function_text_area = $('#function-editor-textarea');

        const storedCode = document.getElementById("function-editor-hidden").value;
        function_editor.setValue(storedCode, -1);

        const functionEditorTab = $('#function-editor-tab');
        functionEditorTab.on('click', function () {
            function_text_area.toggle();
        });

        function_editor.getSession().on('change', function () {
            document.getElementById("function-editor-hidden").value = function_editor.getValue();
        });
    }

    function initContentTab() {
        initExplainerToggle('agile_content_explainer', '#agile_content_explainer_body');

        const exampleEditor2 = ace.edit("json_editor");
        exampleEditor2.session.setMode("ace/mode/json");
        exampleEditor2.setTheme("ace/theme/monokai");
        exampleEditor2.setValue(JSON.stringify(jsonData, null, 2));
        exampleEditor2.setReadOnly(true);

        function togglecarouselExtraViz($checked) {
            if ($checked) {
                $(".agile_carousel_extra").closest('tr').show();
            } else {
                $(".agile_carousel_extra").closest('tr').hide();
            }
        }

        $("#agile_field_render_carousel").on("click", function () {
            togglecarouselExtraViz($(this).is(':checked'));
        });

        togglecarouselExtraViz($("#agile_field_render_carousel").is(':checked'));

        initContentBuilder();
    }

    function initUtilityTab() {
        function refreshUtilityDisplay() {
            makeAjaxCall('agile_refresh_utility', {}, {
                success: function (response) {
                    $('#agile_update_status').text(response.data.updateStatus);
                    $('#agile_time_since_refresh_finish').text(response.data.timeOutMessage);
                    if (response.data.first_post_date) {
                        $('#agile_processing_started_date').text(response.data.first_post_date);
                    }
                    $('#agile_time_since_chunk_started').text(response.data.time_since_chunk_started);
                    if (response.data.total_processing_start_date) {
                        $('#agile_total_processing_started_date').text(response.data.total_processing_start_date);
                    }
                    $('#agile_time_since_post_began').text(response.data.time_since_post_began);
                    if (response.data.last_post_date) {
                        $('#agile_completed_at_date').text(response.data.last_post_date);
                    }
                    $('#agile_time_since_post_finish').text(response.data.time_since_post_finish);
                    $('#agile_last_runtime').text(response.data.lastRuntimeFormatted);
                    $('#agile_post_count_created').text(response.data.post_count_created);
                    $('#agile_post_count_updated').text(response.data.post_count_updated);
                    $('#agile_post_count_deleted').text(response.data.post_count_deleated);
                }
            });
        }

        $('#ats_refresh_button_fast, #ats_refresh_button_slow').on('click', function (e) {
            e.preventDefault();
            let isFullRefresh = $(this).attr('id') === 'ats_refresh_button_slow';
            let button = $(this);
            let $text = button.find('.agile-refresh-text');
            let originalText = $text.text();
            
            setButtonState(button, true, 'Refreshing...', 'refreshing');

            makeAjaxCall('agile_refresh_ats_data', { full_refresh: isFullRefresh ? 1 : 0 }, {
                beforeSend: function () {
                    $('#agile_update_status').text('Active');
                },
                success: function () {
                    refreshUtilityDisplay();
                },
                complete: function () {
                    setButtonState(button, false, originalText, null);
                    button.removeClass('refreshing');
                }
            });
        });
    }

    function initAdvancedTab() {
        initExplainerToggle('agile_advanced_explainer', '#agile_advanced_explainer_body');
    }

    function organizeTab(tabName, cardConfigs) {
        let currentTab = new URLSearchParams(window.location.search).get('tab');
        if (currentTab !== tabName) return;
        
        let $form = $('form[action="options.php"]');
        if (!$form.length) return;
        
        const containerClass = `.agile-${tabName}-container`;
        if ($form.find(containerClass).length) return;
        
        let $formTable = $form.find('table.form-table');
        if (!$formTable.length) return;
        
        let $container = $(`<div class="agile-${tabName}-container"></div>`);
        
        const cards = cardConfigs.map(config => {
            const $card = $(`
                <div class="agile-utility-card">
                    <div class="agile-utility-card-header">
                        <svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                            <path d="${config.iconPath}" fill="currentColor"/>
                        </svg>
                        <h3>${config.title}</h3>
                    </div>
                    <div class="agile-config-fields"></div>
                </div>
            `);
            return { $card, fieldMatcher: config.fieldMatcher };
        });
        
        $formTable.find('tbody tr').each(function() {
            let $row = $(this);
            let fieldId = $row.find('input, select').first().attr('id') || '';
            let fieldName = $row.find('input, select').first().attr('name') || '';
            
            let $fieldTable = $('<table class="form-table"><tbody></tbody></table>');
            $fieldTable.find('tbody').append($row.clone());
            
            let matched = false;
            for (let card of cards) {
                if (card.fieldMatcher(fieldId, fieldName)) {
                    card.$card.find('.agile-config-fields').append($fieldTable);
                    matched = true;
                    break;
                }
            }
            
            if (!matched && cards.length > 0) {
                cards[0].$card.find('.agile-config-fields').append($fieldTable);
            }
        });
        
        cards.forEach(card => {
            if (card.$card.find('.agile-config-fields').children().length > 0) {
                $container.append(card.$card);
            }
        });
        
        if ($container.children().length > 0) {
            $formTable.replaceWith($container);
        }
    }

    function organizeConfigTab() {
        organizeTab('config', [
            {
                title: 'Post Settings',
                iconPath: 'M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z',
                fieldMatcher: (id, name) => id.indexOf('comment_status') !== -1 || 
                                           id.indexOf('post_status') !== -1 || 
                                           id.indexOf('auto_cull') !== -1
            },
            {
                title: 'Integration Widget',
                iconPath: 'M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z',
                fieldMatcher: (id, name) => id.indexOf('widget') !== -1 || name.indexOf('widget') !== -1
            }
        ]);
        
        initWidgetToggle();
    }

    function organizeAdvancedTab() {
        let currentTab = new URLSearchParams(window.location.search).get('tab');
        if (currentTab !== 'advanced') return;
        
        let $form = $('form[action="options.php"]');
        if (!$form.length) return;
        
        let $existingContainer = $form.find('.agile-advanced-container');
        let $existingCard = $existingContainer.find('.agile-utility-card');
        
        if ($existingCard.length > 0) {
            // Card already exists, just populate it with fields
            let $formTable = $form.find('table.form-table');
            if (!$formTable.length) return;
            
            let $fieldsContainer = $existingCard.find('.agile-config-fields');
            
            $formTable.find('tbody tr').each(function() {
                let $row = $(this);
                let $fieldTable = $('<table class="form-table"><tbody></tbody></table>');
                $fieldTable.find('tbody').append($row.clone());
                $fieldsContainer.append($fieldTable);
            });
            
            $formTable.remove();
        } else {
            // Fallback to original behavior if card doesn't exist
            organizeTab('advanced', [
                {
                    title: 'Action Scheduler Settings',
                    iconPath: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
                    fieldMatcher: () => true
                }
            ]);
        }
    }

    function organizeCredentialsTab() {
        organizeTab('credentials', [
            {
                title: 'Basic Credentials',
                iconPath: 'M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 10.99h7c-.53 4.12-3.28 7.79-7 8.94V12H5V6.3l7-3.11v8.8z',
                fieldMatcher: (id, name) => id.indexOf('domain') !== -1 || id.indexOf('corpOrgID') !== -1
            },
            {
                title: 'Entry Point Configuration',
                iconPath: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
                fieldMatcher: (id, name) => id.indexOf('epgID') !== -1 || 
                                           id.indexOf('guid') !== -1 || 
                                           id.indexOf('epgTag') !== -1 ||
                                           id.indexOf('coming_soon') !== -1 || 
                                           name.indexOf('coming_soon') !== -1 ||
                                           id.indexOf('use_coming_soon_feed') !== -1
            },
            {
                title: 'Security',
                iconPath: 'M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z',
                fieldMatcher: (id, name) => id.indexOf('password') !== -1 || name.indexOf('password') !== -1
            }
        ]);
        
        initCredentialsExplainers();
        initComingSoonFeedToggle();
    }

    function initWidgetToggle() {
        function toggleWidgetFields() {
            let isEnabled = $('#agile_field_widget_active').is(':checked');
            let $targetTable = $('.agile-config-fields').find('table').has('#agile_field_widget_target');
            let $modeTable = $('.agile-config-fields').find('table').has('#agile_field_widget_mode');
            
            if (isEnabled) {
                $targetTable.show();
                $modeTable.show();
            } else {
                $targetTable.hide();
                $modeTable.hide();
            }
        }
        
        toggleWidgetFields();
        $(document).off('change', '#agile_field_widget_active').on('change', '#agile_field_widget_active', toggleWidgetFields);
    }

    function initCredentialsExplainers() {
        const fields = ["domain", "corpOrgID", "epgID", "guid", "epgTag"];
        fields.forEach(field => {
            initExplainerToggle('agile_' + field + '_explainer', '#agile_' + field + '_explainer_body');
        });
    }

    function initPasswordToggle() {
        $(document).off('click', '#togglePassword').on('click', '#togglePassword', function() {
            let $input = $('#agile_field_password');
            let $icon = $(this);
            let $path = $icon.find('path');
            let type = $input.attr('type') === 'password' ? 'text' : 'password';
            $input.attr('type', type);
            
            if (type === 'text') {
                $path.attr('d', 'M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-5.9-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 5.9 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z');
            } else {
                $path.attr('d', 'M12 4.5C6.9 4.5 2.73 7.61 1 12c1.73 4.39 5.9 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-5.9-7.5-11-7.5zm0 12c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5 16.5 9.51 16.5 12 14.49 16.5 12 16.5zm0-7.5c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z');
            }
        });
    }

    let themeIntegrationHandlerInitialized = false;
    function initThemeIntegrationHandler() {
        if (themeIntegrationHandlerInitialized) return;
        themeIntegrationHandlerInitialized = true;
        
        $(document).on('change', '#agile_field_config_integration_type', function () {
            let postTypeBox = $('#agile_field_theme_custom_map_post_type');
            let templateBox = $('#agile_field_theme_custom_map_template');
            
            if (!postTypeBox.length || !templateBox.length) return;
            
            switch (this.value) {
                case 'none':
                    postTypeBox.val('agile_post');
                    break;
                case 'event_champ':
                    postTypeBox.val('event');
                    break;
                case 'amy_movie':
                    postTypeBox.val('amy_movie');
                    break;
            }

            let isDisabled = !(this.value === 'custom');
            postTypeBox.prop("disabled", isDisabled);
            templateBox.prop("disabled", isDisabled);
        });
        
        setTimeout(function() {
            let integrationType = $('#agile_field_config_integration_type');
            if (integrationType.length) {
                integrationType.trigger("change");
            }
        }, 50);
    }

    function organizeThemeMappingFields() {
        let currentTab = new URLSearchParams(window.location.search).get('tab');
        if (currentTab !== 'theme') return;

        let $themeForm = $('form[action="options.php"]');
        if (!$themeForm.length) return;
        
        let $formTable = $themeForm.find('table.form-table');
        if (!$formTable.length) return;
        
        let $mappingCard = $themeForm.find('.agile-theme-mapping-card');
        if (!$mappingCard.length) {
            $mappingCard = $('<div class="agile-theme-card agile-theme-mapping-card"><div class="agile-theme-card-header"><svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" fill="currentColor"/></svg><h3>Mapping Fields</h3></div><div class="agile-theme-mapping-fields"></div></div>');
            let $mappingSection = $themeForm.find('.agile-theme-mapping-section');
            if ($mappingSection.length) {
                $mappingCard.insertBefore($mappingSection);
            } else {
                $formTable.before($mappingCard);
            }
        }
        
        if ($mappingCard.find('.agile-theme-mapping-fields tr').length > 0) {
            return;
        }
        
        let $mappingRows = $formTable.find('tbody tr').filter(function() {
            let $row = $(this);
            let fieldId = $row.find('input, select').first().attr('id') || '';
            return fieldId.indexOf('agile_field_config_integration_type') !== -1 ||
                   fieldId.indexOf('agile_field_theme_custom_map_post_type') !== -1 ||
                   fieldId.indexOf('agile_field_theme_custom_map_template') !== -1;
        });
        
        if ($mappingRows.length === 0) return;
        
        $mappingRows.each(function() {
            let $row = $(this);
            let $fieldTable = $('<table class="form-table"><tbody></tbody></table>');
            let $clonedRow = $row.clone(true, true);
            $fieldTable.find('tbody').append($clonedRow);
            $mappingCard.find('.agile-theme-mapping-fields').append($fieldTable);
        });
        
        $mappingRows.remove();
        
        setTimeout(function() {
            let integrationType = $('#agile_field_config_integration_type');
            if (integrationType.length) {
                integrationType.trigger("change");
            }
        }, 100);
    }

    function markThemeCardRows() {
        let currentTab = new URLSearchParams(window.location.search).get('tab');
        if (currentTab !== 'theme') return;
        
        // Find all form-tables that contain agile-theme-card elements
        $('.form-table').each(function() {
            let $table = $(this);
            // Check if this table contains any of our theme cards
            if ($table.find('.agile-theme-card').length > 0) {
                // Remove form-table class to eliminate indentation
                $table.removeClass('form-table').addClass('agile-theme-card-table');
                // Also mark the row for existing CSS rules
                $table.find('tr').addClass('agile-theme-card-row');
            }
        });
        
        // Also check for any tables that might have been missed
        $('.agile-theme-card').each(function() {
            let $card = $(this);
            let $table = $card.closest('table.form-table');
            if ($table.length > 0) {
                $table.removeClass('form-table').addClass('agile-theme-card-table');
                $table.find('tr').addClass('agile-theme-card-row');
            }
        });
    }


    function initCustomFields() {
        $(document).on('click', '#meta-add-field', function() {
            let table = document.getElementById('custom-fields-table');
            if (!table) return;
            let tbody = table.getElementsByTagName('tbody')[0];
            let row = tbody.insertRow();
            let index = tbody.rows.length - 1;
            row.innerHTML = '<td><input type="text" name="agile_custom_fields[' + index + '][0]" /></td>' +
                '<td><input type="text" name="agile_custom_fields[' + index + '][1]" /></td>' +
                '<td><button type="button" class="meta-remove-field button-secondary">Remove</button></td>';
        });

        $(document).on('click', '.meta-remove-field, #meta-remove-field', function() {
            $(this).closest('tr').remove();
        });
    }

    let termFieldsInitialized = false;
    function initTermFields() {
        if (termFieldsInitialized) return;
        termFieldsInitialized = true;
        
        $(document).on('click', '#term-add-field', function(e) {
            e.preventDefault();
            e.stopPropagation();
            let table = $("#custom-term-table tbody");
            if (!table.length) return;
            
            let index = table.find("tr").length;
            let datalistId = 'taxonomy-list-' + index;
            let newRow = $('<tr>').html(
                '<td>' +
                    '<input type="text" list="' + datalistId + '" name="agile_term_fields[' + index + '][0]" class="taxonomy-input" autocomplete="off" placeholder="Type or select taxonomy" />' +
                    '<datalist id="' + datalistId + '"></datalist>' +
                '</td>' +
                '<td><input type="text" name="agile_term_fields[' + index + '][1]" placeholder="Enter value" /></td>' +
                '<td><button type="button" class="button-secondary term-remove-field">Remove</button></td>'
            );
            table.append(newRow);
            $("#agile_field_theme_custom_map_post_type").trigger("change");
        });

        $(document).on('click', '.term-remove-field', function(e) {
            e.preventDefault();
            e.stopPropagation();
            $(this).closest('tr').remove();
        });
    }


    function initContentBuilder() {
        const canvas = document.getElementById('agile-builder-canvas');
        const paletteBlocks = document.querySelectorAll('#agile-builder-palette .agile-block');
        const hidden = document.getElementById('agile_layout_json');
        if (!canvas || !hidden) { return; }

        const FIELD_META = {
            agile_field_content_distributor: { label: 'Distributor', token: '{distributor}', textless: false },
            agile_field_content_duration: { label: 'Duration', token: '{duration}', textless: false },
            agile_field_content_short_description: { label: 'Short Description', token: '{short description}', textless: false },
            agile_field_content_full_description: { label: 'Full Description', token: '{full description}', textless: false },
            agile_field_content_infolink: { label: 'Info Link', token: '', textless: false },
            agile_field_content_renderlocation: { label: 'Location', token: '', textless: true },
            agile_field_content_rating: { label: 'Rating', token: '', textless: true },
            agile_field_content_type: { label: 'Type', token: '{type}', textless: false },
            agile_field_content_short_descriptive1: { label: 'ShortDescriptive1', token: '{short descriptive1}', textless: false },
            agile_field_content_short_descriptive2: { label: 'ShortDescriptive2', token: '{short descriptive2}', textless: false },
            agile_field_content_extra_html: { label: 'ExtraHTML', token: '{extra html}', textless: false }
        };

        function getFieldMeta(fieldKey) {
            if (!fieldKey) { return undefined; }
            return FIELD_META[String(fieldKey).toLowerCase()];
        }

        function makeCanvasBlock(blockData) {
            const el = document.createElement('div');
            el.className = 'agile-canvas-block';
            el.setAttribute('data-type', blockData.type);
            if (blockData.field) el.setAttribute('data-field', blockData.field);
            if (blockData.propertyName) el.setAttribute('data-property-name', blockData.propertyName);

            const drag = document.createElement('span');
            drag.className = 'drag-handle';
            drag.textContent = '≡';

            const content = document.createElement('div');
            content.className = 'content';
            const header = document.createElement('div');
            header.className = 'block-header';
            const label = document.createElement('span');
            label.className = 'block-label';
            
            if (blockData.type === 'text') {
                label.textContent = 'Text';
            } else if (blockData.type === 'custom-property') {
                label.textContent = 'Custom Property';
            } else {
                const meta = FIELD_META[blockData.field] || { label: (blockData.field || '').replace(/^agile_field_content_/, '').replace(/_/g, ' '), token: '', textless: false };
                const resolvedMeta = getFieldMeta(blockData.field) || meta;
                label.textContent = resolvedMeta.label;
                if (resolvedMeta.token) {
                    const badge = document.createElement('span');
                    badge.className = 'token-badge';
                    badge.innerHTML = '<code>' + resolvedMeta.token + '</code>';
                    header.appendChild(badge);
                }
            }
            header.appendChild(label);
            content.appendChild(header);

            const meta = getFieldMeta(blockData.field);
            if (blockData.type === 'field' && meta && meta.textless) {
                const note = document.createElement('div');
                note.className = 'textless-note';
                const fieldKey = blockData.field ? blockData.field.toLowerCase() : '';
                if (fieldKey === 'agile_field_content_rating') {
                    note.textContent = 'Textless block - Requires: Vote Average & Vote Count custom properties';
                } else if (fieldKey === 'agile_field_content_renderlocation') {
                    note.textContent = 'Textless block - Requires: CurrentShowings with Venue data';
                } else {
                    note.textContent = 'Textless block';
                }
                content.appendChild(note);
            } else if (blockData.type === 'custom-property') {
                const propertyNameDiv = document.createElement('div');
                propertyNameDiv.style.marginBottom = '8px';
                propertyNameDiv.style.border = '1px solid #ddd';
                propertyNameDiv.style.padding = '8px';
                propertyNameDiv.style.backgroundColor = '#f9f9f9';
                
                const propertyNameLabel = document.createElement('label');
                propertyNameLabel.textContent = 'Property Name:';
                propertyNameLabel.style.display = 'block';
                propertyNameLabel.style.fontSize = '12px';
                propertyNameLabel.style.marginBottom = '4px';
                
                const propertyNameInput = document.createElement('input');
                propertyNameInput.type = 'text';
                propertyNameInput.className = 'property-name-input';
                propertyNameInput.placeholder = 'e.g. rating, genre, director';
                propertyNameInput.value = blockData.propertyName || '';
                propertyNameInput.style.width = '100%';
                propertyNameInput.addEventListener('input', serialize);
                
                propertyNameDiv.appendChild(propertyNameLabel);
                propertyNameDiv.appendChild(propertyNameInput);
                content.appendChild(propertyNameDiv);
                
                const templateDiv = document.createElement('div');
                templateDiv.style.border = '1px solid #ddd';
                templateDiv.style.padding = '8px';
                templateDiv.style.backgroundColor = '#f9f9f9';
                
                const templateLabel = document.createElement('label');
                templateLabel.textContent = 'Template:';
                templateLabel.style.display = 'block';
                templateLabel.style.fontSize = '12px';
                templateLabel.style.marginBottom = '4px';
                
                const templateInput = document.createElement('input');
                templateInput.type = 'text';
                templateInput.className = 'template-input';
                templateInput.placeholder = 'e.g. Rated {rating}, Genre: {genre}';
                templateInput.value = blockData.template || '';
                templateInput.style.width = '100%';
                templateInput.addEventListener('input', serialize);
                
                templateDiv.appendChild(templateLabel);
                templateDiv.appendChild(templateInput);
                content.appendChild(templateDiv);
            } else {
                const input = document.createElement('input');
                input.type = 'text';
                const token = (blockData.type === 'field' && meta) ? (meta.token || '') : '';
                let initial = blockData.text || '';
                if (token && initial.indexOf(token) === -1) {
                    initial = (initial.trim() ? initial + ' ' : '') + token;
                }
                input.value = initial;
                input.placeholder = blockData.type === 'text' ? 'Text' : ((meta && meta.token) ? meta.token : (blockData.field || '').replace(/^agile_field_content_/, '').replace(/_/g, ' '));

                if (token) {
                    let lastWithToken = input.value;
                    input.addEventListener('input', function () {
                        if (input.value.indexOf(token) === -1) {
                            input.value = lastWithToken;
                        } else {
                            lastWithToken = input.value;
                        }
                        serialize();
                    });
                } else {
                    input.addEventListener('input', serialize);
                }
                content.appendChild(input);
            }

            const remove = document.createElement('button');
            remove.type = 'button';
            remove.className = 'button-secondary';
            remove.textContent = 'Remove';
            remove.addEventListener('click', function(){ el.remove(); serialize(); });

            el.appendChild(drag);
            el.appendChild(content);
            el.appendChild(remove);
            return el;
        }

        function serialize() {
            const data = [];
            canvas.querySelectorAll('.agile-canvas-block').forEach(function(node){
                const type = node.getAttribute('data-type');
                const field = node.getAttribute('data-field') || undefined;
                const propertyName = node.getAttribute('data-property-name') || undefined;
                
                const block = { type: type };
                if (field) block.field = field;
                if (propertyName) block.propertyName = propertyName;
                
                if (type === 'custom-property') {
                    const propertyNameInput = node.querySelector('.property-name-input');
                    const templateInput = node.querySelector('.template-input');
                    
                    if (propertyNameInput) block.propertyName = propertyNameInput.value;
                    if (templateInput) block.template = templateInput.value;
                } else {
                    const textInput = node.querySelector('input[type="text"]');
                    const text = textInput ? textInput.value : '';
                    
                    const meta = getFieldMeta(field);
                    if (text && (!meta || !meta.textless)) {
                        block.text = text;
                    }
                }
                data.push(block);
            });
            hidden.value = JSON.stringify(data);
        }

        try {
            if (hidden.value) {
                const initial = JSON.parse(hidden.value);
                if (Array.isArray(initial)) {
                    canvas.innerHTML = '';
                    initial.forEach(function(b){ canvas.appendChild(makeCanvasBlock(b)); });
                }
            }
        } catch (e) { /* ignore */ }

        paletteBlocks.forEach(function(block){
            block.addEventListener('dragstart', function(e){
                e.dataTransfer.setData('application/json', JSON.stringify({
                    type: block.getAttribute('data-type'),
                    field: block.getAttribute('data-field') || undefined
                }));
            });
        });

        canvas.addEventListener('dragover', function(e){ e.preventDefault(); });
        canvas.addEventListener('drop', function(e){
            e.preventDefault();
            try {
                const data = JSON.parse(e.dataTransfer.getData('application/json'));
                const el = makeCanvasBlock({ type: data.type, field: data.field ? String(data.field).toLowerCase() : undefined, text: '' });
                canvas.appendChild(el);
                serialize();
            } catch (_) { /* ignore */ }
        });

        if (typeof $(canvas).sortable === 'function') {
            $(canvas).sortable({ handle: '.drag-handle', update: serialize });
        }
    }


    let metricsUpdateInterval;
    
    function updateUtilityMetrics() {
        makeAjaxCall('agile_get_utility_metrics', { nonce: agileAjax.utility_metrics_nonce }, {
            success: function(response) {
                if (response && response.update_status !== undefined) {
                    $('#agile_update_status').text(response.update_status);
                    $('#agile_time_since_refresh_scheduled').text(response.time_since_refresh_scheduled || 'Never');
                    $('#agile_time_since_post_scheduled').text(response.time_since_post_scheduled || 'N/A');
                    if (response.first_post_date) {
                        $('#agile_processing_started_date').text(response.first_post_date);
                    }
                    $('#agile_time_since_chunk_started').text(response.time_since_chunk_started || 'N/A');
                    if (response.total_processing_start_date) {
                        $('#agile_total_processing_started_date').text(response.total_processing_start_date);
                    }
                    $('#agile_time_since_post_began').text(response.time_since_post_began || 'N/A');
                    if (response.last_post_date) {
                        $('#agile_completed_at_date').text(response.last_post_date);
                    }
                    $('#agile_time_since_post_finish').text(response.time_since_post_finish || 'N/A');
                    
                    if (response.last_runtime_minutes) {
                        $('#agile_last_runtime').text(response.last_runtime_minutes);
                    } else if (response.last_runtime) {
                        $('#agile_last_runtime').text(response.last_runtime + ' sec');
                    }
                    
                    $('#agile_post_count_created').text(response.post_count_created || 0);
                    $('#agile_post_count_updated').text(response.post_count_updated || 0);
                    $('#agile_post_count_deleted').text(response.post_count_deleted || 0);
                    
                    if (response.total_processed !== undefined) {
                        $('#agile_total_processed').text(response.total_processed || 0);
                    }
                    if (response.data_freshness) {
                        $('#agile_data_freshness').text(response.data_freshness);
                    }
                    if (response.next_refresh) {
                        $('#agile_next_refresh').text(response.next_refresh);
                    }
                    
                    let statusColor = '#666';
                    let statusBg = '#f5f5f5';
                    let status = (response.update_status || '').toLowerCase();
                    if (status === 'idle') {
                        statusColor = '#28a745';
                        statusBg = '#d4edda';
                    } else if (status.indexOf('processing') !== -1 || status.indexOf('running') !== -1) {
                        statusColor = '#007bff';
                        statusBg = '#cce5ff';
                    } else if (status.indexOf('error') !== -1 || status.indexOf('failed') !== -1) {
                        statusColor = '#dc3545';
                        statusBg = '#f8d7da';
                    }
                    $('#agile_update_status').css({
                        'background-color': statusBg,
                        'color': statusColor
                    });
                }
            },
            error: function(xhr, status, error) {
                console.log('Error updating utility metrics:', error);
            }
        });
    }
    
    function startMetricsUpdates() {
        if (metricsUpdateInterval) {
            clearInterval(metricsUpdateInterval);
        }
        updateUtilityMetrics();
        metricsUpdateInterval = setInterval(updateUtilityMetrics, 1000);
    }
    
    function stopMetricsUpdates() {
        if (metricsUpdateInterval) {
            clearInterval(metricsUpdateInterval);
            metricsUpdateInterval = null;
        }
    }

    function checkUtilityTab() {
        const activeTab = new URLSearchParams(window.location.search).get("tab");
        if (activeTab === 'utility') {
            startMetricsUpdates();
        } else {
            stopMetricsUpdates();
        }
    }


    jQuery(document).ready(function ($) {
        if (window.location.pathname.endsWith('admin.php') && window.location.search.includes('page=agile')) {
            if (!window.location.search.includes('tab=')) {
                let url = new URL(window.location.href);
                url.searchParams.set('tab', 'credentials');
                window.location.href = url.toString();
            }

            const tab = new URLSearchParams(window.location.search).get("tab");

            switch (tab) {
                case 'credentials':
                    initCredentialsTab();
                    break;
                case 'style':
                    initStyleTab();
                    break;
                case 'theme':
                    initThemeTab();
                    break;
                case 'content':
                    initContentTab();
                    break;
                case 'utility':
                    initUtilityTab();
                    break;
                case 'advanced':
                    initAdvancedTab();
                    break;
            }
        }

        initThemeIntegrationHandler();
        checkUtilityTab();
        organizeConfigTab();
        organizeAdvancedTab();
        organizeCredentialsTab();
        organizeThemeMappingFields();
        markThemeCardRows();
        
        let currentTab = new URLSearchParams(window.location.search).get('tab');
        if (currentTab === 'config') {
            initWidgetToggle();
        }
        if (currentTab === 'credentials') {
            initCredentialsExplainers();
        }

        $('.nav-tab').on('click', function() {
            setTimeout(function() {
                initThemeIntegrationHandler();
                checkUtilityTab();
                organizeConfigTab();
                organizeAdvancedTab();
                organizeCredentialsTab();
                organizeThemeMappingFields();
                markThemeCardRows();
                
                let activeTab = new URLSearchParams(window.location.search).get('tab');
                if (activeTab === 'config') {
                    initWidgetToggle();
                }
                if (activeTab === 'credentials') {
                    initCredentialsExplainers();
                    initComingSoonFeedToggle();
                }
            }, 200);
        });
        
        setTimeout(function() {
            initThemeIntegrationHandler();
            organizeConfigTab();
            organizeAdvancedTab();
            organizeCredentialsTab();
            organizeThemeMappingFields();
            markThemeCardRows();
            
            let delayedTab = new URLSearchParams(window.location.search).get('tab');
            if (delayedTab === 'config') {
                initWidgetToggle();
            }
            if (delayedTab === 'credentials') {
                initCredentialsExplainers();
                initComingSoonFeedToggle();
            }
        }, 500);
    });
    
    $(document).ready(function() {
        initCustomFields();
        initTermFields();
        initPasswordToggle();
        initThemeIntegrationHandler();
    });

    $(window).on('beforeunload', function() {
        stopMetricsUpdates();
    });

})(jQuery);
