<?php

/**
 * The options-menu-specific functionality of the plugin.
 *
 * @link       http://example.com
 * @since      1.0.0
 *
 * @package    agile_tix
 * @subpackage agile_tix/admin/includes
 */

/**
 * The admin-specific functionality of the plugin.
 *
 * Defines the plugin name, version, and two examples hooks for how to
 * enqueue the admin-specific stylesheet and JavaScript.
 *
 * @package    agile_tix
 * @subpackage agile_tix/admin/includes
 * @author     AgileTix
 */

class agile_tix_Options
{
    /**
     * The ID of this plugin.
     *
     * @since    1.0.0
     * @access   private
     * @var      string    $agile_tix    The ID of this plugin.
     */
    private $agile_tix;

    /**
     * The version of this plugin.
     *
     * @since    1.0.0
     * @access   private
     * @var      string    $version    The current version of this plugin.
     */
    private $version;

    /**
     * Initialize the class and set its properties.
     *
     * @since    1.0.0
     * @param      string    $agile_tix       The name of this plugin.
     * @param      string    $version    The version of this plugin.
     */
    public function __construct($agile_tix, $version)
    {
        $this->agile_tix = $agile_tix;
        $this->version = $version;
    }

    function agile_options_page()
    {
        add_menu_page(
            'Settings',
            'AgileTix Options',
            'manage_options',
            'agile',
            'agile_tix_Options::agile_html_tabs',
        );
    }

    /**
     * This generates the basic tab layout for out settings page
     * The tabs are: Credentials, Config, Utility, Style, Content, Theme
     * @return void
     */
    static function agile_html_tabs()
    {
        ?>
        <div class="wrap">
            <div style="display: flex; align-items: center; gap: 10px;">
                <img
                    src="<?php echo plugin_dir_url(__FILE__) ?>../assets/AgileTix_300ppi_Logo.png"
                    style="height: 32px;"
                    alt="AgileTix Logo" />
                <h1 style="margin: 0;"><?php echo get_admin_page_title(); ?></h1>
            </div>

            <?php
            $tabs = array(
                'credentials' => 'Credentials',
                'config' => 'Config',
                'utility' => 'Utility',
                'style' => 'Style',
                'content' => 'Content',
                'theme' => 'Theme',
                'advanced' => 'Advanced',
            );


            if (!isset($_GET['tab'])) {
                // Redirect handled by JavaScript in agile-ticketing-admin.js
                // This prevents the page from rendering without a tab parameter
                ?>
                <div id="agile-tab-redirect-placeholder"></div>
                <?php
                return;
            }

            $default_tab = array_key_first($tabs);
            $current_tab = isset($_GET['tab']) && isset($tabs[$_GET['tab']]) ? $_GET['tab'] : $default_tab;

            // Redirect if no tab parameter is present
            if (!isset($_GET['tab'])) {
                $redirect_url = add_query_arg('tab', $default_tab, admin_url('admin.php?page=agile'));
                wp_redirect($redirect_url);
                exit;
            }

            ?>
            <div>
                <form method="post" action="options.php" style="display: flex; width:100%">
                    <div
                        <?php if ($current_tab == 'theme' || $current_tab == 'content') {
                            echo ('style="width: 50%;"');
                        } ?>>
                        <nav class="nav-tab-wrapper">
                            <?php
                            foreach ($tabs as $tab => $name) {
                                $current = $tab === $current_tab ? ' nav-tab-active' : '';
                                $url = add_query_arg(array('page' => 'agile', 'tab' => $tab), '');
                                echo "<a class=\"nav-tab{$current}\" href=\"{$url}\">{$name}</a>";
                            }
                            ?>
                        </nav>
                        <?php
                        settings_fields("agile_options_{$current_tab}_settings");
                        do_settings_sections("agile_options_{$current_tab}");

                        if ($current_tab != "utility") {
                            submit_button();
                        }

                        if ($current_tab == 'credentials') {
                            agile_tix_Options::agile_credentials_activate_btn();
                        }

                        ?>
                    </div>

                    <?php
                    if ($current_tab == 'theme' || $current_tab == 'content') {
                        ?>
                        <div style="width: 50%; padding-left: 20px;">
                            <script src="<?php echo plugin_dir_url(__FILE__) ?>../AceCodeEditor/src-min-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
                            <div class="ace-editor-container" id="ace-editor-container" style="position: relative; width: 100%; max-width: 800px;">
                                <div class="ace-editor-tab" id="ace-editor-tab">example.JSON</div>
                                <div id="json_editor" style="height: 1350px; width: 100%; border: 1px solid #ddd;"></div>
                            </div>
                        </div>
                        <?php
                    }
                    ?>
                </form>
                <?php
                if ($current_tab == 'utility') {
                    $credsAreValid = get_option('agile_field_credentials_are_valid') ?? '';
                    $disabledText = $credsAreValid ? '' : 'disabled';

                    if (!$credsAreValid) {
                        echo ('<p>We were unable to locate any relevant data with the credentials you\'ve entered and have disabled refreshes. To refresh your posts, please ensure your credentials are correct.</p>');
                    }

                    ?>
                    <div class="agile-refresh-buttons-container">
                        <button id="ats_refresh_button_fast" class="agile-refresh-button agile-refresh-button-fast"
                            title="This will not get new data from ATS, only reformat known data unless no known data is found. If you changed your guid, you need to use the full refresh" <?php echo ($disabledText); ?>>
                            <svg class="agile-refresh-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                <path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z" fill="currentColor"/>
                            </svg>
                            <span class="agile-refresh-text">Fast Refresh ATS Data</span>
                            <span class="agile-refresh-subtitle">Quick reformat of existing data</span>
                        </button>

                        <button id="ats_refresh_button_slow" class="agile-refresh-button agile-refresh-button-full"
                            title="This will collect new data from ATS and recreate/update all posts" <?php echo ($disabledText); ?>>
                            <svg class="agile-refresh-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                <path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z" fill="currentColor"/>
                            </svg>
                            <span class="agile-refresh-text">Full Refresh ATS Data</span>
                            <span class="agile-refresh-subtitle">Complete data sync from ATS</span>
                        </button>
                    </div>
                    <?php
                }
                ?>

            </div>
        </div>
        <?php
    }

    //TODO: break this into smaller funcs for each seperate tab
    //This creates the settings used to manipulate data and the setting fields to populate them
    function agile_register_settings_tabs()
    {
        $textFieldArgs = array(
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default' => NULL,
        );

        $page_slug = 'agile_options_credentials';
        $option_group = 'agile_options_credentials_settings';
        //These settings are not directly visible to the user, but influence information presented to them
        //hidden api call fields
        register_setting($option_group, 'agile_field_apiURL', array(
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default' => '',
        ));

        register_setting($option_group, 'agile_field_webURL', array(
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default' => '',
        ));

        //used for forcing content settings to be initialized on first install and then settings are allowed to persist
        //is_not seems a bit funny, but this is also not initilized to any value, thus defaults to false as the useless default would suggest
        register_setting($option_group, 'agile_is_not_first_install', array(
            'type' => 'boolean',
            'default' => false,
        ));

        //utility display fields
        register_setting($option_group, 'agile_field_utility_last_known_runtime');
        register_setting($option_group, 'agile_field_utility_last_post_scheduled_start');
        register_setting($option_group, 'agile_field_utility_last_post_update_start');
        register_setting($option_group, 'agile_field_utility_total_processing_start');
        register_setting($option_group, 'agile_field_utility_last_post_update');
        register_setting($option_group, 'agile_field_utility_last_post_count_created', array('default' => 0));
        register_setting($option_group, 'agile_field_utility_last_post_count_updated', array('default' => 0));
        register_setting($option_group, 'agile_field_utility_last_post_count_deleated', array('default' => 0));
        register_setting($option_group, 'agile_field_utility_update_status', array('default' => 'Idle'));
        //End hidden settings



        //Credentials tab
        add_settings_section(
            $option_group,
            __("Credentials", 'agile'),
            'agile_tix_Options::agile_section_credentials_callback',
            $page_slug
        );

        register_setting($option_group, 'agile_field_domain', $textFieldArgs);
        add_settings_field(
            'agile_field_domain',
            __('Domain: ', 'agile'),
            'agile_tix_Options::agile_field_domain_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_domain',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );

        register_setting($option_group, 'agile_field_corpOrgID', $textFieldArgs);
        add_settings_field(
            'agile_field_corpOrgID',
            __('Corp Org ID: ', 'agile'),
            'agile_tix_Options::agile_field_corpOrgID_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_corpOrgID',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );
        $corpOrgId = get_option('agile_field_corpOrgID');

        register_setting($option_group, 'agile_field_epgID', array('type' => 'string','sanitize_callback' => 'sanitize_text_field','default' => NULL));
        
        if ($corpOrgId != 10012){
            add_settings_field(
                'agile_field_epgID',
                __('Entry Point Group ID:', 'agile'),
                'agile_tix_Options::agile_field_epgID_cb',
                $page_slug,
                $option_group,
                array(
                    'label_for' => 'agile_field_epgID',
                    'class' => 'agile_row',
                    'agile_custom_data' => 'custom',
                )
            );
        }
        

        register_setting($option_group, 'agile_field_guid', array('type' => 'string','sanitize_callback' => 'sanitize_text_field','default' => NULL));
        if ($corpOrgId != 10012){
            add_settings_field(
                'agile_field_guid',
                __('GUID:', 'agile'),
                'agile_tix_Options::agile_field_guid_cb',
                $page_slug,
                $option_group,
                array(
                    'label_for' => 'agile_field_guid',
                    'class' => 'agile_row',
                    'agile_custom_data' => 'custom',
                )
            );
        }
        register_setting($option_group, 'agile_field_epgTag', array('type' => 'string','sanitize_callback' => 'sanitize_text_field','default' => NULL));
        
        if ($corpOrgId == 10012){
            add_settings_field(
                'agile_field_epgTag',
                __('EPG Tag:', 'agile'),
                'agile_tix_Options::agile_field_epgTag_cb',
                $page_slug,
                $option_group,
                array(
                    'label_for' => 'agile_field_epgTag',
                    'class' => 'agile_row',
                    'agile_custom_data' => 'custom',
                )
            );
        }
        register_setting($option_group, 'agile_field_password', array(
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default' => NULL,
        ));
        if (get_option('agile_field_password') == false) {
            //if the user doesn't have a password, spin one up
            update_option('agile_field_password', wp_generate_password(24, false, false), false);//turn off autoload
        }

        add_settings_field(
            'agile_field_password',
            __('Secret:', 'agile'),
            'agile_tix_Options::agile_field_password_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_password',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
                'default' => false
            )
        );

        register_setting($option_group, 'agile_field_webhook_is_active', array('default' => false));
        register_setting($option_group, 'agile_field_credentials_are_valid', array('default' => false));

        // Coming Soon Feed Settings
        register_setting($option_group, 'agile_field_use_coming_soon_feed', array('type' => 'boolean', 'sanitize_callback' => 'sanitize_text_field', 'default' => false));
        add_settings_field(
            'agile_field_use_coming_soon_feed',
            __('Use Coming Soon Feed:', 'agile'),
            'agile_tix_Options::agile_field_use_coming_soon_feed_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_use_coming_soon_feed',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );

        register_setting($option_group, 'agile_field_coming_soon_epgID', array('type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => NULL));
        add_settings_field(
            'agile_field_coming_soon_epgID',
            __('Coming Soon Entry Point Group ID:', 'agile'),
            'agile_tix_Options::agile_field_coming_soon_epgID_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_coming_soon_epgID',
                'class' => 'agile_row agile_coming_soon_field',
                'agile_custom_data' => 'custom',
            )
        );

        register_setting($option_group, 'agile_field_coming_soon_guid', array('type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => NULL));
        add_settings_field(
            'agile_field_coming_soon_guid',
            __('Coming Soon GUID:', 'agile'),
            'agile_tix_Options::agile_field_coming_soon_guid_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_coming_soon_guid',
                'class' => 'agile_row agile_coming_soon_field',
                'agile_custom_data' => 'custom',
            )
        );

        //config tab
        $page_slug = 'agile_options_config';
        $option_group = 'agile_options_config_settings';

        add_settings_section(
            $option_group,
            __("Config", 'agile'),
            'agile_tix_Options::agile_section_config_callback',
            $page_slug
        );

        register_setting($option_group, 'agile_field_comment_status', array('show_in_rest' => true, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => 'closed'));
        add_settings_field(
            'agile_field_comment_status',
            __('Comments: ', 'agile'),
            'agile_tix_Options::agile_field_comment_status_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_domain',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );


        register_setting($option_group, 'agile_field_post_status', array('autoload' => 'true', 'show_in_rest' => true, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => 'publish'));
        add_settings_field(
            'agile_field_post_status',
            __('Post Status:', 'agile'),
            'agile_tix_Options::agile_field_post_status_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_post_status',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );

        register_setting($option_group, 'agile_field_auto_cull', array('show_in_rest' => true, 'type' => 'boolean', 'sanitize_callback' => 'sanitize_text_field', 'default' => '1'));
        add_settings_field(
            'agile_field_auto_cull',
            __('Automatically Cull Outdated Posts:', 'agile'),
            'agile_tix_Options::agile_field_auto_cull_toggle',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_auto_cull',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );


        register_setting($option_group, 'agile_field_widget_active', array('show_in_rest' => true, 'type' => 'boolean', 'sanitize_callback' => 'sanitize_text_field', 'default' => '0'));
        add_settings_field(
            'agile_field_widget_active',
            __('Integration Widget Enabled:', 'agile'),
            'agile_tix_Options::agile_field_widget_active_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_widget_active',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );

        register_setting($option_group, 'agile_field_widget_target', array('show_in_rest' => true, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field'/*, 'default' => 'agile_frame'*/));
        add_settings_field(
            'agile_field_widget_target',
            __('Integration Widget Target:', 'agile'),
            'agile_tix_Options::agile_field_widget_target_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_widget_target',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );


        register_setting($option_group, 'agile_field_widget_mode', array('show_in_rest' => true, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field'/*, 'default' => 'popup'*/));
        add_settings_field(
            'agile_field_widget_mode',
            __('Integration Widget Mode:', 'agile'),
            'agile_tix_Options::agile_field_widget_mode_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_widget_mode',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );


        //Utility tab
        $page_slug = 'agile_options_utility';
        $option_group = 'agile_options_utility_settings';

        add_settings_section(
            $option_group,
            __("Utility", 'agile'),
            'agile_tix_Options::agile_section_utility_callback',
            $page_slug
        );


        //style tab
        $page_slug = 'agile_options_style';
        $option_group = 'agile_options_style_settings';
        add_settings_section(
            $option_group,
            __("Style", 'agile'),
            'agile_tix_Options::agile_section_style_callback',
            $page_slug
        );

        register_setting(
            $option_group,
            'agile_field_style_editor',
            [
                'type' => 'string',
                'sanitize_callback' => null,
                'default' => '/*Insert your public facing css here. This will not be visible on your admin panel*/',
            ]
        );

        add_settings_field(
            'agile_field_style_editor',
            __('', 'agile'),
            'agile_tix_Options::agile_field_style_editor_CB',
            $page_slug,
            $option_group,
            array(
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );


        //Content tab
        $page_slug = 'agile_options_content';
        $option_group = 'agile_options_content_settings';

        register_setting($option_group, 'agile_options_content_settings', array(
            'type' => 'array',
            'sanitize_callback' => function ($input) {
                $sanitized_input = [];
                if (isset($input['layout_json'])) {
                    $decoded = json_decode(wp_unslash($input['layout_json']), true);
                    if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
                        foreach ($decoded as &$block) {
                            if (isset($block['type'])) { $block['type'] = sanitize_key($block['type']); }
                            if (isset($block['field'])) { $block['field'] = sanitize_key($block['field']); }
                            if (isset($block['text'])) { $block['text'] = sanitize_text_field($block['text']); }
                        }
                        $sanitized_input['layout_json'] = wp_json_encode($decoded);
                    }
                }
                return $sanitized_input;
            },
        ));

        // Legacy content field registrations removed; using layout_json exclusively
        /*
        if (get_option('agile_is_not_first_install') == false) {
            agile_tix::agile_tix_log_event("agile_is_not_first_install == !");
            //TODO: keep on eye on this moving from staging to real. The option should be copied over and everything SHOULD work, but...
            //default is default save behavior, not default value, force update on these values to match the presentation

            update_option('agile_options_content_settings', array('field_order' => 'agile_field_content_distributor,agile_field_content_infoLink,agile_field_content_duration,agile_field_content_full_description,agile_field_content_release_year,agile_field_content_rating,agile_field_content_director,agile_field_content_cast,agile_field_content_genre,agile_field_content_renderLocation'));
            
            //update the content fields themselves
            foreach ($contentDefaults as $defaultField) {
                update_option($defaultField[0], $defaultField[2]);
            }
            update_option('agile_field_content_infoLink', 'Learn More');

            //hopefully never run this snippet again

            agile_tix::agile_tix_log_event("get_option('agile_is_not_first_install') = " . get_option('agile_is_not_first_install'));
            update_option('agile_is_not_first_install', true);
            agile_tix::agile_tix_log_event("get_option('agile_is_not_first_install') = " . get_option('agile_is_not_first_install'));
        }
        */
        register_setting($option_group, 'agile_field_render_carousel', array('show_in_rest' => false, 'type' => 'boolean', 'default' => '1'));
        register_setting($option_group, 'agile_field_carousel_auto_scroll', array('show_in_rest' => false, 'type' => 'boolean', 'default' => '1'));
        register_setting($option_group, 'agile_field_carousel_auto_scroll_interval', array('show_in_rest' => false, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '5000'));
        register_setting($option_group, 'agile_field_carousel_pause_on_hover', array('show_in_rest' => false, 'type' => 'boolean', 'sanitize_callback' => 'sanitize_text_field', 'default' => '1'));

        register_setting($option_group, 'agile_field_carousel_size', array('show_in_rest' => false, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => 'auto'));

        //register_setting($option_group, 'agile_field_carousel_aspect_ratio', array('show_in_rest' => false, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '16/9'));


        /*
         * register_setting($option_group, 'agile_field_widget_target', array('show_in_rest' => true, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => 'agile_frame'));
        add_settings_field(
            'agile_field_widget_target',
            __('Integration Widget Target:', 'agile'),
            'agile_tix_Options::agile_field_widget_target_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_widget_target',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );*/

        
        add_settings_section(
            $option_group,
            __("Post Content", 'agile'),
            'agile_tix_Options::agile_section_content_callback',
            $page_slug,
        );


        //Theme support tab
        $page_slug = 'agile_options_theme';
        $option_group = 'agile_options_theme_settings';

        add_settings_section(
            $option_group,
            __("Theme", 'agile'),
            'agile_tix_Options::agile_section_theme_callback',
            $page_slug
        );

        register_setting($option_group, 'agile_field_config_integration_type', array(
            'show_in_rest' => true,
            'type' => 'string',
            'sanitize_callback' => function ($value) {
                $allowed_values = array('none', 'event_champ', 'amy_movie', 'custom');
                return in_array($value, $allowed_values) ? $value : 'none';
            },
            'default' => NULL,
        ));
        add_settings_field(
            'agile_field_config_integration_type',
            __('Theme Integration:', 'agile'),
            'agile_tix_Options::agile_field_config_integration_type_CB',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_config_integration_type',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )

        );

        add_settings_section(
            $option_group,
            __("Theme", 'agile'),
            function () {
                ?>
            <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 <?php agile_tix_Options::agile_field_explainer("agile_mapping_fields_explainer"); ?></h3>
                </div>
                <div class="agile-theme-mapping-section">
                    <p id="agile_mapping_subheader" class="agile-theme-mapping-intro"><em>Not using one of our supported themes (EventChamp, AmyMovie)?</em> No sweat, just select custom and input what post type you're using and how to map your data.</p>
                    <div id="agile_mapping_fields_explainer_body" class="agile-info-box">
                        <h4 class="agile-info-box-title">Mapping Fields Overview</h4>
                        <p class="agile-info-box-text">
                            The Mapping Fields section allows you to configure how your event data maps to WordPress when using the "Custom" theme integration option. This gives you complete control over how your events are stored and displayed.
                        </p>
                        <p class="agile-info-box-subtitle">What You Can Configure:</p>
                        <ul class="agile-info-box-list">
                            <li><strong>Post Type:</strong> Select which WordPress post type will receive your event data (e.g., "post", "event", "movie", or a custom post type)</li>
                            <li><strong>Template:</strong> Choose a template file that will be used to display your events on the frontend</li>
                            <li><strong>Custom Fields:</strong> Map event data fields to WordPress custom fields (meta-data) that your theme can use</li>
                            <li><strong>Post Terms:</strong> Map event data to WordPress taxonomies (categories, tags, or custom taxonomies) for organizing your events</li>
                            <li><strong>Function Editor:</strong> Create custom PHP functions to transform and format your data before it's saved</li>
                        </ul>
                        <p class="agile-info-box-subtitle">Getting Started:</p>
                        <p class="agile-info-box-text" style="margin-bottom: 0;">
                            First, select "Custom" from the Theme Integration dropdown above. Then configure each section below based on your theme's requirements. Use the JSON preview on the right to see the structure of your event data and identify the exact field paths you need to map.
                        </p>
                    </div>
                </div>
                <div class="agile-theme-mapping-fields"></div>
            </div>
            <?php
            },
            $page_slug
        );


        register_setting(
            $option_group,
            'agile_field_theme_custom_map_post_type',
            array(
                'type' => 'string',
                'sanitize_callback' => function ($value) {
                    $postTypeArgs = array(
                        'public' => true,
                        //'_builtin' => false
                    );

                    $output = 'names';
                    $operator = 'and';

                    $post_types = get_post_types($postTypeArgs, $output, $operator);

                    return in_array($value, $post_types) ? $value : 'Select a Post Type(None)';
                },
                'default' => NULL
            )
        );
        add_settings_field(
            'agile_field_theme_custom_map_post_type',
            __('Post Type: ', 'agile'),
            'agile_tix_Options::agile_field_theme_custom_map_post_type_CB',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_theme_custom_map_post_type',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );

        register_setting($option_group, 'agile_field_theme_custom_map_template', array(
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            //old sanitize callback, for some reason get_page_templates renders different values on load and save
            /*function ($value) {
                $templates = get_page_templates();
                return isset($templates[$value]) ? $value : '';
            }*/
            'default' => NULL
        ));
        add_settings_field(
            'agile_field_theme_custom_map_template',
            __('Template: ', 'agile'),
            'agile_tix_Options::agile_field_theme_custom_map_template_CB',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_theme_custom_map_template',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );


        register_setting($option_group, 'agile_custom_fields', array(
            'sanitize_callback' => function ($input) {
                $sanitized_fields = [];

                if (is_array($input)) {
                    foreach ($input as $field) {
                        if (!empty($field[0]) && !empty($field[1])) {
                            $sanitized_fields[] = [
                                sanitize_text_field($field[0]),
                                sanitize_text_field($field[1]),
                            ];
                        }
                    }
                }

                return $sanitized_fields;
            }
        ));
        add_settings_field(
            'agile_custom_fields',
            __('', 'agile'),
            'agile_tix_Options::agile_custom_fields_CB',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_custom_fields',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );

        register_setting($option_group, 'agile_term_fields', array(
            'sanitize_callback' => function ($input) {
                $sanitized_fields = [];

                if (is_array($input)) {
                    foreach ($input as $field) {
                        if (!empty($field[0]) && !empty($field[1])) {
                            $sanitized_fields[] = [
                                sanitize_text_field($field[0]),
                                sanitize_text_field($field[1]),
                            ];
                        }
                    }
                }

                return $sanitized_fields;
            }
        ));
        add_settings_field(
            'agile_term_fields',
            __('', 'agile'),
            'agile_tix_Options::agile_term_fields_CB',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_term_fields',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );


        // Default to empty - examples are now in the explainer section
        register_setting($option_group, 'agile_field_theme_custom_code', array('default' => ''));
        add_settings_field(
            'agile_field_theme_custom_code',
            __('', 'agile'),
            'agile_tix_Options::agile_field_theme_custom_code_CB',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_theme_custom_code',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );

        


        $page_slug = 'agile_options_advanced';
        $option_group = 'agile_options_advanced_settings';

        add_settings_section(
            $option_group,
            __("Advanced", 'agile'),
            'agile_tix_Options::agile_section_advanced_callback',
            $page_slug
        );

        register_setting($option_group, 'agile_field_actSched_batch_size', array('show_in_rest' => false, 'type' => 'number', 'sanitize_callback' => 'sanitize_text_field', 'default' => 25 ));
        add_settings_field(
            'agile_field_actSched_batch_size',
            __('Action Scheduler - Batch Size: ', 'agile'),
            'agile_tix_Options::agile_field_actSched_batch_size_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_actSched_batch_size',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );


        register_setting($option_group, 'agile_field_actSched_concurrentBatches', array('show_in_rest' => false, 'type' => 'number', 'sanitize_callback' => 'sanitize_text_field', 'default' => 1));
        add_settings_field(
            'agile_field_actSched_concurrentBatches',
            __('Action Scheduler - Concurrent Batches: ', 'agile'),
            'agile_tix_Options::agile_field_actSched_concurrentBatches_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_field_actSched_concurrentBatches',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );


        register_setting($option_group, 'agile_chunk_size', array('show_in_rest' => false, 'type' => 'number', 'sanitize_callback' => 'sanitize_text_field', 'default' => 10));
        add_settings_field(
            'agile_chunk_size',
            __('Action Scheduler - Chunk Size: ', 'agile'),
            'agile_tix_Options::agile_chunk_size_cb',
            $page_slug,
            $option_group,
            array(
                'label_for' => 'agile_chunk_size',
                'class' => 'agile_row',
                'agile_custom_data' => 'custom',
            )
        );


    }

    //#region settings fields callbacks
    static function agile_field_domain_cb($args)
    {

        $options = get_option('agile_field_domain');

        ?>
        <input type="text"
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_field_domain"
            value="<?php echo isset($options) ? esc_attr($options) : ''; ?>"
            title="The domain you sign into in main agile system"
            class="regular-text"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
            required />

        <?php agile_tix_Options::agile_field_explainer("agile_domain_explainer"); ?>
        <div id="agile_domain_explainer_body" class="agile-info-box">
            <p class="agile-info-box-text">Your domain signifies what larger organization you represent and can be found as the 3rd option of any sign in form.</p>
            <img
                src="<?php echo plugin_dir_url(__FILE__) ?>../assets/domainExample.png"
                alt="Domain Example"
                class="agile-info-box-image" />
        </div>
        <?php
    }

    static function agile_field_corpOrgID_cb($args)
    {

        $option = get_option('agile_field_corpOrgID');

        ?>
        <input type="text"
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_field_corpOrgID"
            value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
            class="regular-text"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
            required />

        <?php agile_tix_Options::agile_field_explainer("agile_corpOrgID_explainer"); ?>
        <div id="agile_corpOrgID_explainer_body" class="agile-info-box">
            <p class="agile-info-box-text">Your Corp Org ID signifies which organization inside your domain you represent and can be found at the top of your corp org's property page.</p>
            <img
                src="<?php echo plugin_dir_url(__FILE__) ?>../assets/corpOrgIDExample.png"
                alt="Corp Org ID Example"
                class="agile-info-box-image" />
        </div>

        <?php

    }

    static function agile_field_epgID_cb($args)
    {
        $option = get_option('agile_field_epgID');

            ?>
            <input type="text"
                id="<?php echo esc_attr($args['label_for']); ?>"
                name="agile_field_epgID"
                value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
                title="The entry point group ID for the entry point you want to use"
                class="regular-text"
                data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
                required />


            <?php agile_tix_Options::agile_field_explainer("agile_epgID_explainer"); ?>
            <div id="agile_epgID_explainer_body" class="agile-info-box">
                <p class="agile-info-box-text">Your Entry Point Group ID signifies entry point group you would like your site to pull from and can be found at the top of your entry point group property page.</p>
                <img
                    src="<?php echo plugin_dir_url(__FILE__) ?>../assets/epgIDExample.png"
                    alt="EPG ID Example"
                    class="agile-info-box-image" />
            </div>
            <?php
        

        
    }

    static function agile_field_guid_cb($args)
    {
        $option = get_option('agile_field_guid');

            ?>
            <input type="text"
                id="<?php echo esc_attr($args['label_for']); ?>"
                name="agile_field_guid"
                value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
                title="The GUID for the entry point you want to use. Can be found in the URL for your desired entry point. Do not include the trailing &"
                class="regular-text"
                data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
                required />

            <?php agile_tix_Options::agile_field_explainer("agile_guid_explainer"); ?>
            <div id="agile_guid_explainer_body" class="agile-info-box">
                <p class="agile-info-box-text">Your GUID signifies which entry point you would like to use and can be found in your entry point's URL. <strong>This is not your entry point group's GUID, this is unique GUID to your specific entry point</strong></p>
                <img
                    src="<?php echo plugin_dir_url(__FILE__) ?>../assets/guidExample.png"
                    alt="GUID Example"
                    class="agile-info-box-image" />
            </div>

            <?php
    }

    static function agile_field_epgTag_cb($args){
        $option = get_option('agile_field_epgTag');

        ?>
        <input type="text"
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_field_epgTag"
            value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
            title="The tag for the entry point group you want to use. Do not include the trailing &"
            class="regular-text"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
            required />
        <?php
    }

    static function agile_field_use_coming_soon_feed_cb($args)
    {
        $option = get_option('agile_field_use_coming_soon_feed');
        ?>
        <label for="<?php echo esc_attr($args['label_for']); ?>" class="agile_switch">
            <input type="checkbox"
                id="<?php echo esc_attr($args['label_for']); ?>"
                data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
                name="agile_field_use_coming_soon_feed"
                title="Enable Coming Soon Feed"
                value="1" <?php checked($option, 1); ?> />
            <span class="agile_slider"></span>
        </label>
        <p class="description">Enable this to configure a separate feed for coming soon events. These events will contain a "ComingSoonDate" field.</p>
        <?php
    }

    static function agile_field_coming_soon_guid_cb($args)
    {
        $option = get_option('agile_field_coming_soon_guid');
        $useComingSoon = get_option('agile_field_use_coming_soon_feed');
        ?>
        <input type="text"
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_field_coming_soon_guid"
            value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
            title="The GUID for the coming soon feed entry point. Can be found in the URL for your desired entry point. Do not include the trailing &"
            class="regular-text"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
            <?php echo $useComingSoon ? 'required' : ''; ?> />
        <div id="agile_coming_soon_guid_explainer_body" class="agile-info-box">
            <p class="agile-info-box-text">Your Coming Soon GUID signifies which entry point you would like to use for the coming soon feed. This is unique to your specific entry point.</p>
        </div>
        <?php
    }

    static function agile_field_coming_soon_epgID_cb($args)
    {
        $option = get_option('agile_field_coming_soon_epgID');
        $useComingSoon = get_option('agile_field_use_coming_soon_feed');
        ?>
        <input type="text"
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_field_coming_soon_epgID"
            value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
            title="The Entry Point Group ID for the coming soon feed (optional)"
            class="regular-text"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
            <?php echo $useComingSoon ? 'required' : ''; ?> />
        <?php
    }

    static function agile_field_appKey_cb($args)
    {

        $option = get_option('agile_field_appKey');

        ?>
        <input type="text"
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_field_appKey"
            value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
            title="A pre-defined appkey for this application."
            class="regular-text"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
            required />
        <?php
    }

    static function agile_field_userKey_cb($args)
    {

        $option = get_option('agile_field_userKey');

        ?>
        <input type="text"
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_field_userKey"
            value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
            title="A pre-defined user key for the user installing this plugin."
            class="regular-text"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
            required />
        <?php
    }

    static function agile_field_password_cb($args)
    {
        $option = get_option('agile_field_password');

        ?>
        <div class="agile-password-input-wrapper">
            <input type="password"
                id="<?php echo esc_attr($args['label_for']); ?>"
                name="agile_field_password"
                value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
                title="An arbitrary secret used for security. Predefined for you, but changes can be made"
                class="regular-text agile-password-input"
                data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
                required />
            <svg id="togglePassword" class="agile-password-toggle" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path 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" fill="currentColor"></path>
            </svg>
        </div>
        <p class="description">Preconfigured on installation. You are free to save this for your own records, but no input is required.</p>
        <?php
    }

    static function agile_field_comment_status_cb($args)
    {
        $option = get_option('agile_field_comment_status');
        ?>
        <div class="agile-config-radio-group">
            <div class="agile-config-radio-option">
                <input type="radio" id="agile_field_comment_status_closed" name="agile_field_comment_status" value="closed" <?php checked($option, 'closed'); ?> />
                <label for="agile_field_comment_status_closed"><?php _e('Closed', 'agile'); ?></label>
            </div>
            <div class="agile-config-radio-option">
                <input type="radio" id="agile_field_comment_status_open" name="agile_field_comment_status" value="open" <?php checked($option, 'open'); ?> />
                <label for="agile_field_comment_status_open"><?php _e('Open', 'agile'); ?></label>
            </div>
        </div>
        <?php
    }

    static function agile_field_post_status_cb($args)
    {
        $option = get_option('agile_field_post_status');
        ?>
        <div class="agile-config-radio-group">
            <div class="agile-config-radio-option">
                <input type="radio" id="agile_field_post_status_publish" name="agile_field_post_status" value="publish" <?php checked($option, 'publish'); ?> />
                <label for="agile_field_post_status_publish"><?php _e('Publish', 'agile'); ?></label>
            </div>
            <div class="agile-config-radio-option">
                <input type="radio" id="agile_field_post_status_draft" name="agile_field_post_status" value="draft" <?php checked($option, 'draft'); ?> />
                <label for="agile_field_post_status_draft"><?php _e('Draft', 'agile'); ?></label>
            </div>
        </div>
        <?php
    }

    static function agile_field_auto_cull_toggle($args)
    {
        $option = get_option('agile_field_auto_cull');
        ?>
        <label for="<?php echo esc_attr($args['label_for']); ?>" class="agile_switch">
            <input type="checkbox"
                id="<?php echo esc_attr($args['label_for']); ?>"
                data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
                name="agile_field_auto_cull"
                title="This will permanently delete all posts and associated images not found in the latest feed. This action is irreversible."
                value="1" <?php checked($option, 1); ?> />
            <span class="agile_slider"></span>
        </label>
        <div class="agile-config-field-help">This will permanently delete all posts and associated images not found in the latest feed. This action is irreversible.</div>
        <?php
    }


    static function agile_field_widget_active_cb($args)
    {
        $option = get_option('agile_field_widget_active');
        ?>
        <label for="<?php echo esc_attr($args['label_for']); ?>" class="agile_switch">
            <input type="checkbox"
                id="<?php echo esc_attr($args['label_for']); ?>"
                data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
                name="agile_field_widget_active"
                title=""
                value="1" <?php checked($option, 1); ?> />
            <span class="agile_slider"></span>
        </label>
        <div class="agile-widget-warning">
            <i>The Integration Widget requires the use of a custom domain to function properly. If your organization doesn't have a custom domain, please reach out to your AgileTIX support representative.</i>
        </div>
        <?php
    }



    static function agile_field_widget_target_cb($args)
    {
        $current_value = get_option('agile_field_widget_target', 'none');
        ?>
        <select name="agile_field_widget_target" id="agile_field_widget_target" class="agile_row">
            <option value="none" <?php selected($current_value, 'none'); ?>>None</option>
            <option value="agile_frame" <?php selected($current_value, 'agile_frame'); ?>>Frame</option>
            <option value="agile_tab" <?php selected($current_value, 'agile_tab'); ?>>Tab</option>
            <option value="agile_window" <?php selected($current_value, 'agile_window'); ?>>Window</option>
        </select>
        <?php
    }


    static function agile_field_widget_mode_cb($args)
    {
        $current_value = get_option('agile_field_widget_mode', 'none');
        ?>
        <select name="agile_field_widget_mode" id="agile_field_widget_mode" class="agile_row">
            <option value="none" <?php selected($current_value, 'none'); ?>>None</option>
            <option value="popup" <?php selected($current_value, 'popup'); ?>>Popup</option>
            <option value="sidebar" <?php selected($current_value, 'sidebar'); ?>>Sidebar</option>
        </select>
        <?php
    }


    static function agile_section_credentials_callback($args)
    {
        ?>
        <div class="agile-credentials-section">
            <p id="<?php echo esc_attr($args['id']); ?>" class="agile-credentials-intro"><?php esc_html_e('Please enter your org\'s credentials and what entry point you would like to be imported.', 'agile'); ?></p>
        </div>
        <?php
    }

    //Should present the user with the freshness of underlying data from our API, the last time data was parsed into posts, and the runtime of the last post process
    static function agile_section_utility_callback($args)
    {
        //$timeout = get_option('_transient_timeout_agile_api_response', 0);
        //$timeOutMessage = '';
        $scheduledPost = get_option('agile_field_utility_last_post_scheduled_start');
        $firstPost = get_option('agile_field_utility_last_post_update_start');
        $totalProcessingStart = get_option('agile_field_utility_total_processing_start');
        
        if (!empty($scheduledPost)) {
            $displayDate = date('Y-m-d H:i:s', $scheduledPost);
            $timeOutMessage = $displayDate . '.';
            } else {
                $timeOutMessage = 'The show data does not exist or has already expired. (This does not mean your existing posts are affected)';
        }

        if ($scheduledPost != '') {
            $scheduledPostFormatted = human_time_diff($scheduledPost, current_time('timestamp'));
        } else {
            $scheduledPostFormatted = 'Scheduled timestamp not found';
        }

        if ($firstPost != '') {
            $firstPostFormatted = human_time_diff($firstPost, current_time('timestamp'));
        } else {
            $firstPostFormatted = 'Active processing timestamp not found';
        }
        
        if ($totalProcessingStart != '') {
            $totalProcessingStartFormatted = human_time_diff($totalProcessingStart, current_time('timestamp'));
        } else {
            $totalProcessingStartFormatted = 'Total processing timestamp not found';
        }

        $lastPost = get_option('agile_field_utility_last_post_update');
        if ($lastPost != '') {
            $lastPostFormatted = human_time_diff($lastPost, current_time('timestamp'));
        } else {
            $lastPostFormatted = 'Last post refresh timestamp not found';
        }

        $lastRuntime = get_option('agile_field_utility_last_known_runtime');
        if ($lastRuntime != '') {
            $lastRuntimeFormatted = number_format($lastRuntime, 2);
        } else {
            $lastRuntimeFormatted = 'Last runtime not found';
        }

        $updateStatus = get_option('agile_field_utility_update_status');
        $post_count_created = (int)(get_option('agile_field_utility_last_post_count_created') ?? 0);
        $post_count_updated = (int)(get_option('agile_field_utility_last_post_count_updated') ?? 0);
        $post_count_deleated = (int)(get_option('agile_field_utility_last_post_count_deleated') ?? 0);
        $webhookIsActive = get_option('agile_field_webhook_is_active') ?? false;
        
        // Calculate additional statistics
        $totalPostsProcessed = $post_count_created + $post_count_updated;
        $currentTime = current_time('timestamp');
        
        // Format dates and times with better presentation
        if (!empty($scheduledPost)) {
            $displayDate = date('Y-m-d H:i:s', $scheduledPost);
            $timeOutMessage = $displayDate;
            $scheduledPostFormatted = human_time_diff($scheduledPost, $currentTime);
            $scheduledPostAgo = $scheduledPostFormatted . ' ago';
        } else {
            $timeOutMessage = 'Never';
            $scheduledPostFormatted = 'N/A';
            $scheduledPostAgo = 'No scheduled refresh found';
        }

        if ($firstPost != '') {
            $firstPostFormatted = human_time_diff($firstPost, $currentTime);
            $firstPostAgo = $firstPostFormatted . ' ago';
            $firstPostDate = date('Y-m-d H:i:s', $firstPost);
        } else {
            $firstPostFormatted = 'N/A';
            $firstPostAgo = 'No active processing found';
            $firstPostDate = 'N/A';
        }
        
        if ($totalProcessingStart != '') {
            $totalProcessingStartFormatted = human_time_diff($totalProcessingStart, $currentTime);
            $totalProcessingStartAgo = $totalProcessingStartFormatted . ' ago';
            $totalProcessingStartDate = date('Y-m-d H:i:s', $totalProcessingStart);
        } else {
            $totalProcessingStartFormatted = 'N/A';
            $totalProcessingStartAgo = 'No total processing start found';
            $totalProcessingStartDate = 'N/A';
        }

        if ($lastPost != '') {
            $lastPostFormatted = human_time_diff($lastPost, $currentTime);
            $lastPostAgo = $lastPostFormatted . ' ago';
            $lastPostDate = date('Y-m-d H:i:s', $lastPost);
            
            // Calculate data freshness (how old is the data)
            $dataAge = $currentTime - (int)$lastPost;
            $dataAgeHours = round($dataAge / 3600, 1);
            $dataAgeFormatted = $dataAgeHours < 1 ? round($dataAge / 60, 0) . ' minutes' : $dataAgeHours . ' hours';
        } else {
            $lastPostFormatted = 'N/A';
            $lastPostAgo = 'No refresh completed yet';
            $lastPostDate = 'N/A';
            $dataAgeFormatted = 'Unknown';
        }

        if ($lastRuntime != '') {
            $lastRuntime = (float)$lastRuntime;
            $lastRuntimeFormatted = number_format($lastRuntime, 2);
            $lastRuntimeMinutes = $lastRuntime > 60 ? number_format($lastRuntime / 60, 2) . ' min' : $lastRuntimeFormatted . ' sec';
        } else {
            $lastRuntimeFormatted = 'N/A';
            $lastRuntimeMinutes = 'N/A';
        }

        // Determine status color
        $statusColor = '#666';
        $statusBg = '#f5f5f5';
        if (strtolower($updateStatus) === 'idle') {
            $statusColor = '#28a745';
            $statusBg = '#d4edda';
        } elseif (stripos($updateStatus, 'processing') !== false || stripos($updateStatus, 'running') !== false) {
            $statusColor = '#007bff';
            $statusBg = '#cce5ff';
        } elseif (stripos($updateStatus, 'error') !== false || stripos($updateStatus, 'failed') !== false) {
            $statusColor = '#dc3545';
            $statusBg = '#f8d7da';
        }

        // Calculate next scheduled refresh (15 minutes after last ping)
        $nextRefreshTime = '';
        if ($lastPost != '' && $webhookIsActive) {
            $nextRefresh = (int)$lastPost + 900; // 15 minutes = 900 seconds
            if ($nextRefresh > $currentTime) {
                $nextRefreshFormatted = human_time_diff($nextRefresh, $currentTime);
                $nextRefreshTime = 'in ' . $nextRefreshFormatted;
            } else {
                $nextRefreshTime = 'Overdue';
            }
        } elseif (!$webhookIsActive) {
            $nextRefreshTime = 'Webhook inactive';
        } else {
            $nextRefreshTime = 'N/A';
        }

        ?>

        <div id="agile-utility-output">
            <!-- Status Overview Card -->
            <div class="agile-utility-card agile-utility-card-full-width">
                <div class="agile-utility-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"/>
                    </svg>
                    <h3>System Status</h3>
                </div>
                <div class="agile-utility-status-container">
                    <div>
                        <div class="agile-utility-stat-label agile-utility-stat-label-spacing">Current Status</div>
                        <span class="agile-status-badge" id="agile_update_status" style="background-color: <?php echo esc_attr($statusBg); ?>; color: <?php echo esc_attr($statusColor); ?>;"><?php echo esc_html($updateStatus); ?></span>
                    </div>
                    <div class="agile-utility-status-item">
                        <div class="agile-utility-stat-label agile-utility-stat-label-spacing">Webhook Status</div>
                        <span class="agile-status-badge" style="background-color: <?php echo $webhookIsActive ? '#d4edda' : '#f8d7da'; ?>; color: <?php echo $webhookIsActive ? '#155724' : '#721c24'; ?>;">
                            <?php echo $webhookIsActive ? 'Active' : 'Inactive'; ?>
                        </span>
                    </div>
                    <?php if ($webhookIsActive && $lastPost != ''): ?>
                    <div class="agile-utility-status-item">
                        <div class="agile-utility-stat-label agile-utility-stat-label-spacing">Next Scheduled Refresh</div>
                        <div class="agile-utility-stat-value" id="agile_next_refresh"><?php echo esc_html($nextRefreshTime); ?></div>
                    </div>
                    <?php endif; ?>
                </div>
            </div>

            <!-- Performance Metrics -->
            <div class="agile-utility-section-title">Performance Metrics</div>
            <div class="agile-utility-grid-2">
                <div class="agile-metric-large">
                    <div class="value" id="agile_last_runtime"><?php echo esc_html($lastRuntimeMinutes); ?></div>
                    <div class="label">Last Runtime</div>
                </div>
                <div class="agile-metric-large">
                    <div class="value" id="agile_data_freshness"><?php echo esc_html($dataAgeFormatted); ?></div>
                    <div class="label">Data Freshness</div>
                    <div class="agile-stat-subtext">Time since last update</div>
                </div>
            </div>

            <!-- Last Refresh Details -->
            <div class="agile-utility-section-title">Last Refresh Details</div>
            <div class="agile-utility-container">
                <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="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"/>
                        </svg>
                        <h3>Timing Information</h3>
                    </div>
                    <div class="agile-utility-stat">
                        <span class="agile-utility-stat-label">Scheduled At</span>
                        <span class="agile-utility-stat-value" id="agile_time_since_refresh_scheduled"><?php echo esc_html($timeOutMessage); ?></span>
                    </div>
                    <div class="agile-utility-stat">
                        <span class="agile-utility-stat-label">Time Since Scheduled</span>
                        <span class="agile-utility-stat-value" id="agile_time_since_post_scheduled"><?php echo esc_html($scheduledPostAgo); ?></span>
                    </div>
                    <div class="agile-utility-stat">
                        <span class="agile-utility-stat-label">Processing Started</span>
                        <span class="agile-utility-stat-value" id="agile_processing_started_date"><?php echo esc_html($firstPostDate); ?></span>
                    </div>
                    <div class="agile-utility-stat">
                        <span class="agile-utility-stat-label">Time Since Chunk Started</span>
                        <span class="agile-utility-stat-value" id="agile_time_since_chunk_started"><?php echo esc_html($firstPostAgo); ?></span>
                    </div>
                    <div class="agile-utility-stat">
                        <span class="agile-utility-stat-label">Total Processing Started</span>
                        <span class="agile-utility-stat-value" id="agile_total_processing_started_date"><?php echo esc_html($totalProcessingStartDate); ?></span>
                    </div>
                    <div class="agile-utility-stat">
                        <span class="agile-utility-stat-label">Time Since Started</span>
                        <span class="agile-utility-stat-value" id="agile_time_since_post_began"><?php echo esc_html($totalProcessingStartAgo); ?></span>
                    </div>
                    <div class="agile-utility-stat">
                        <span class="agile-utility-stat-label">Completed At</span>
                        <span class="agile-utility-stat-value" id="agile_completed_at_date"><?php echo esc_html($lastPostDate); ?></span>
                    </div>
                    <div class="agile-utility-stat">
                        <span class="agile-utility-stat-label">Time Since Completed</span>
                        <span class="agile-utility-stat-value" id="agile_time_since_post_finish"><?php echo esc_html($lastPostAgo); ?></span>
                    </div>
                </div>

                <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="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"/>
                        </svg>
                        <h3>Post Statistics</h3>
                    </div>
                    <div class="agile-utility-stat">
                        <span class="agile-utility-stat-label">Posts Created</span>
                        <span class="agile-utility-stat-value agile-post-count-created" id="agile_post_count_created"><?php echo esc_html($post_count_created); ?></span>
                    </div>
                    <div class="agile-utility-stat">
                        <span class="agile-utility-stat-label">Posts Updated</span>
                        <span class="agile-utility-stat-value agile-post-count-updated" id="agile_post_count_updated"><?php echo esc_html($post_count_updated); ?></span>
                    </div>
                    <div class="agile-utility-stat">
                        <span class="agile-utility-stat-label">Posts Deleted</span>
                        <span class="agile-utility-stat-value agile-post-count-deleted" id="agile_post_count_deleted"><?php echo esc_html($post_count_deleated); ?></span>
                    </div>
                    <div class="agile-utility-stat agile-utility-stat-total">
                        <span class="agile-utility-stat-label agile-utility-stat-label-total">Total Processed</span>
                        <span class="agile-utility-stat-value agile-utility-stat-value-total" id="agile_total_processed"><?php echo esc_html($totalPostsProcessed); ?></span>
                    </div>
                </div>
            </div>
        </div>
        <?php
    }

    static function agile_section_style_callback($args)
    {
        ?>
        <div class="agile-style-section">
            <p id="<?php echo esc_attr($args['id']); ?>" class="agile-style-intro"><?php esc_html_e('Modify how your front-end content is styled. Use the code editor below to write custom CSS that will be applied to your public-facing pages.', 'agile'); ?></p>
        </div>
        <?php
    }

    static function agile_section_content_callback($args)
    {
        ?>
        <div class="agile-content-section">
            <div id="agl_settings_textContent_div" class="agile-content-card">
                <div class="agile-content-card-header">
                    <svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                        <path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z" fill="currentColor"/>
                    </svg>
                    <h3>Text Content</h3>
                </div>
                <p id="<?php echo esc_attr($args['id']); ?>" class="agile-content-intro">
                    <?php esc_html_e("Change how your post's text content is formatted.", 'agile'); ?> <?php agile_tix_Options::agile_field_explainer("agile_content_explainer"); ?>
                </p>
                <div id="agile_content_explainer_body" class="agile-info-box">
                    <h4 class="agile-info-box-title">How to Build Your Content Layout</h4>
                    <p class="agile-info-box-text">
                        <strong>Getting Started:</strong> Drag blocks from the palette on the left onto the canvas on the right to build your content layout. The order of blocks on the canvas determines how they appear on your event pages.
                    </p>
                    <ul class="agile-info-box-list">
                        <li><strong>Text Blocks:</strong> Add custom text that appears on every event. Click the block after adding it to edit the text.</li>
                        <li><strong>Field Blocks:</strong> Display dynamic event data (like Duration, Description, etc.). Each field has a token (shown in a badge) that gets replaced with the actual value from your event data. You can add custom text before or after the token.</li>
                        <li><strong>Textless Blocks:</strong> Some field blocks (like Location Link) are "textless" and render a preconfigured element without requiring text input. These blocks automatically display formatted content based on the event data.</li>
                        <li><strong>Custom Property Block:</strong> Display custom properties from your event data that aren't available as standard fields. See details below.</li>
                    </ul>
                    <p class="agile-info-box-subtitle">Important Requirements:</p>
                    <ul class="agile-info-box-list">
                        <li>All non-empty, non-label field blocks must contain the field's name (lowercase) in curly braces, e.g., <code>{distributor}</code> or <code>{duration}</code>. This token is what gets replaced with the actual event data.</li>
                        <li>If you don't want a value included in your content, simply leave that field blank or remove the block entirely.</li>
                        <li>Click and drag blocks on the canvas to change how fields are ordered. The order on the canvas determines how they appear on your event pages.</li>
                    </ul>
                    <p class="agile-info-box-text">
                        <strong>Styling:</strong> For ease of styling, each field inserted is given an ID in the format <code>agile_content_...</code>. You can use these IDs in your custom CSS to style individual content fields.
                    </p>
                    <p class="agile-info-box-text">
                        <strong>Tips:</strong> You can reorder blocks by dragging them on the canvas, and remove any block using the "Remove" button. Don't forget to save your settings after making changes!
                    </p>
                    <div class="agile-info-box-warning">
                        <h4 class="agile-info-box-warning-title">Using the Custom Property Block</h4>
                        <p class="agile-info-box-text">
                            The <strong>Custom Property</strong> block lets you display any custom property from your event data that isn't available as a standard field block. This is perfect for properties like ratings, genres, directors, age restrictions, or any other custom metadata your events have.
                        </p>
                        <p class="agile-info-box-subtitle">How it works:</p>
                        <ol class="agile-info-box-list">
                            <li><strong>Drag the Custom Property block</strong> onto the canvas.</li>
                            <li><strong>Enter the Property Name:</strong> Type the exact name of the custom property as it appears in your event data (e.g., "rating", "genre", "director"). This is case-sensitive and must match exactly.</li>
                            <li><strong>Create a Template:</strong> Write how you want the property to be displayed. Use <code>{propertyName}</code> as a placeholder where the actual value should appear.</li>
                        </ol>
                        <p class="agile-info-box-text">
                            <strong>Example:</strong> If your event has a custom property named "rating" with a value of "PG-13", you could:
                        </p>
                        <ul class="agile-info-box-list agile-info-box-example">
                            <li>Property Name: <code>rating</code></li>
                            <li>Template: <code>Rated {rating}</code></li>
                            <li>Result: <em>Rated PG-13</em></li>
                        </ul>
                        <p class="agile-info-box-text" style="margin-bottom: 0;">
                            <strong>Pro Tip:</strong> If an event has multiple values for the same property, they will be automatically joined with commas. For example, if an event has genres "Action" and "Comedy", the template <code>Genres: {genre}</code> would display as <em>Genres: Action, Comedy</em>.
                        </p>
                    </div>
                    <div class="agile-info-box-warning">
                        <h4 class="agile-info-box-warning-title">Using the Location Link Block</h4>
                        <p class="agile-info-box-text">
                            The <strong>Location Link</strong> block displays venue information with a clickable map icon. This is a textless block that automatically renders formatted location information from your event's showing data.
                        </p>
                        <p class="agile-info-box-subtitle">Required Data:</p>
                        <p class="agile-info-box-text">
                            For the Location Link block to work, your event must have:
                        </p>
                        <ul class="agile-info-box-list">
                            <li><strong>CurrentShowings</strong> array with at least one showing</li>
                            <li>First showing must have a <strong>Venue</strong> object</li>
                            <li>Venue should contain address information: <code>Name</code>, <code>Address1</code>, <code>City</code>, <code>State</code>, <code>Zip</code> (Address2 is optional)</li>
                        </ul>
                        <p class="agile-info-box-text" style="margin-bottom: 0;">
                            <strong>Important:</strong> The Location Link block will only render if the event has at least one showing with venue data. The block displays the venue name, full address, and a clickable map icon that opens location services.
                        </p>
                    </div>
                    <div class="agile-info-box-warning">
                        <h4 class="agile-info-box-warning-title">Using the Rating Block</h4>
                        <p class="agile-info-box-text">
                            The <strong>Rating</strong> block displays TMDB ratings with a visual star display, numerical score (out of 10), and vote count. This is a textless block that automatically renders formatted rating information.
                        </p>
                        <p class="agile-info-box-subtitle">Required Field Mappings:</p>
                        <p class="agile-info-box-text">
                            For the Rating block to work, you must map TMDB fields to custom properties in your admin settings:
                        </p>
                        <ul class="agile-info-box-list">
                            <li><strong>"TMDB Rating"</strong> -> <code>Vote Average</code> (custom property name)</li>
                            <li><strong>"TMDB Votes"</strong> -> <code>Vote Count</code> (custom property name)</li>
                        </ul>
                        <p class="agile-info-box-text" style="margin-bottom: 0;">
                            <strong>Important:</strong> The Rating block will only render if both <code>Vote Average</code> and <code>Vote Count</code> custom properties are present in your event data. If either is missing, the block will not display anything.
                        </p>
                    </div>
            </div>
                <div class="agile-content-builder-wrapper">
                    <h4 class="agile-content-builder-title">Content Builder (drag blocks onto canvas)</h4>
                    <div id="agile-builder" class="agile-content-builder">
                        <div id="agile-builder-palette" class="agile-builder-palette">
                            <div class="agile-builder-palette-title">Blocks</div>
                            <div class="agile-block type-text" data-type="text" draggable="true">Text</div>
                            <div class="agile-block type-field" data-type="field" data-field="agile_field_content_distributor" draggable="true">Distributor</div>
                            <div class="agile-block type-field" data-type="field" data-field="agile_field_content_duration" draggable="true">Duration</div>
                            <div class="agile-block type-field" data-type="field" data-field="agile_field_content_short_description" draggable="true">Short Description</div>
                            <div class="agile-block type-field" data-type="field" data-field="agile_field_content_full_description" draggable="true">Full Description</div>
                            <div class="agile-block type-field" data-type="field" data-field="agile_field_content_infoLink" draggable="true">Info Link</div>
                            <div class="agile-block type-field" data-type="field" data-field="agile_field_content_renderLocation" draggable="true">Location Link (textless)</div>
                            <div class="agile-block type-field" data-type="field" data-field="agile_field_content_rating" draggable="true">Rating (textless)</div>
                            <div class="agile-block type-field" data-type="field" data-field="agile_field_content_type" draggable="true">Type</div>
                            <div class="agile-block type-field" data-type="field" data-field="agile_field_content_short_descriptive1" draggable="true">ShortDescriptive1</div>
                            <div class="agile-block type-field" data-type="field" data-field="agile_field_content_short_descriptive2" draggable="true">ShortDescriptive2</div>
                            <div class="agile-block type-field" data-type="field" data-field="agile_field_content_extra_html" draggable="true">ExtraHTML</div>
                            <div class="agile-block type-custom-property" data-type="custom-property" draggable="true">Custom Property</div>
                        </div>
                        <div id="agile-builder-canvas" class="agile-builder-canvas">
                            <div class="agile-builder-canvas-placeholder">Drag blocks here. Click text to edit.</div>
                        </div>
                    </div>
                    <?php $settings = get_option('agile_options_content_settings'); ?>
                    <input type="hidden" id="agile_layout_json" name="agile_options_content_settings[layout_json]" value="<?php echo esc_attr($settings['layout_json'] ?? ''); ?>" />
                </div>
            </div>

            <div id="agl_settings_mediaContent_div" class="agile-content-card agile-content-card-media">
                <div class="agile-content-card-header">
                    <svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                        <path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z" fill="currentColor"/>
                    </svg>
                    <h3>Media Carousel</h3>
                </div>
                <p class="agile-content-intro">
            <p>
                    <?php esc_html_e('Replace your default poster image with a media carousel (if you have more than one image associated with an event).', 'agile'); ?>
                </p>

                <table class="form-table agile-content-media-table" role="presentation"> <!--form-table--> 
                <tbody>
                    <?php
                    // Get the media content fields that were registered
                    $media_fields = [
                        'agile_field_render_carousel' => __('Render Additional Media in Carousel:', 'agile'),
                        'agile_field_carousel_size' => __('Carousel Height:', 'agile'),
                        'agile_field_carousel_auto_scroll' => __('Auto-Scroll Media:', 'agile'),
                        'agile_field_carousel_auto_scroll_interval' => __('Auto-Scroll Time Interval (MS):', 'agile'),
                        'agile_field_carousel_pause_on_hover' => __('Pause Auto-Scroll on Hover:', 'agile'),
                        
                        //'agile_field_carousel_aspect_ratio' => __('Media Carousel Aspect Ratio:', 'agile') 
                    ];

                    foreach ($media_fields as $field_id => $field_label) {
                        ?>
                        <tr>
                            <th scope="row">
                                <label for="<?php echo esc_attr($field_id); ?>"><?php echo esc_html($field_label); ?></label>
                            </th>
                            <td>
                                <?php
                                // Call the appropriate field callback function
                                $callback_function = '';
                                switch ($field_id) {
                                    case 'agile_field_render_carousel':
                                        $callback_function = 'agile_field_render_carousel_toggle';
                                        break;
                                    case 'agile_field_carousel_auto_scroll':
                                        $callback_function = 'agile_field_carousel_auto_scroll_toggle';
                                        break;
                                    case 'agile_field_carousel_auto_scroll_interval':
                                        $callback_function = 'agile_field_carousel_auto_scroll_interval_CB';
                                        break;
                                    case 'agile_field_carousel_pause_on_hover':
                                        $callback_function = 'agile_field_carousel_pause_on_hover_toggle';
                                        break;
                                    case 'agile_field_carousel_size':
                                        $callback_function = 'agile_field_carousel_size_CB';
                                        break;
                                    /*case 'agile_field_carousel_aspect_ratio':
                                        $callback_function = 'agile_field_carousel_aspect_ratio_CB';
                                        break;*/
                                }

                                if ($callback_function && method_exists('agile_tix_Options', $callback_function)) {
                                    $args = array(
                                        'label_for' => $field_id,
                                        'class' => 'agile_row',
                                        'agile_custom_data' => 'custom',
                                    );
                                    call_user_func(array('agile_tix_Options', $callback_function), $args);
                                }
                                ?>
                            </td>
                        </tr>
                        <?php
                    }
                    ?>
                </tbody>
            </table>
            </div>
        </div>
        <?php
    }


    static function agile_field_render_carousel_toggle($args)
    {
        $option = get_option('agile_field_render_carousel');

        ?>
        <label for="<?php echo esc_attr($args['label_for']); ?>" class="agile_switch">
            <input type="checkbox"
                id="<?php echo esc_attr($args['label_for']); ?>"
                data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
                name="agile_field_render_carousel"
                title="Should the plugin render additional media in the media carousel if available?"
                value="1" <?php checked($option, 1); ?> />
            <span class="agile_slider"></span>
        </label>
        <?php
    }

    static function agile_field_carousel_auto_scroll_toggle($args)
    {
        $option = get_option('agile_field_carousel_auto_scroll');

        ?>
        <label for="<?php echo esc_attr($args['label_for']); ?>" class="agile_switch">
            <input type="checkbox"
                class="agile_carousel_extra"
                id="<?php echo esc_attr($args['label_for']); ?>"
                data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
                name="agile_field_carousel_auto_scroll"
                title="Automatically Scroll Between Carousel Media?"
                value="1" <?php checked($option, 1); ?> />
            <span class="agile_slider agile_carousel_extra"></span>
        </label>
        <?php
    }


    static function agile_field_carousel_auto_scroll_interval_CB($args)
    {
        $option = get_option("agile_field_carousel_auto_scroll_interval");
        ?>
        <input type="text"
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_field_carousel_auto_scroll_interval"
            value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
            title="How long your carousel will sit on an image before scrolling (if auto scroll enabled)"
            class="regular-text agile_carousel_extra"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
            required />
        <?php
    }


    static function agile_field_carousel_pause_on_hover_toggle($args)
    {
        $option = get_option('agile_field_carousel_pause_on_hover');

        ?>
        <label for="<?php echo esc_attr($args['label_for']); ?>" class="agile_switch">
            <input type="checkbox"
                class="agile_carousel_extra"
                id="<?php echo esc_attr($args['label_for']); ?>"
                data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
                name="agile_field_carousel_pause_on_hover"
                title="Pause Auto-Scroll when user hovers over an option"
                value="1" <?php checked($option, 1); ?> />
            <span class="agile_slider agile_carousel_extra"></span>
        </label>
        <?php

    }
    
    //currently not in use
    static function agile_field_carousel_aspect_ratio_CB($args){
        $option = get_option('agile_field_carousel_aspect_ratio');

        ?>
        <input type="text"
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_field_carousel_aspect_ratio"
            value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
            title="Aspect ratio to render your media carousel in i.e. (16/9, 1/1, auto)"
            class="regular-text agile_carousel_extra"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
            required />
        <?php
    }
    

    static function agile_field_carousel_size_CB($args){
        $option = get_option('agile_field_carousel_size');

        ?>
        <select name="agile_field_carousel_size" id="agile_field_carousel_size" class="agile_row agile_carousel_extra">
            <option value="auto" <?php selected($option, 'auto'); ?>>Auto (Recommended )</option>
            <!--<option value="xsmall" <?php selected($option, 'xsmall'); ?>>Extra Small (10 vh)</option>  this small of a carousel looks stupid --> 
            <option value="small" <?php selected($option, 'small'); ?>>Small (20 vh)</option>
            <option value="medium" <?php selected($option, 'medium'); ?>>Medium (30 vh)</option>
            <option value="large" <?php selected($option, 'large'); ?>>Large (40 vh)</option>
            <option value="xlarge" <?php selected($option, 'xlarge'); ?>>Extra Large (50 vh)</option>
            <option value="xxlarge" <?php selected($option, 'xxlarge'); ?>>XXLarge (60 vh)</option>
            <option value="xxxlarge" <?php selected($option, 'xxxlarge'); ?>>3XLarge (70 vh)</option>
        </select>
        <?php
    }

    static function agile_section_config_callback($args)
    {
        ?>
        <div class="agile-config-section">
            <p id="<?php echo esc_attr($args['id']); ?>" class="agile-config-intro"><?php esc_html_e('Determine how you want non-content aspects of your posts to be presented.', 'agile'); ?></p>
        </div>
        <?php
    }

    static function agile_section_theme_callback($args)
    {
        ?>
        <div class="agile-theme-section">
            <p id="<?php echo esc_attr($args['id']); ?>" class="agile-theme-intro">Configure how this plugin integrates with your WordPress theme. <?php agile_tix_Options::agile_field_explainer("agile_theme_explainer"); ?></p>
            <div id="agile_theme_explainer_body" class="agile-info-box">
                <h4 class="agile-info-box-title">Theme Integration Overview</h4>
                <p class="agile-info-box-text">
                    This tab allows you to configure how event data from the plugin integrates with your WordPress theme. You can choose from supported theme integrations or create custom mappings for unsupported themes.
                </p>
                <p class="agile-info-box-subtitle">Theme Integration Options:</p>
                <ul class="agile-info-box-list">
                    <li><strong>None (Agile):</strong> Use the plugin's default theme-agnostic approach. This works with any theme but provides basic styling.</li>
                    <li><strong>EventChamp:</strong> If you're using the EventChamp theme, select this option for seamless integration with the theme's event post type and custom fields.</li>
                    <li><strong>Amy Movie:</strong> If you're using the Amy Movie theme, select this option for automatic integration with the theme's movie post type and metadata structure.</li>
                    <li><strong>Custom:</strong> For any other theme or custom setup, use the mapping tools below to configure how event data maps to your theme's post type, custom fields, and taxonomies.</li>
                </ul>
                <p class="agile-info-box-subtitle">Custom Mapping Tools:</p>
                <p class="agile-info-box-text" style="margin-bottom: 0;">
                    When using the "Custom" integration option, you'll configure three main components: <strong>Custom Fields</strong> (for post meta-data), <strong>Post Terms</strong> (for taxonomies like categories and tags), and the <strong>Function Editor</strong> (for advanced data transformation). Each section below includes detailed explanations.
                </p>
            </div>
        </div>
        <?php
    }

    

    static function agile_field_config_integration_type_CB($args)
    {
        $current_value = get_option('agile_field_config_integration_type', 'none');
        $themes = wp_get_themes();
        ?>
        <select name="agile_field_config_integration_type" id="agile_field_config_integration_type" class="agile_row">
            <option value="none" <?php selected($current_value, 'none'); ?>>None (Agile)</option>
            <?php if (array_key_exists('eventchamp', $themes)) { ?>
                <option value="event_champ" <?php selected($current_value, 'event_champ'); ?>>Event Champ</option>
            <?php } ?>
            <?php if (array_key_exists('amy-movie', $themes)) { ?>
                <option value="amy_movie" <?php selected($current_value, 'amy_movie'); ?>>Amy Movie</option>
            <?php } ?>
            <option value="custom" <?php selected($current_value, 'custom'); ?>>Custom</option>
        </select>
        <?php
    }

    static function agile_field_theme_custom_map_post_type_CB($args)
    {
        $postTypeArgs = array(
            'public' => true,
            //'_builtin' => true //changed to add vanilla posts as an option
        );

        $output = 'names';
        $operator = 'and';

        $post_types = get_post_types($postTypeArgs, $output, $operator);
        if (isset($post_types['attachment'])) {
            unset($post_types['attachment']);
        }

        $option = get_option('agile_field_theme_custom_map_post_type');
        ?>

        <select
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_field_theme_custom_map_post_type"
            class="regular-text agile-meta-map"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>">

            <option value="">Select a Post Type(None)</option>
            <?php foreach ($post_types as $post_type): ?>
                <option value="<?php echo esc_attr($post_type); ?>"
                    <?php selected($option, $post_type); ?>>
                    <?php echo esc_html($post_type); ?>
                </option>
            <?php endforeach; ?>
        </select>
        <?php
    }

    static function agile_field_theme_custom_map_template_CB($args)
    {
        //$templates will only ever return the templates active for the current theme
        $templates = get_page_templates();
        $option = get_option('agile_field_theme_custom_map_template');
        ?>

        <select
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_field_theme_custom_map_template"
            class="regular-text agile-meta-map"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>">

            <option value="">Select a Template(None)</option>
            <?php foreach ($templates as $template): ?>
                <option value="<?php echo esc_attr($template); ?>"
                    <?php selected($option, $template); ?>>
                    <?php echo esc_html($template); ?>
                </option>
            <?php endforeach; ?>
        </select>
        <?php


    }

    static function agile_field_style_editor_CB()
    {
        $option = get_option('agile_field_style_editor');
        $file_path = plugin_dir_path(__FILE__) . '../public/css/agile-ticketing-user-defined-public.css';
        $file_content = file_exists($file_path) ? file_get_contents($file_path) : '';

        if ($file_content == '') {
            //If the file is empty or doesn't exist, like on a fresh plugin install, check if the setting exists from a previous install
            $file_content = get_option('agile_field_style_editor') ?? '';
        }

        ?>
        <div class="agile-style-editor-wrapper">
            <script src="<?php echo plugin_dir_url(__FILE__) ?>../AceCodeEditor/src-min-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
            <div class="agile-style-editor-layout">
                <div class="ace-editor-container" id="ace-editor-container">
                    <div class="ace-editor-tab" id="ace-editor-tab">
                        <svg class="ace-editor-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                            <path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0L19.2 12l-4.6-4.6L16 6l6 6-6 6-1.4-1.4z" fill="currentColor"/>
                        </svg>
                        <span>agile-ticketing-user-defined-public.css</span>
                    </div>
                    <div id="ace-editor"><?php echo esc_textarea($file_content); ?></div>
                </div>
                <div class="agile-style-presets-container">
                    <div class="agile-style-presets-header">
                        <h3>Style Presets</h3>
                    </div>
                    <div class="agile-style-presets-disclaimer">
                        <p><strong>Note:</strong> Style presets may not work correctly with all WordPress themes. If you experience styling issues, try using custom CSS instead.</p>
                    </div>
                    <?php
                    // Show warning if custom styles exist
                    $available_custom_styles = self::agile_get_available_custom_styles();
                    if ($available_custom_styles['custom-1'] || $available_custom_styles['custom-2']) {
                        echo '<div class="agile-style-presets-warning">';
                        echo '<p><strong>Warning:</strong> Any saved custom styles will be lost if the plugin is uninstalled.</p>';
                        echo '<p>If you wish to download the file directly, you can find it in /wp-content/plugins/agile-ticketing-plugin/includes/style-presets</p>';
                        echo '</div>';
                    }
                    ?>
                    <div class="agile-style-presets-buttons">
                        <button type="button" class="button agile-preset-btn" data-preset="none">None</button>
                        <button type="button" class="button agile-preset-btn" data-preset="default">Minimal</button>
                        <button type="button" class="button agile-preset-btn" data-preset="dark">Dark</button>
                        <?php
                        // Dynamically render custom style buttons if files exist
                        if ($available_custom_styles['custom-1']) {
                            echo '<button type="button" class="button agile-preset-btn" data-preset="custom-1">Custom Style 1</button>';
                        }
                        if ($available_custom_styles['custom-2']) {
                            echo '<button type="button" class="button agile-preset-btn" data-preset="custom-2">Custom Style 2</button>';
                        }
                        ?>
                        <button type="button" class="button button-primary agile-save-preset-btn" id="agile-save-preset-btn-1" data-slot="custom-1">Save to Style 1</button>
                        <button type="button" class="button button-primary agile-save-preset-btn" id="agile-save-preset-btn-2" data-slot="custom-2">Save to Style 2</button>
                    </div>
                </div>
            </div>
            <input type="hidden" id="ace-editor-hidden" name="agile_field_style_editor" value="<?php echo (esc_attr($file_content)); ?>" />
        </div>
        <?php
    }

    static function agile_field_theme_custom_code_CB()
    {
        $value = get_option('agile_field_theme_custom_code');
        ?>
        <div class="agile-theme-card">
            <div class="agile-theme-card-header">
                <svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                    <path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0L19.2 12l-4.6-4.6L16 6l6 6-6 6-1.4-1.4z" fill="currentColor"/>
                </svg>
                <h2>Function Editor <?php agile_tix_Options::agile_field_explainer("agile_function_editor_explainer"); ?></h2>
            </div>
            <div id="agile_function_editor_explainer_body" class="agile-info-box">
                <h4 class="agile-info-box-title">Understanding the Function Editor</h4>
                <p class="agile-info-box-text">
                    <strong>Advanced:</strong> The Function Editor allows you to create custom PHP functions that manipulate and format your event data before it's saved to WordPress. These functions can be called from Custom Fields and Post Terms using bracket notation.
                </p>
                <p class="agile-info-box-subtitle">How Functions Work:</p>
                <ul class="agile-info-box-list">
                    <li>All functions receive the event data as their first parameter (similar to the JSON example shown)</li>
                    <li>Functions can access any field from the event data using dot notation or array access</li>
                    <li>Functions should return a value that will be used as the custom field or term value</li>
                    <li>Functions containing unsafe commands will not be executed for security reasons</li>
                </ul>
                <p class="agile-info-box-subtitle">Important Guidelines:</p>
                <ul class="agile-info-box-list">
                    <li>Do not include opening or closing PHP tags (<?php ?> or &lt;? ?&gt;)</li>
                    <li>Write only function definitions and helper code</li>
                    <li>You are solely responsible for the output of your own functions</li>
                    <li>Test your functions carefully before using them in production</li>
                </ul>
                <p class="agile-info-box-subtitle">Example Functions:</p>
                <div class="agile-code-example">
                    <pre>// Example 1: Convert a field to uppercase
// Usage in Custom Fields: allCaps("CorpOrgName")
function allCaps($show, $path) {
    return isset($show[$path]) ? strtoupper($show[$path]) : "Key not found";
}

// Example 2: Format a date field
// Usage in Custom Fields: formatDate("CurrentShowings.0.StartDate", "F j, Y")
function formatDate($show, $datePath, $format = "Y-m-d") {
    if (!isset($show[$datePath])) {
        return "Date not found";
    }
    $date = strtotime($show[$datePath]);
    return $date ? date($format, $date) : $show[$datePath];
}

// Example 3: Combine multiple fields
// Usage in Custom Fields: combineFields("Name", "Duration")
function combineFields($show, $field1, $field2) {
    $val1 = isset($show[$field1]) ? $show[$field1] : "";
    $val2 = isset($show[$field2]) ? $show[$field2] : "";
    return trim($val1 . " - " . $val2);
}

// Example 4: Safe array access with dot notation
// Usage in Custom Fields: getNestedValue("CurrentShowings.0.StartDate")
function getNestedValue($show, $path) {
    $keys = explode('.', $path);
    $value = $show;
    foreach ($keys as $key) {
        if (isset($value[$key])) {
            $value = $value[$key];
        } else {
            return "Path not found";
        }
    }
    return $value;
}</pre>
                </div>
                <p class="agile-info-box-text" style="margin-bottom: 0;">
                    <strong>Using Functions:</strong> Once you've defined a function, use bracket notation in Custom Fields or Post Terms. For example, <code>allCaps("CorpOrgName")</code> will call your function with the "CorpOrgName" field value. The function receives the entire event data array as the first parameter, and any additional parameters you pass in the brackets.
                </p>
            </div>
            <div class="ace-editor-container" id="function-editor-container">
                <div class="ace-editor-tab" id="function-editor-tab">
                    <svg class="ace-editor-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                        <path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0L19.2 12l-4.6-4.6L16 6l6 6-6 6-1.4-1.4z" fill="currentColor"/>
                    </svg>
                    <span>Function Editor</span>
                </div>
                <div id="function-editor-textarea"></div>
            </div>
            <textarea id="function-editor-hidden" name="agile_field_theme_custom_code" style="display:none;"><?php echo esc_textarea($value); ?></textarea>
        </div>
        <?php
    }

    static function agile_custom_fields_CB()
    {
        $custom_fields = get_option('agile_custom_fields', []);
        ?>
        <div class="agile-theme-card">
            <div class="agile-theme-card-header">
                <svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                    <path d="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" fill="currentColor"/>
                </svg>
                <h2>Custom Fields <?php agile_tix_Options::agile_field_explainer("agile_custom_fields_explainer"); ?></h2>
            </div>
            <div id="agile_custom_fields_explainer_body" class="agile-info-box">
                <h4 class="agile-info-box-title">Understanding Custom Fields</h4>
                <p class="agile-info-box-text">
                    <strong>Important!</strong> Custom fields and terms will only be evaluated if you are using the custom theme integration option.
                </p>
                <p class="agile-info-box-text">
                    Custom fields allow you to map event data to WordPress post meta-data. These values will be stored as custom fields (meta-data) on your posts, which can then be accessed by your theme templates or other plugins.
                </p>
                <p class="agile-info-box-subtitle">Using Dot Notation (Unmodified Data):</p>
                <p class="agile-info-box-text">
                    To use data directly from your event without modification, access it using "dot" notation. This follows the structure of your JSON event data. For example, to store a show's start date as meta-data named <code>example_StartDate</code>, use the value <code>CurrentShowings.0.StartDate</code>.
                </p>
                <p class="agile-info-box-subtitle">Using Bracket Notation (With Functions):</p>
                <p class="agile-info-box-text" style="margin-bottom: 0;">
                    To modify and format your data, use functions you've defined in the Function Editor below. Use "bracket" notation to pass field values to your custom functions. For example, if you wanted the name of a show to be passed to a function, you would use <code>your_function("Name")</code>. The function will receive the field value and can return a modified version.
                </p>
            </div>
            <table id="custom-fields-table">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Value</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    <?php if (is_array($custom_fields)) {
                        foreach ($custom_fields as $index => $field): ?>
                            <tr>
                                <td><input type="text" name="agile_custom_fields[<?php echo $index; ?>][0]" value="<?php echo esc_attr($field[0]); ?>" /></td>
                                <td><input type="text" name="agile_custom_fields[<?php echo $index; ?>][1]" value="<?php echo esc_attr($field[1]); ?>" /></td>
                                <td><button type="button" id="meta-remove-field" class="button-secondary">Remove</button></td>
                            </tr>
                        <?php endforeach;
                    } ?>
                </tbody>
            </table>
            <button type="button" id="meta-add-field" class="button-secondary" >Add Field</button>
        </div>
        <?php
    }




    static function agile_term_fields_CB()
    {
        $custom_terms = get_option('agile_term_fields', []);
        ?>
        <div class="agile-theme-card">
            <div class="agile-theme-card-header">
                <svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                    <path d="M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7.01v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16z" fill="currentColor"/>
                </svg>
                <h2>Post Terms <?php agile_tix_Options::agile_field_explainer("agile_post_terms_explainer"); ?></h2>
            </div>
            <div id="agile_post_terms_explainer_body" class="agile-info-box">
                <h4 class="agile-info-box-title">Understanding Post Terms</h4>
                <p class="agile-info-box-text">
                    Post Terms allow you to map event data to WordPress taxonomies (like categories, tags, or custom taxonomies). These terms will be assigned to your posts, allowing you to organize and filter content using WordPress's built-in taxonomy system.
                </p>
                <p class="agile-info-box-subtitle">How It Works:</p>
                <ul class="agile-info-box-list">
                    <li>Select or enter the taxonomy name (e.g., "category", "post_tag", or a custom taxonomy)</li>
                    <li>Enter the value from your event data using dot notation or bracket notation with functions</li>
                    <li>Terms will only be added if the chosen taxonomy is associated with the post type you're creating</li>
                    <li>If a term doesn't exist, WordPress will create it automatically</li>
                </ul>
                <p class="agile-info-box-text" style="margin-bottom: 0;">
                    <strong>Note:</strong> Like Custom Fields, Post Terms will only be evaluated when using the custom theme integration option. The taxonomy dropdown will show available taxonomies for your selected post type.
                </p>
            </div>
            <table id="custom-term-table">
                <thead>
                    <tr>
                        <th>Taxonomy</th>
                        <th>Value</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    <?php if (is_array($custom_terms)) {
                        foreach ($custom_terms as $index => $field): ?>
                            <tr>
                                <td>
                                    <input type="text" list="taxonomy-list-<?php echo $index; ?>" name="agile_term_fields[<?php echo $index; ?>][0]" class="taxonomy-input" autocomplete="off" value="<?php echo esc_attr($field[0]); ?>" placeholder="Type or select taxonomy" />
                                    <datalist id="taxonomy-list-<?php echo $index; ?>"></datalist>
                                </td>
                                <td><input type="text" name="agile_term_fields[<?php echo $index; ?>][1]" value="<?php echo esc_attr($field[1]); ?>" placeholder="Enter value" /></td>
                                <td><button type="button" class="button-secondary term-remove-field">Remove</button></td> 
                            </tr>
                        <?php endforeach;
                    } ?>
                </tbody>
            </table>
            <button type="button" id="term-add-field" class="button-secondary">Add Field</button>
        </div>

        <?php
    }

    static function agile_section_advanced_callback($args)
    {
        ?>
        <div class="agile-advanced-section">
            <div class="agile-advanced-container">
                <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="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>Action Scheduler Settings</h3>
                    </div>
                    <p id="<?php echo esc_attr($args['id']); ?>" class="agile-advanced-intro">This plugin uses the Action Scheduler library to handle background processing of data. These settings are used to configure the Action Scheduler and how this plugin interacts with it. <?php agile_tix_Options::agile_field_explainer("agile_advanced_explainer"); ?></p>
                    <div id="agile_advanced_explainer_body" class="agile-info-box">
                        <h4 class="agile-info-box-title">Understanding Action Scheduler</h4>
                        <p class="agile-info-box-text">
                            Action Scheduler is a background processing library that allows WordPress plugins to schedule and run tasks asynchronously. This prevents long-running operations from blocking page loads and provides a reliable way to process large amounts of data in the background.
                        </p>
                        <p class="agile-info-box-subtitle">
                            <strong>How the Settings Influence Processing:</strong>
                        </p>
                        <ul class="agile-info-box-list">
                            <li><strong>Batch Size:</strong> Controls how many actions Action Scheduler processes in each batch. A larger batch size can improve performance if your actions complete quickly, but may cause timeouts if actions take too long. The default is 25 actions per batch.</li>
                            <li><strong>Concurrent Batches:</strong> Determines how many batches can run simultaneously. Increasing this allows more parallel processing, which can speed up overall completion time, but also increases server resource usage. The default is 1 concurrent batch.</li>
                            <li><strong>Chunk Size:</strong> Specifies how many posts worth of content are processed per chunk within this plugin's workflow. This setting helps break large data processing tasks into manageable pieces. A larger chunk size can be more efficient, but must be balanced against timeout limits. The default is 10 posts per chunk.</li>
                        </ul>
                        <p class="agile-info-box-subtitle">
                            <strong>Performance Optimization:</strong>
                        </p>
                        <p class="agile-info-box-text" style="margin-bottom: 0;">
                            These settings work together to balance processing speed with server resources. Increasing batch size and concurrent batches can speed up processing, but may strain your server if set too high. The chunk size should be set to the largest value that doesn't cause timeouts during processing. Monitor your server's performance and adjust these values accordingly.
                        </p>
                    </div>
                    <div class="agile-config-fields"></div>
                </div>
            </div>
        </div>
        <?php
    }


    static function agile_field_actSched_batch_size_cb($args){
        $option = get_option("agile_field_actSched_batch_size");
        ?>
        <input type="number"
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_field_actSched_batch_size"
            value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
            title="By default, Action Scheduler will claim a batch of 25 actions. This small batch size is because the default time limit is only 30 seconds; however, if you know your actions are processing very quickly, e.g. taking milliseconds not seconds, or that you have more than 30 seconds available to process each batch, increasing the batch size can slightly improve performance."
            class="regular-text"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
            min="1"
            step="1"
            required />
        <div class="agile-config-field-help">By default, Action Scheduler will claim a batch of 25 actions. This small batch size is because the default time limit is only 30 seconds; however, if you know your actions are processing very quickly, e.g. taking milliseconds not seconds, or that you have more than 30 seconds available to process each batch, increasing the batch size can slightly improve performance.</div>
        <?php
    }


    static function agile_field_actSched_concurrentBatches_cb($args){
        $option = get_option("agile_field_actSched_concurrentBatches");
        ?>
        <input type="number"
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_field_actSched_concurrentBatches"
            value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
            title="By default, Action Scheduler will run only one concurrent batch of actions."
            class="regular-text"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
            min="1"
            step="1"
            required />
        <div class="agile-config-field-help">By default, Action Scheduler will run only one concurrent batch of actions. Increasing this allows more parallel processing, which can speed up overall completion time, but also increases server resource usage.</div>
        <?php
    }

    static function agile_chunk_size_cb($args){
        $option = get_option("agile_chunk_size");
        ?>
        <input type="number"
            id="<?php echo esc_attr($args['label_for']); ?>"
            name="agile_chunk_size"
            value="<?php echo isset($option) ? esc_attr($option) : ''; ?>"
            title="How many posts worth of content should be carved out per chunk. Best performance should come with the largest possible number that never induces a timeout. Default is 10"
            class="regular-text"
            data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
            min="1"
            step="1"
            required />
        <div class="agile-config-field-help">How many posts worth of content should be carved out per chunk. Best performance should come with the largest possible number that never induces a timeout. Default is 10.</div>
        <?php
    }

    static function agile_field_useEPGTAG_cb($args){
        $option = get_option('agile_field_useEPGTAG') ?? false;

        ?>
        <label for="<?php echo esc_attr($args['label_for']); ?>" class="agile_switch">
            <input type="checkbox"
                id="<?php echo esc_attr($args['label_for']); ?>"
                data-custom="<?php echo esc_attr($args['agile_custom_data']); ?>"
                name="agile_field_useEPGTAG"
                title="Your event feeds will be populated based on your EPG Tag instead of your EPGID and GUID. See credentials for new input options"
                value="1" <?php checked($option, 1); ?> />
            <span class="agile_slider"></span>
        </label>
        <?php
    }


    //#endregion settings fields callbacks

    function agile_save_custom_style_to_file()
    {
        //agile_tix::agile_tix_log_event("agile_save_custom_style_to_file invoked");
        $new_value = get_option('agile_field_style_editor');

        //turbo basic version
        $file_path = plugin_dir_path(__FILE__) . '../public/css/agile-ticketing-user-defined-public.css';

        // Save the new value to the file
        if (file_put_contents($file_path, $new_value) === false) {
            agile_tix::agile_tix_log_event('Failed to save the agile-ticketing-user-defined-public.css file.');
        } else {
            //agile_tix::agile_tix_log_event("file_put_contents worked, enqueueing styles");
            $file_url = plugin_dir_url(__FILE__) . '../public/css/agile-ticketing-user-defined-public.css';

            //enqueue style
            if (!has_action('wp_enqueue_scripts', ['agile_tix_Options', 'agile_enqueue_custom_CB'])) {
                //to avoid double enqueueing a style kill the old one to keep it fresh
                remove_action('wp_enqueue_scripts', ['agile_tix_Options', 'agile_enqueue_custom_CB']);
            }

            //add_action('wp_enqueue_scripts', agile_tix_Options::agile_enqueue_custom($file_url,$file_path));
            add_action('wp_enqueue_scripts', function () use ($file_url, $file_path) {
                agile_tix_Options::agile_enqueue_custom_CB($file_url, $file_path);
            });
        }
    }

    //its own function so it can be easily checked if its already added to a hook and/or removed from a hook
    static function agile_enqueue_custom_CB($file_url, $file_path)
    {
        //agile_tix::agile_tix_log_event("wp_enqueue_style run");
        wp_enqueue_style('agile-custom-styles', $file_url, array(), filemtime($file_path));
    }

    /*Public facing custom styles are handled like so:
    //On install, there is no agile-ticketing-user-defined-public.css file
    //After saving some text and saving hopefully valid style content, that file is created or overwritten with the new style
    //On Uninstall, agile-ticketing-user-defined-public.css is effectivly destroyed as it resides inside the now deleted plugin folder
    //This can be problematic as the style code is persistant between installs as it is saved as an option, but the file it represents is not
    //This can lead to the user being able to see thier style code in our settings UI, but doesn't get any styling out of it as there is no file to reference
    */
    function agile_enqueue_user_styles()
    {
        $file_path = plugin_dir_path(__FILE__) . '../public/css/agile-ticketing-user-defined-public.css';
        $customStyle = get_option('agile_field_style_editor');

        if (file_exists($file_path)) {
            $file_url = plugin_dir_url(__FILE__) . '../public/css/agile-ticketing-user-defined-public.css';
            //agile_tix::agile_tix_log_event("Enqueueing user-defined styles");
            wp_enqueue_style('agile-custom-styles', $file_url, array(), filemtime($file_path));
        } else if ($customStyle && $customStyle != '' && $customStyle != '/*Insert your public facing css here. This will not be visible on your admin panel*/') {
            agile_tix::agile_tix_log_event("agile_enqueue_user_styles file doesn't exist, but style found");
            //the user has a custom style and it isn't an empty file or the default placeholder, but not a file to enqueue
            //create the file for them
            agile_tix_Options::agile_save_custom_style_to_file();
        } else {
            //agile_tix::agile_tix_log_event("agile_enqueue_user_styles no file, no style");
            //the user has not touched our CSS editor or at the very least has no desire to present custom styles with our editor
            //no need to do anything
            //agile_tix::agile_tix_log_event("CSS file not found for enqueueing");
        }
    }


    //Gets all meta data keys for EXISTING POSTS to population custom mapping field options
    static function agile_get_post_type_meta($post_type)
    {
        global $wpdb;
        $cache_key = 'meta_keys_' . $post_type;
        $meta_keys = wp_cache_get($cache_key);

        if ($meta_keys === false) {
            $sql = $wpdb->prepare("
            SELECT DISTINCT meta_key
            FROM $wpdb->postmeta
            WHERE meta_key NOT LIKE '\_%'
            AND post_id IN (SELECT ID FROM $wpdb->posts WHERE post_type = %s)
        ", $post_type);

            $meta_keys = $wpdb->get_col($sql);

            wp_cache_set($cache_key, $meta_keys, '', HOUR_IN_SECONDS);
        }

        return $meta_keys;
    }


    function agile_get_meta_fields_ajax()
    {
        if (!isset($_POST['post_type'])) {
            wp_send_json_error('Missing post type');
        }

        global $wpdb;
        $post_type = sanitize_text_field($_POST['post_type']);
        $meta_keys = agile_tix_Options::agile_get_post_type_meta($post_type);

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

    function agile_get_tax_by_postType()
    {
        if (!isset($_POST['PostType'])) {
            wp_send_json_error('Missing post type');
        }
        $post_type = sanitize_text_field($_POST['PostType']);

        $taxonomies = get_object_taxonomies($post_type, 'names');
        if (!empty($taxonomies)) {
            wp_send_json_success($taxonomies);
        } else {
            wp_send_json_error('No taxonomies found');
        }
    }

    //Adds a link to the plugin displayed in plugins.php to take the user to our settings page
    function agile_plugin_settings_link($links)
    {
        $url = esc_url(add_query_arg(
            'page',
            'agile',
            get_admin_url() . 'admin.php'
        ));
        $settings_link = "<a href='$url'>" . __('Settings') . '</a>';
        array_unshift($links, $settings_link);
        return $links;
    }

    //resets the values and order of the content fields
    function agile_reset_content_to_default()
    {
        if (!current_user_can('manage_options')) {
            wp_die(__('Unauthorized user', 'agile'));
        }

        if (!isset($_POST['ats_reset_nonce']) || !wp_verify_nonce($_POST['ats_reset_nonce'], 'ats_reset_content_default_action')) {
            wp_die(__('Security check failed', 'agile'));
        }

        // Reset settings
        update_option('agile_options_content_settings', array(
            'field_order' => "agile_field_content_distributor,agile_field_content_infoLink,agile_field_content_duration,agile_field_content_full_description,agile_field_content_release_year,agile_field_content_rating,agile_field_content_genre,agile_field_content_director,agile_field_content_cast,agile_field_content_renderLocation"
        ));
        update_option('agile_field_content_distributor', 'Proudly presented by {distributor}');
        update_option('agile_field_content_infoLink', 'Learn More');
        update_option('agile_field_content_duration', '{duration} minutes');
        update_option('agile_field_content_full_description', '{full description}');
        update_option('agile_field_content_release_year', 'Released {release year}');
        update_option('agile_field_content_rating', 'Rated {rating}');
        update_option('agile_field_content_director', 'Directed by {director}');
        update_option('agile_field_content_cast', 'Cast: {cast list}');
        update_option('agile_field_content_genre', 'Genre: {genre list}');
        update_option('agile_field_content_renderLocation', '{location}');

        // Redirect back to settings page
        wp_redirect(admin_url('admin.php?page=agile&settings-updated=true'));
        exit;
    }

    /**
     * Process flow:
     * run the data through location api to get API and web URL
     * Try to use that data to get some data to confirm its good
     * If the data is good, run a call to our wordpress hook to automatically ping the site for data refreshes
     * If the data is bad, don't call the WP hook, let them know what went wrong
     */
    function agile_verify_credentials_after_save()
    {
        if (
            isset($_GET['page'], $_GET['tab'], $_GET['settings-updated']) &&
            $_GET['page'] === 'agile' &&
            $_GET['tab'] === 'credentials' &&
            $_GET['settings-updated'] === 'true'
        ) {
            $requiredCredentials = array('agile_field_domain', 'agile_field_corpOrgID',  'agile_field_password');

            foreach ($requiredCredentials as $cred) {
                $credential = get_option($cred);
                if ($credential == false || $credential == '') {
                    add_settings_error('agile_options_credentials', 'error_code', __('Atleast one credential was found missing or empty', 'agile'), 'error');
                    return false;
                }
            }

            //check if we are using EPGTAG or EPGID/GUID combo
            $epgID = get_option('agile_field_epgID');
            $guid = get_option('agile_field_guid');
            $useEPGTAG = get_option('agile_field_epgTag');

            if ($epgID == "" || is_null($epgID) ||  $epgID == false || $guid == "" || is_null($guid) ||  $guid == false){
                //Invalid epgID or guid, check if we are using EPGTAG
                if ($useEPGTAG == "" || $useEPGTAG == false || is_null($useEPGTAG) || $useEPGTAG == 0){
                    //not using EPGTAG and epgID or guid is bad, error
                    add_settings_error('agile_options_credentials', 'error_code', __('You must provide either a valid EPGID and GUID', 'agile'), 'error');
                    return false;
                }
            }

            // Validate coming soon feed credentials if enabled
            $useComingSoon = get_option('agile_field_use_coming_soon_feed');
            if ($useComingSoon) {
                $comingSoonGuid = get_option('agile_field_coming_soon_guid');
                if ($comingSoonGuid == "" || is_null($comingSoonGuid) || $comingSoonGuid == false) {
                    add_settings_error('agile_options_credentials', 'error_code', __('Coming Soon Feed is enabled but GUID is missing', 'agile'), 'error');
                    return false;
                }
            }



            $locData = agile_ticketing_location_services::agile_collect_locationData();
            $apiURL = '';
            $webURL = '';
            if (array_key_exists('APIURL', $locData)) {
                $apiURL = $locData['APIURL'];
                update_option('agile_field_apiURL', $apiURL);
            }
            if (array_key_exists('WebURL', $locData)) {
                $webURL = $locData['WebURL'];
                update_option('agile_field_webURL', $webURL);
            }

            //agile_tix::agile_tix_log_event('agile_verify_credentials_after_save run $apiURL ' . $apiURL);
            //agile_tix::agile_tix_log_event('agile_verify_credentials_after_save run $apiURL ' . $webURL);
            if ($apiURL == '' || $webURL == '') {
                //no way to collect data without these, escape
                update_option('agile_field_credentials_are_valid', false);
                add_settings_error('agile_options_credentials', 'error_code', __('We were unable to find data with these credentials', 'agile'), 'error');
                return false;
            }

            //agile_tix::agile_tix_log_event('agile_verify_credentials_after_save run');
            //agile_tix::agile_tix_log_event('isset check run');
            $fetchResult = agile_tix_data_fetcher::fetch_agile_data();
            //fetch either returns an array of data or an error message as a string
            if (is_string($fetchResult)) {
                //something wrong we can identify happened
                update_option('agile_field_credentials_are_valid', false);
                add_settings_error('agile_options_credentials', 'error_code', __(esc_html($fetchResult), 'agile'), 'error');
                agile_tix::agile_tix_log_event('agile_verify_credentials_after_save $fetchResult: ' . json_encode($fetchResult));

            } else if (is_array($fetchResult) && array_key_exists('ArrayOfShow', $fetchResult)) {
                agile_tix::agile_tix_log_event('agile_verify_credentials_after_save ArrayOfShow: ' . json_encode($fetchResult));
                update_option('agile_field_credentials_are_valid', false);
                //if the array of show is empty but there, everything could be fine, still warn the user they have no data to make posts with
                add_settings_error('agile_options_credentials', 'error_code', __('No shows were found using those credentials', 'agile'), 'error');
                //agile_tix::agile_tix_log_event('No shows were found using those credentials');
            } else {
                // Main feed credentials are valid, now validate coming soon feed if enabled
                $useComingSoon = get_option('agile_field_use_coming_soon_feed');
                if ($useComingSoon) {
                    $comingSoonFetchResult = agile_tix_data_fetcher::fetch_agile_data('coming_soon');
                    
                    // Coming soon feed validation with tolerance for empty feeds
                    if (is_string($comingSoonFetchResult)) {
                        update_option('agile_field_credentials_are_valid', false);
                        add_settings_error('agile_options_credentials', 'error_code', __('Coming Soon Feed: ' . esc_html($comingSoonFetchResult), 'agile'), 'error');
                        agile_tix::agile_tix_log_event('agile_verify_credentials_after_save coming soon $fetchResult: ' . json_encode($comingSoonFetchResult));
                    } else if (is_array($comingSoonFetchResult)) {
                        // Valid array response - allow missing or empty ArrayOfShows (empty feeds are valid)
                        // Only check that the response is a valid array structure
                        if (!isset($comingSoonFetchResult['ArrayOfShows'])) {
                            // Missing ArrayOfShows is acceptable - treat as empty feed
                            // agile_tix::agile_tix_log_event('agile_verify_credentials_after_save coming soon: Empty feed (no ArrayOfShows), treating as valid');
                        } else if (is_array($comingSoonFetchResult['ArrayOfShows']) && empty($comingSoonFetchResult['ArrayOfShows'])) {
                            // Empty ArrayOfShows is acceptable - treat as valid empty feed
                            // agile_tix::agile_tix_log_event('agile_verify_credentials_after_save coming soon: Empty feed (empty ArrayOfShows), treating as valid');
                        }
                        // If we get here, the coming soon feed is valid (even if empty)
                        agile_tix::agile_tix_log_event('agile_verify_credentials_after_save coming soon creds are good');
                    } else {
                        // Unexpected data type
                        update_option('agile_field_credentials_are_valid', false);
                        add_settings_error('agile_options_credentials', 'error_code', __('Coming Soon Feed: Invalid response format', 'agile'), 'error');
                        agile_tix::agile_tix_log_event('agile_verify_credentials_after_save coming soon: Unexpected data type: ' . gettype($comingSoonFetchResult));
                    }
                }
                
                //If credentials pulls up valid results AND all credentials are valid, we activate this site on ATS side
                //we may want to make this a less automatic process, maybe an 'activate' button that is enabled by this instead of a direct call
                //$isActive = true;
                //agile_tix_Rest_Route::agile_call_wordpress_webhook($isActive);

                //Instead of automatic activation, if credentials are valid and data is good, unlock the activate button
                //you can always deactivate, but activation is locked behind valid creds
                agile_tix::agile_tix_log_event('agile_verify_credentials_after_save creds are good');
                //assume if we get here the creds are good for now
                update_option('agile_field_credentials_are_valid', true);


            }
        }
    }


    function agile_display_settings_errors()
    {
        settings_errors('agile_options_credentials');
    }


    function agile_activate_webhook()
    {
        $isActivation = isset($_POST['is_activation']) && $_POST['is_activation'] == 1;
        agile_tix::agile_tix_log_event('agile_activate_webhook $isActivation =' . $isActivation);
        agile_tix_Rest_Route::agile_call_wordpress_webhook($isActivation);
        wp_send_json_success();
    }


    function agile_refresh_ats_data()
    {
        $full_refresh = isset($_POST['full_refresh']) && $_POST['full_refresh'] == 1;
        agile_tix_post_creator::ats_universal_refresh_showsList($full_refresh);
        wp_send_json_success();
    }

    //called after manual utility data refresh to update our data collection and post creation stats
    function agile_refresh_utility()
    {
        /*$timeout = get_option('_transient_timeout_agile_api_response');
        $time_stored = time() - ($timeout - HOUR_IN_SECONDS);
        $timeOutMessage = '';
        if ($timeout) {
            $current_time = time();
            $time_stored = $current_time - ($timeout - HOUR_IN_SECONDS);
            $timeOutMessage = 'The show data has been stored for ' . human_time_diff(0, $time_stored) . '.';
        } else {
            //$timeOutMessage = 'The show data does not exist or has already expired. (This does not mean your existing posts are affected)';
        }*/

        $scheduledPost = get_option('agile_field_utility_last_post_scheduled_start');
        $firstPost = get_option('agile_field_utility_last_post_update_start');
        $totalProcessingStart = get_option('agile_field_utility_total_processing_start');
        
        if (!empty($scheduledPost)) {
            $timeOutMessage = date('Y-m-d H:i:s', $scheduledPost);
        } else {
        $timeOutMessage = date('Y-m-d H:i:s');
        }

        if ($scheduledPost != '') {
            $scheduledPostFormatted = human_time_diff($scheduledPost, current_time('timestamp'));
        } else {
            $scheduledPostFormatted = 'Scheduled timestamp not found';
        }

        if ($firstPost != '') {
            $firstPostFormatted = human_time_diff($firstPost, current_time('timestamp'));
            $firstPostDate = date('Y-m-d H:i:s', $firstPost);
        } else {
            $firstPostFormatted = 'Active processing timestamp not found';
            $firstPostDate = 'N/A';
        }
        
        if ($totalProcessingStart != '') {
            $totalProcessingStartFormatted = human_time_diff($totalProcessingStart, current_time('timestamp'));
            $totalProcessingStartDate = date('Y-m-d H:i:s', $totalProcessingStart);
        } else {
            $totalProcessingStartFormatted = 'Total processing timestamp not found';
            $totalProcessingStartDate = 'N/A';
        }

        $lastPost = get_option('agile_field_utility_last_post_update');
        $lastPostFormattedFinished = $lastPost ? human_time_diff($lastPost, current_time('timestamp')) : 'Not found';
        $lastPostDate = $lastPost ? date('Y-m-d H:i:s', $lastPost) : 'N/A';

        $lastRuntime = get_option('agile_field_utility_last_known_runtime');
        $lastRuntimeFormatted = $lastRuntime ? number_format($lastRuntime, 2) : 'Not found';

        update_option('agile_field_utility_update_status', 'Idle');

        $post_count_created = get_option('agile_field_utility_last_post_count_created');
        $post_count_updated = get_option('agile_field_utility_last_post_count_updated');
        $post_count_deleated = get_option('agile_field_utility_last_post_count_deleated');

        wp_send_json_success([
            'updateStatus' => 'Idle',
            'timeOutMessage' => $timeOutMessage,
            'lastPostFormattedScheduled' => $scheduledPostFormatted,
            'first_post_date' => $firstPostDate,
            'time_since_chunk_started' => $firstPostFormatted . ' ago',
            'total_processing_start_date' => $totalProcessingStartDate,
            'lastPostFormattedBegan' => $totalProcessingStartFormatted . ' ago',
            'time_since_post_began' => $totalProcessingStartFormatted . ' ago',
            'last_post_date' => $lastPostDate,
            'time_since_post_finish' => $lastPostFormattedFinished,
            'lastPostFormattedFinished' => $lastPostFormattedFinished,
            'lastRuntimeFormatted' => $lastRuntimeFormatted,
            'post_count_created' => $post_count_created,
            'post_count_updated' => $post_count_updated,
            'post_count_deleated' => $post_count_deleated,
        ]);
    }

    /**
     * Helper function to check which custom style files exist
     * Returns array with keys 'custom-1' and 'custom-2' set to true if files exist
     */
    static function agile_get_available_custom_styles()
    {
        $presets_dir = plugin_dir_path(__FILE__) . 'style-presets/';
        $available = [
            'custom-1' => file_exists($presets_dir . 'custom-1.css'),
            'custom-2' => file_exists($presets_dir . 'custom-2.css')
        ];
        return $available;
    }

    /**
     * AJAX handler to fetch style preset CSS file
     */
    function agile_get_style_preset()
    {
        // Check user permissions
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Insufficient permissions');
        }

        // Get preset name from POST data
        if (!isset($_POST['preset']) || empty($_POST['preset'])) {
            wp_send_json_error('Missing preset name');
        }

        $preset_name = sanitize_text_field($_POST['preset']);

        // Validate preset name to prevent directory traversal
        if (preg_match('/[^a-zA-Z0-9_-]/', $preset_name)) {
            wp_send_json_error('Invalid preset name');
        }

        // Build file path
        $preset_file = plugin_dir_path(__FILE__) . 'style-presets/' . $preset_name . '.css';

        // Check if file exists
        if (!file_exists($preset_file)) {
            wp_send_json_error('Preset file not found');
        }

        // Read file content
        $file_content = file_get_contents($preset_file);

        if ($file_content === false) {
            wp_send_json_error('Failed to read preset file');
        }

        // Return success with file content
        wp_send_json_success([
            'content' => $file_content
        ]);
    }

    /**
     * AJAX handler to save current CSS as a custom style preset
     */
    function agile_save_custom_style_preset()
    {
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Insufficient permissions');
        }

        if (!isset($_POST['css_content'])) {
            wp_send_json_error('Missing CSS content');
        }

        $css_content = wp_unslash($_POST['css_content']);
        
        $css_content_trimmed = trim($css_content);
        if (empty($css_content_trimmed)) {
            wp_send_json_error('CSS content cannot be empty');
        }

        if (!isset($_POST['target_slot']) || empty($_POST['target_slot'])) {
            wp_send_json_error('Target slot is required');
        }

        $target_slot = sanitize_text_field($_POST['target_slot']);

        // Validate target slot
        if (!in_array($target_slot, ['custom-1', 'custom-2'])) {
            wp_send_json_error('Invalid target slot. Must be custom-1 or custom-2');
        }

        $available = self::agile_get_available_custom_styles();
        $is_overwrite = $available[$target_slot];
        $slot_number = ($target_slot === 'custom-1') ? 1 : 2;
        $slot_to_use = $target_slot;

        $presets_dir = plugin_dir_path(__FILE__) . 'style-presets/';
        $preset_file = $presets_dir . $slot_to_use . '.css';

        // Ensure directory exists
        if (!file_exists($presets_dir)) {
            wp_mkdir_p($presets_dir);
        }

        $result = file_put_contents($preset_file, $css_content);

        if ($result === false) {
            wp_send_json_error('Failed to save preset file. Please check file permissions.');
        }

        $message = $is_overwrite 
            ? 'Custom Style ' . $slot_number . ' overwritten successfully'
            : 'Custom Style ' . $slot_number . ' saved successfully';
        
        wp_send_json_success([
            'slot' => $slot_number,
            'preset_name' => $slot_to_use,
            'is_overwrite' => $is_overwrite,
            'message' => $message
        ]);
    }

    //Used to validate content fields to ensure they contain their target replacment token
    static function agile_validate_custom_fields($input, $required_string, $option_name)
    {
        $sanitized = sanitize_text_field($input);
        if ($sanitized != '') {
            //force a non empty string to include the replacment token
            if (strpos($sanitized, $required_string) === false) {
                add_settings_error(
                    $option_name,
                    $option_name . '_error',
                    'The field must contain "' . $required_string . '".',
                    'error'
                );
                // Return the existing option value to prevent saving an invalid input
                return get_option($option_name);
            }
        }


        return $sanitized;
    }

    static function agile_validate_EPG_fields($input, $option_name){
        $sanitized = sanitize_text_field($input);




        return $sanitized;
    }


    //Renders a simple question mark Icon inside the div id
    static function agile_field_explainer($id)
    {
        ?>
        <div id="<?php echo $id ?>" style="display: inline-block; vertical-align:middle;">
            <svg height="24px" width="24px" version="1.1" id="_x32_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
                viewbox="0 0 512 512" xml:space="preserve">
                <style type="text/css">
                    .st0 {
                        fill: #000000;
                    }

                </style>
                <g>
                    <path class="st0" d="M256,0C114.616,0,0,114.612,0,256s114.616,256,256,256s256-114.612,256-256S397.385,0,256,0z M207.678,378.794
                    c0-17.612,14.281-31.893,31.893-31.893c17.599,0,31.88,14.281,31.88,31.893c0,17.595-14.281,31.884-31.88,31.884
                    C221.959,410.678,207.678,396.389,207.678,378.794z M343.625,218.852c-3.596,9.793-8.802,18.289-14.695,25.356
                    c-11.847,14.148-25.888,22.718-37.442,29.041c-7.719,4.174-14.533,7.389-18.769,9.769c-2.905,1.604-4.479,2.95-5.256,3.826
                    c-0.768,0.926-1.029,1.306-1.496,2.826c-0.273,1.009-0.558,2.612-0.558,5.091c0,6.868,0,12.512,0,12.512
                    c0,6.472-5.248,11.728-11.723,11.728h-28.252c-6.475,0-11.732-5.256-11.732-11.728c0,0,0-5.645,0-12.512
                    c0-6.438,0.752-12.744,2.405-18.777c1.636-6.008,4.215-11.718,7.508-16.694c6.599-10.083,15.542-16.802,23.984-21.48
                    c7.401-4.074,14.723-7.455,21.516-11.281c6.789-3.793,12.843-7.91,17.302-12.372c2.988-2.975,5.31-6.05,7.087-9.52
                    c2.335-4.628,3.955-10.067,3.992-18.389c0.012-2.463-0.698-5.702-2.632-9.405c-1.926-3.686-5.066-7.694-9.264-11.29
                    c-8.45-7.248-20.843-12.545-35.054-12.521c-16.285,0.058-27.186,3.876-35.587,8.62c-8.36,4.776-11.029,9.595-11.029,9.595
                    c-4.268,3.718-10.603,3.85-15.025,0.314l-21.71-17.397c-2.719-2.173-4.322-5.438-4.396-8.926c-0.063-3.479,1.425-6.81,4.061-9.099
                    c0,0,6.765-10.43,22.451-19.38c15.62-8.992,36.322-15.488,61.236-15.429c20.215,0,38.839,5.562,54.268,14.661
                    c15.434,9.148,27.897,21.744,35.851,36.876c5.281,10.074,8.525,21.43,8.533,33.38C349.211,198.042,347.248,209.058,343.625,218.852
                    z"></path>
                </g>
            </svg>
        </div>
        <?php
    }


    static function agile_credentials_activate_btn()
    {

        $webHookIsActive = get_option('agile_field_webhook_is_active');
        $isActiveText = $webHookIsActive ? 'Deactivate' : 'Activate';

        $credsAreValid = get_option('agile_field_credentials_are_valid');
        $isStagingSite = agile_tix_Rest_Route::agile_is_staging_site();
        //if the webhook is already active, assume the disable button is active
        //if the webhook is not active, assume the enable button is deactive (it'll get activated as part of credential save if they're valid)

        $disabledText = ($credsAreValid && !$isStagingSite) ? '' : 'disabled';
        //validate both these assumptions against credentials to ensure we're not missing anything
        $requiredCredentials = array('agile_field_domain', 'agile_field_corpOrgID', /*'agile_field_epgID', 'agile_field_guid',*/ /*'agile_field_appKey', 'agile_field_userKey',*/ 'agile_field_password');

        foreach ($requiredCredentials as $cred) {
            $credential = get_option($cred);
            if ($credential == false || $credential == '') {
                //invalid cred, disable the button
                update_option('agile_field_credentials_are_valid', false);
                $disabledText = 'disabled';
                break;
            }
        }

        //check if we are using EPGTAG or EPGID/GUID combo
        $epgID = get_option('agile_field_epgID');
        $guid = get_option('agile_field_guid');
        $useEPGTAG = get_option('agile_field_epgTag');

        if ($epgID == "" || is_null($epgID) ||  $epgID == false || $guid == "" || is_null($guid) ||  $guid == false){
            //Invalid epgID or guid, check if we are using EPGTAG
            if ($useEPGTAG == "" || $useEPGTAG == false || is_null($useEPGTAG) || $useEPGTAG == 0){
                //not using EPGTAG and epgID or guid is bad, error
                update_option('agile_field_credentials_are_valid', false);
                add_settings_error('agile_options_credentials', 'error_code', __('You must provide either a valid EPGID and GUID', 'agile'), 'error');
            }
        }

        // Validate coming soon feed credentials if enabled
        $useComingSoon = get_option('agile_field_use_coming_soon_feed');
        if ($useComingSoon) {
            $comingSoonGuid = get_option('agile_field_coming_soon_guid');
            if ($comingSoonGuid == "" || is_null($comingSoonGuid) || $comingSoonGuid == false) {
                update_option('agile_field_credentials_are_valid', false);
                add_settings_error('agile_options_credentials', 'error_code', __('Coming Soon Feed is enabled but GUID is missing', 'agile'), 'error');
            }
        }





        $buttonClass = $webHookIsActive ? 'agile-webhook-button-deactivate' : 'agile-webhook-button-activate';
        ?>
        <div class="agile-webhook-activation-card">
            <div class="agile-webhook-activation-content">
                <p class="agile-webhook-description">Once your credentials are validated and saved, activate and deactivate automatic show refreshes every quarter hour.</p>
                <p class="agile-webhook-note">These pings are automatically deactivated on uninstall.</p>
                <?php
                if ($isStagingSite) {
                    echo '<p class="agile-webhook-warning">We have detected this is a staging site. Due to security issues, automated pings may not be enabled for staging sites, please use the manual refresh options found in utility.</p>';
                }
                ?>
                <button class="agile-webhook-button <?php echo esc_attr($buttonClass); ?>" id="agile_credentials_activate_webhook" <?php echo ($disabledText) ?>>
                    <?php if ($webHookIsActive): ?>
                        <svg class="agile-webhook-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                            <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"/>
                        </svg>
                        <span class="agile-webhook-button-text">Deactivate</span>
                    <?php else: ?>
                        <svg class="agile-webhook-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                            <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" fill="currentColor"/>
                        </svg>
                        <span class="agile-webhook-button-text">Activate</span>
                    <?php endif; ?>
                </button>
            </div>
        </div>
        <?php

    }


    static function agile_hide_featured_image_conditionally($html, $post_id, $post_thumbnail_id){
        //global $post;    
    
        $hideImg = get_post_meta($post_id, "ATS_HideFeatImg")[0] ?? 0;
        
        /*if (is_single() && !is_home() && !is_archive() && !is_search() && $hideImg && $post_id == $post->ID &&  in_the_loop() && is_main_query()   ) {
            
            $current_post_id = get_queried_object_id();
            if ($post_id == $current_post_id) {
                return ''; // suppress output
            }
        }*/
        if ($hideImg) {
            // Only add the attribute if this is the actual post thumbnail with the right classes
            if (strpos($html, 'wp-post-image') !== false) {
                $html = str_replace('<img', '<img data-carousel-conditional="true"', $html);
            }
        }
        

        return $html;
    }

    /**
     * AJAX handler to fetch current utility metrics
     */
    public static function ajax_get_utility_metrics() {
        // Verify nonce for security
        if (!wp_verify_nonce($_POST['nonce'], 'agile_utility_metrics_nonce')) {
            wp_die('Security check failed');
        }

        // Check user permissions
        if (!current_user_can('manage_options')) {
            wp_die('Insufficient permissions');
        }

        $scheduledPost = get_option('agile_field_utility_last_post_scheduled_start');
        $firstPost = get_option('agile_field_utility_last_post_update_start');
        $totalProcessingStart = get_option('agile_field_utility_total_processing_start');
        
        if (!empty($scheduledPost)) {
            $displayDate = date('Y-m-d H:i:s', $scheduledPost);
            $timeOutMessage = $displayDate . '.';
        } else {
            $timeOutMessage = 'The show data does not exist or has already expired. (This does not mean your existing posts are affected)';
        }

        if ($scheduledPost != '') {
            $scheduledPostFormatted = human_time_diff($scheduledPost, current_time('timestamp'));
        } else {
            $scheduledPostFormatted = 'Scheduled timestamp not found';
        }

        if ($firstPost != '') {
            $firstPostFormatted = human_time_diff($firstPost, current_time('timestamp'));
        } else {
            $firstPostFormatted = 'Active processing timestamp not found';
        }
        
        if ($totalProcessingStart != '') {
            $totalProcessingStartFormatted = human_time_diff($totalProcessingStart, current_time('timestamp'));
        } else {
            $totalProcessingStartFormatted = 'Total processing timestamp not found';
        }

        $lastPost = get_option('agile_field_utility_last_post_update');
        if ($lastPost != '') {
            $lastPostFormatted = human_time_diff($lastPost, current_time('timestamp'));
        } else {
            $lastPostFormatted = 'Last post refresh timestamp not found';
        }

        $lastRuntime = get_option('agile_field_utility_last_known_runtime');
        if ($lastRuntime != '') {
            $lastRuntimeFormatted = number_format($lastRuntime, 2);
        } else {
            $lastRuntimeFormatted = 'Last runtime not found';
        }

        $updateStatus = get_option('agile_field_utility_update_status');
        $post_count_created = (int)(get_option('agile_field_utility_last_post_count_created') ?? 0);
        $post_count_updated = (int)(get_option('agile_field_utility_last_post_count_updated') ?? 0);
        $post_count_deleated = (int)(get_option('agile_field_utility_last_post_count_deleated') ?? 0);
        $webhookIsActive = get_option('agile_field_webhook_is_active') ?? false;
        $currentTime = current_time('timestamp');
        
        // Calculate additional statistics
        $totalPostsProcessed = $post_count_created + $post_count_updated;
        
        // Format dates and times with better presentation
        if (!empty($scheduledPost)) {
            $displayDate = date('Y-m-d H:i:s', $scheduledPost);
            $timeOutMessage = $displayDate;
            $scheduledPostAgo = $scheduledPostFormatted . ' ago';
        } else {
            $timeOutMessage = 'Never';
            $scheduledPostAgo = 'No scheduled refresh found';
        }

        if ($firstPost != '') {
            $firstPostAgo = $firstPostFormatted . ' ago';
            $firstPostDate = date('Y-m-d H:i:s', $firstPost);
        } else {
            $firstPostAgo = 'No active processing found';
            $firstPostDate = 'N/A';
        }
        
        if ($totalProcessingStart != '') {
            $totalProcessingStartAgo = $totalProcessingStartFormatted . ' ago';
            $totalProcessingStartDate = date('Y-m-d H:i:s', $totalProcessingStart);
        } else {
            $totalProcessingStartAgo = 'No total processing start found';
            $totalProcessingStartDate = 'N/A';
        }

        if ($lastPost != '') {
            $lastPostAgo = $lastPostFormatted . ' ago';
            $lastPostDate = date('Y-m-d H:i:s', $lastPost);
            
            // Calculate data freshness
            $dataAge = $currentTime - (int)$lastPost;
            $dataAgeHours = round($dataAge / 3600, 1);
            $dataAgeFormatted = $dataAgeHours < 1 ? round($dataAge / 60, 0) . ' minutes' : $dataAgeHours . ' hours';
        } else {
            $lastPostAgo = 'No refresh completed yet';
            $lastPostDate = 'N/A';
            $dataAgeFormatted = 'Unknown';
        }

        if ($lastRuntime != '') {
            $lastRuntime = (float)$lastRuntime;
            $lastRuntimeMinutes = $lastRuntime > 60 ? number_format($lastRuntime / 60, 2) . ' min' : $lastRuntimeFormatted . ' sec';
        } else {
            $lastRuntimeMinutes = 'N/A';
        }

        // Calculate next scheduled refresh (15 minutes after last ping)
        $nextRefreshTime = '';
        if ($lastPost != '' && $webhookIsActive) {
            $nextRefresh = (int)$lastPost + 900; // 15 minutes = 900 seconds
            if ($nextRefresh > $currentTime) {
                $nextRefreshFormatted = human_time_diff($nextRefresh, $currentTime);
                $nextRefreshTime = 'in ' . $nextRefreshFormatted;
            } else {
                $nextRefreshTime = 'Overdue';
            }
        } elseif (!$webhookIsActive) {
            $nextRefreshTime = 'Webhook inactive';
        } else {
            $nextRefreshTime = 'N/A';
        }

        // Return JSON response
        wp_send_json([
            'update_status' => $updateStatus,
            'time_since_refresh_scheduled' => $timeOutMessage,
            'time_since_post_scheduled' => $scheduledPostAgo,
            'time_since_chunk_started' => $firstPostAgo,
            'time_since_post_began' => $totalProcessingStartAgo,
            'time_since_post_finish' => $lastPostAgo,
            'last_runtime' => $lastRuntimeFormatted,
            'last_runtime_minutes' => $lastRuntimeMinutes,
            'post_count_created' => $post_count_created,
            'post_count_updated' => $post_count_updated,
            'post_count_deleted' => $post_count_deleated,
            'total_processed' => $totalPostsProcessed,
            'data_freshness' => $dataAgeFormatted,
            'next_refresh' => $nextRefreshTime,
            'first_post_date' => $firstPostDate,
            'total_processing_start_date' => $totalProcessingStartDate,
            'last_post_date' => $lastPostDate
        ]);
    }

}