<?php

namespace Attributes\Admin;

use Attributes\Core\Settings;
use Exception;

/**
 * Admin Settings Management Class
 *
 * Handles the plugin's administrative interface, settings registration,
 * and AJAX operations for the WordPress admin panel.
 *
 * @package Attributes\Admin
 * @since   1.1.0
 */
class Admin
{

    /**
     * Core settings instance.
     *
     * @access private
     * @var    Settings
     */
    private Settings $settings;

    /**
     * Admin page hook suffix.
     *
     * @access private
     * @var    string
     */
    private string $page_hook;

    /**
     * Global submenu registry for Pro plugins
     *
     * @access private
     * @var    array
     */
    private static array $pending_submenus = array();

    /**
     * Track if Pro submenus have been registered to prevent duplication
     *
     * @access private
     * @var    bool
     */
    private bool $pro_submenus_registered = false;

    /**
     * Initialize the class and set its properties.
     *
     * @param  Settings $settings Core settings instance.
     * @return void
     */
    public function __construct(Settings $settings)
    {
        $this->settings = $settings;
        $this->init_hooks();
    }

    /**
     * Register all necessary admin hooks.
     *
     * @access private
     * @return void
     */
    private function init_hooks(): void
    {
        // Admin menu and settings - priority 5 to ensure main menu is created first
        add_action('admin_menu', [$this, 'add_settings_page'], 5);
        add_action('admin_init', [$this, 'register_settings']);

        // Pro plugin integration - only if license is valid and not already registered
        if ($this->is_pro_license_valid() && !$this->pro_submenus_registered) {
            add_action('admin_menu', [$this, 'register_pro_submenus_directly'], 15);
        }

        // AJAX handlers
        add_action('wp_ajax_attrua_create_page', [$this, 'handle_create_page']);
        add_action('wp_ajax_attrua_delete_page', [$this, 'handle_delete_page']);
        add_action('wp_ajax_attrua_toggle_redirect', [$this, 'handle_toggle_redirect']);
        add_action('wp_ajax_attrua_check_page_exists', [$this, 'handle_check_page_exists']);

        // Assets
        add_action('attrua_enqueue_admin_assets', [$this, 'enqueue_assets']);

        // Add post state for Attributes pages
        add_filter('display_post_states', [$this, 'add_post_state'], 10, 2);

        // Add UI hook for rows rendering
        add_action('attrua_render_page_rows', [$this, 'render_login_pages'], 10, 1);

        // Add hook for rendering individual rows
        add_action('attrua_render_page_row', [$this, 'render_page_row_callback'], 10, 3);
    }

    /**
     * Add plugin settings page to WordPress admin menu.
     *
     * @access public
     * @return void
     */
    public function add_settings_page(): void
    {
        $icon_url = ATTRUA_URL . 'assets/img/attrua-icon.svg';

        $this->page_hook = add_menu_page(
            __('Attributes User Access', 'attributes-user-access'),
            __('User Access', 'attributes-user-access'),
            'manage_options',
            'attributes-user-access',
            [$this, 'render_settings_page'],
            $icon_url,
            30
        );

        // DIRECT SOLUTION: Immediately check for and register Pro submenus
        // This ensures Pro submenus are available immediately after main menu creation
        $this->register_pro_submenus_directly();

        // After creating the main menu, add pending submenus
        add_action('admin_menu', array(self::class, 'add_pending_submenus'), 99);
    }

    /**
     * Register plugin settings and sections.
     *
     * @access public
     * @return void
     */
    public function register_settings(): void
    {
        // Register Pages Settings
        register_setting(
            'attrua_pages_group',
            'attrua_pages_options',
            [
                'type' => 'array',
                'description' => __('Authentication pages settings', 'attributes-user-access'),
                'sanitize_callback' => [$this, 'sanitize_pages_settings'],
                'default' => [
                    'login' => null
                ],
                'show_in_rest' => false
            ]
        );

        // Register Redirects Settings
        register_setting(
            'attrua_pages_group',
            'attrua_redirect_options',
            [
                'type' => 'array',
                'description' => __('Page redirect settings', 'attributes-user-access'),
                'sanitize_callback' => [$this, 'sanitize_redirect_settings'],
                'default' => [
                    'login' => false
                ]
            ]
        );

        // Add settings sections
        add_settings_section(
            'attrua_pages',
            __('Authentication Pages', 'attributes-user-access'),
            [$this, 'render_pages_section'],
            'attributes-user-access'
        );

        /**
         * Hook: attrua_register_settings_sections
         * 
         * Fired during settings registration.
         * Use this hook to register additional settings sections.
         *

         */
        do_action('attrua_register_settings_sections');
    }

    /**
     * Register submenu from external plugins (Pro plugins)
     * 
     * @access public
     * @param  array $submenu_config Submenu configuration
     * @return bool  Whether submenu was registered successfully
     */
    public static function register_external_submenu(array $submenu_config): bool
    {
        // Validate required fields
        $required_fields = ['page_title', 'menu_title', 'capability', 'menu_slug', 'callback'];
        foreach ($required_fields as $field) {
            if (empty($submenu_config[$field])) {
                return false;
            }
        }

        // Set default position if not provided
        if (!isset($submenu_config['position'])) {
            $submenu_config['position'] = null;
        }

        // Store pending submenu
        self::$pending_submenus[] = $submenu_config;

        // If admin_menu has already run AND we're in admin context, add immediately
        // and mark it as processed to prevent duplication
        if (did_action('admin_menu') && is_admin()) {
            self::add_pending_submenu($submenu_config);
            // Mark this submenu as processed by removing it from pending queue
            $last_key = array_key_last(self::$pending_submenus);
            if ($last_key !== null) {
                self::$pending_submenus[$last_key]['processed'] = true;
            }
        }

        return true;
    }

    /**
     * Add pending submenus after parent menu is created
     *
     * @access public
     * @return void
     */
    public static function add_pending_submenus(): void
    {
        foreach (self::$pending_submenus as $submenu_config) {
            // Skip already processed submenus to prevent duplication
            if (isset($submenu_config['processed']) && $submenu_config['processed']) {
                continue;
            }
            self::add_pending_submenu($submenu_config);
        }
        self::$pending_submenus = array(); // Clear after adding
    }
    /**
     * Add individual submenu
     *
     * @access private
     * @param  array $config Submenu configuration
     * @return string|false  Hook name on success, false on failure
     */
    private static function add_pending_submenu(array $config)
    {
        $hook = add_submenu_page(
            'attributes-user-access',
            $config['page_title'],
            $config['menu_title'],
            $config['capability'],
            $config['menu_slug'],
            $config['callback'],
            $config['position']
        );

        // Call load hook if provided
        if ($hook && !empty($config['load_hook'])) {
            add_action("load-{$hook}", $config['load_hook']);
        }

        return $hook;
    }

    /**
     * Enqueue admin scripts and styles.
     *
     * @access public
     * @param  string $hook_suffix The current admin page hook suffix.
     * @return void
     */
    public function enqueue_assets(string $hook_suffix): void
    {
        if ($hook_suffix !== $this->page_hook) {
            return;
        }

        wp_localize_script(
            'attrua-admin',
            'attruaAdmin',
            array_merge(
                $this->get_script_data(),
                ['wpLoginUrl' => wp_login_url()]
            )
        );
    }

    /**
     * Get localized script data.
     *
     * @access private
     * @return array
     */
    private function get_script_data(): array
    {
        $page_types = $this->get_page_defaults();
        $script_data = [
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('attrua_admin'),
            'pageTypes' => [],
            'i18n' => [
                'editPage' => __('Edit Page', 'attributes-user-access'),
                'viewPage' => __('View Page', 'attributes-user-access'),
                'delete' => __('Delete', 'attributes-user-access'),
                'createPage' => __('Create Page', 'attributes-user-access'),
                'creatingPage' => __('Creating...', 'attributes-user-access'),
                'deletingPage' => __('Deleting...', 'attributes-user-access'),
                'confirmDelete' => __('Are you sure you want to delete this page?', 'attributes-user-access'),
                'pageCreated' => __('Page created successfully.', 'attributes-user-access'),
                'pageDeleted' => __('Page deleted successfully.', 'attributes-user-access'),
                'settingsSaved' => __('Settings saved.', 'attributes-user-access'),
                'error' => __('An error occurred.', 'attributes-user-access'),
                'redirectToggle' => __('Redirect WordPress page to this page', 'attributes-user-access'),
                'titleRequired' => __('Please enter a page title.', 'attributes-user-access'),
                'saving' => __('Saving...', 'attributes-user-access'),
                'saveChanges' => __('Save Changes', 'attributes-user-access'),
                'retry' => __('Retry', 'attributes-user-access'),
                'dismiss' => __('Dismiss this notice', 'attributes-user-access'),
                'invalidData' => __('Invalid data provided.', 'attributes-user-access')
            ]
        ];

        // Transform page defaults to script data format
        foreach ($page_types as $type => $config) {
            $script_data['pageTypes'][$type] = [
                'title' => $config['title'],
                'slug' => $config['slug']
            ];
        }

        return $script_data;
    }

    /**
     * Validates settings based on active tab context.
     *
     * @access public
     * @param  array $input Raw settings input
     * @return array Sanitized settings
     */
    public function validate_settings(array $input): array
    {
        $active_tab = 'pages'; // Default
        if (isset($_POST['tab'])) {
            // Verify nonce before processing POST data
            check_admin_referer('attrua_settings_action');
            $active_tab = sanitize_key(wp_unslash($_POST['tab']));
        }
        $validator_method = "validate_{$active_tab}_settings";

        if (method_exists($this, $validator_method)) {
            return $this->$validator_method($input);
        }

        return $input;
    }

    /**
     * Render the settings page content.
     *
     * @access public
     * @return void
     */
    public function render_settings_page(): void
    {
        if (!current_user_can('manage_options')) {
            wp_die(__('You do not have sufficient permissions to access this page.', 'attributes-user-access'));
        }

        require_once ATTRUA_PATH . 'display/admin/settings-page.php';
    }

    /**
     * Render pages section header
     * 
     * @access public
     * @return void
     */
    public function render_pages_section(): void
    {
        // Optional header content for the pages section
    }

    /**
     * Render login page rows
     *
     * @access public
     * @param  bool $has_premium_features Whether premium features are active
     * @return void
     */
    public function render_login_pages($has_premium_features = false): void
    {
        // Render row for the login page type
        $this->render_page_row('login');
    }

    /**
     * Render individual page configuration row
     * 
     * @access private
     * @param  string $page_type Page type identifier
     * @return void
     */
    private function render_page_row(string $page_type): void
    {
        // Get page ID from settings
        $page_id = $this->settings->get("pages.{$page_type}");

        // If page ID is invalid or the page doesn't exist, try to find by shortcode
        if (!$page_id || !get_post($page_id)) {
            $page_id = $this->get_page_id_for_type($page_type);

            // Update settings if found
            if ($page_id) {
                $this->settings->set("pages.{$page_type}", $page_id);
            }
        }

        // Get default options for this page type
        $page_defaults = $this->get_page_defaults();
        $options = $page_defaults[$page_type] ?? [
            'title' => ucfirst($page_type),
            'slug' => $page_type,
            'shortcode' => "[attributes_{$page_type}_form]"
        ];

        // Start row with the required class
        $row_class = apply_filters('attrua_page_row_class', 'attrua-page-row ' . esc_attr($page_type), $page_type);
        echo '<tr class="' . esc_attr($row_class) . '" data-page-type="' . esc_attr($page_type) . '">';

        // Title column
        $this->render_title_column($page_type, $page_id, $options);

        // Slug column
        $this->render_slug_column($page_type, $page_id, $options);

        // Shortcode column
        $this->render_shortcode_column($page_type, $page_id, $options);

        // Actions column
        $this->render_actions_column($page_type, $page_id, $options);

        // Redirect column
        $this->render_redirect_column($page_type, $page_id, $options);

        echo '</tr>';
    }

    /**
     * Callback for rendering individual page rows
     * 
     * @param string $page_type Page type identifier
     * @param int|null $page_id Page ID or null if not yet created
     * @param array $options Options for the page row
     * @return void
     */
    public function render_page_row_callback(string $page_type, ?int $page_id, array $options): void
    {
        $this->render_page_row($page_type, $page_id, $options);
    }

    /**
     * Render title column
     *
     * @access private
     * @param  string  $page_type Page type identifier
     * @param  int     $page_id   Page ID or null
     * @param  array   $options   Options for the page row
     * @return void
     */
    private function render_title_column(string $page_type, ?int $page_id, array $options): void
    {
        // Determine if input should be displayed
        $display_style = $page_id ? 'style="display: none"' : '';

        echo '<th scope="row">';

        if ($page_id) {
            $page = get_post($page_id);
            if ($page) {
                echo '<strong class="attrua-page-title-display">' . esc_html($page->post_title) . '</strong>';
            } else {
                echo '<strong class="attrua-page-title-display">' . esc_html($options['title']) . '</strong>';
            }
        }

        // Always render the input field, even if hidden
?>
        <input type="text"
            class="attrua-page-title"
            name="attrua_pages_options[<?php echo esc_attr($page_type); ?>_title]"
            value="<?php echo esc_attr($options['title']); ?>"
            placeholder="<?php echo esc_attr($options['title']); ?>"
            <?php echo $display_style; ?> />
    <?php

        // Add this after the title is output:
        do_action('attrua_after_page_title', $page_type, $page_id, $options);

        echo '</th>';
    }

    /**
     * Render slug column
     *
     * @access private
     * @param  string  $page_type Page type identifier
     * @param  int     $page_id   Page ID or null
     * @param  array   $options   Options for the page row
     * @return void
     */
    private function render_slug_column(string $page_type, ?int $page_id, array $options): void
    {
        // Determine if input should be displayed
        $display_style = $page_id ? 'style="display: none"' : '';

        echo '<td>';

        if ($page_id) {
            $slug = get_post_field('post_name', $page_id);
            echo '<strong class="attrua-page-slug-display"><code class="attrua-page-prefix">/</code> ' . esc_html($slug) . '</strong>';
        }

        // Always render the input field for consistent behavior
    ?>
        <input type="text"
            class="attrua-page-slug"
            name="attrua_pages_options[<?php echo esc_attr($page_type); ?>_slug]"
            value="<?php echo esc_attr($options['slug']); ?>"
            placeholder="<?php echo esc_attr($options['slug']); ?>"
            <?php echo $display_style; ?> />
        <?php

        do_action('attrua_after_page_slug', $page_type, $page_id, $options);

        echo '</td>';
    }

    /**
     * Render shortcode column
     *
     * @access private
     * @param  string  $page_type Page type identifier
     * @param  int     $page_id   Page ID or null
     * @param  array   $options   Options for the page row
     * @return void
     */
    private function render_shortcode_column(string $page_type, ?int $page_id, array $options): void
    {
        echo '<td style="width: 200px;">';

        if ($page_id) {
        ?>
            <div class="attrua-page-shortcode">
                <code><?php echo esc_html($options['shortcode']); ?></code>
                <button type="button"
                    class="attrua-copy-shortcode"
                    data-shortcode="<?php echo esc_attr($options['shortcode']); ?>">
                    <i class="ti ti-copy"></i>
                </button>
            </div>
        <?php
        }

        do_action('attrua_after_page_shortcode', $page_type, $page_id, $options);

        echo '</td>';
    }

    /**
     * Render actions column
     *
     * @access private
     * @param  string  $page_type Page type identifier
     * @param  int     $page_id   Page ID or null
     * @param  array   $options   Options for the page row
     * @return void
     */
    private function render_actions_column(string $page_type, ?int $page_id, array $options): void
    {
        echo '<td style="width: 300px;">';
        echo '<div class="attrua-page-control">';

        // Generate nonce for AJAX operations
        $admin_nonce = wp_create_nonce('attrua_admin');

        if ($page_id) {
        ?>
            <div class="attrua-page-actions">
                <a href="<?php echo esc_url(get_edit_post_link($page_id)); ?>" class="button">
                    <i class="ti ti-pencil"></i>&nbsp;<?php esc_html_e('Edit Page', 'attributes-user-access'); ?>
                </a>
                <a href="<?php echo esc_url(get_permalink($page_id)); ?>" class="button" target="_blank">
                    <i class="ti ti-eye"></i>&nbsp;<?php esc_html_e('View Page', 'attributes-user-access'); ?>
                </a>
                <button type="button"
                    class="button attrua-delete"
                    data-page-id="<?php echo esc_attr($page_id); ?>"
                    data-page-type="<?php echo esc_attr($page_type); ?>"
                    data-nonce="<?php echo esc_attr($admin_nonce); ?>">
                    <i class="ti ti-trash"></i>&nbsp;<?php esc_html_e('Delete', 'attributes-user-access'); ?>
                </button>
            </div>
        <?php
        } else {
        ?>
            <button type="button"
                class="button attrua-create-page"
                data-page-type="<?php echo esc_attr($page_type); ?>"
                data-default-title="<?php echo esc_attr($options['title']); ?>"
                data-default-slug="<?php echo esc_attr($options['slug']); ?>"
                data-nonce="<?php echo esc_attr($admin_nonce); ?>">
                <?php esc_html_e('Create Page', 'attributes-user-access'); ?>
            </button>
        <?php
        }

        echo '</div>';
        echo '</td>';
    }

    /**
     * Render redirect column
     *
     * @access private
     * @param  string  $page_type Page type identifier
     * @param  int     $page_id   Page ID or null
     * @param  array   $options   Options for the page row
     * @return void
     */
    private function render_redirect_column(string $page_type, ?int $page_id, array $options): void
    {
        echo '<td>';
        if ($page_id) {
            // Get redirect status
            $redirect_enabled = $this->settings->get("redirects.{$page_type}", false);

            // Get URLs
            $wp_url = $this->get_wp_url($page_type);
            $custom_url = get_permalink($page_id);

            // Generate nonce for AJAX operations
            $admin_nonce = wp_create_nonce('attrua_admin');

        ?>
            <label class="attrua-redirect-toggle">
                <input type="checkbox"
                    name="attrua_redirect_options[<?php echo esc_attr($page_type); ?>]"
                    value="1"
                    <?php checked($redirect_enabled); ?>
                    data-page-type="<?php echo esc_attr($page_type); ?>"
                    data-wp-url="<?php echo esc_url($wp_url); ?>"
                    data-custom-url="<?php echo esc_url($custom_url); ?>"
                    data-nonce="<?php echo esc_attr($admin_nonce); ?>">
                <span class="slider"></span>
                <code class="attrua-redirect-url"><?php echo esc_url($redirect_enabled ? $custom_url : $wp_url); ?></code>
            </label>
<?php
        }

        do_action('attrua_after_page_actions', $page_type, $page_id, $options);

        echo '</td>';
    }

    /**
     * Get page defaults for different page types
     * 
     * @access public
     * @return array Configuration for different page types
     */
    private function get_page_defaults(): array
    {
        global $wp_filter;

        // Safely inspect the filter if it exists
        if (isset($wp_filter['attrua_page_defaults'])) {
            $hook = $wp_filter['attrua_page_defaults'];

            // WP_Hook has a public property 'callbacks' which is an array
            if (property_exists($hook, 'callbacks') && is_array($hook->callbacks)) {
                foreach ($hook->callbacks as $priority => $callbacks) {

                    foreach ($callbacks as $id => $callback_data) {
                        $callback_info = 'Unknown callback type';

                        if (isset($callback_data['function'])) {
                            if (is_array($callback_data['function'])) {
                                if (is_object($callback_data['function'][0])) {
                                    $callback_info = get_class($callback_data['function'][0]) . "->" . $callback_data['function'][1];
                                } else {
                                    $callback_info = $callback_data['function'][0] . "::" . $callback_data['function'][1];
                                }
                            } elseif (is_string($callback_data['function'])) {
                                $callback_info = $callback_data['function'];
                            } elseif (is_callable($callback_data['function'])) {
                                $callback_info = 'Anonymous function';
                            }
                        }
                    }
                }
            }
        }

        $defaults = [
            'login' => [
                'title' => __('Login', 'attributes-user-access'),
                'slug' => 'login',
                'shortcode' => '[attributes_login_form]',
            ]
        ];

        // Apply the filter
        $filtered = apply_filters('attrua_page_defaults', $defaults);

        return $filtered;
    }

    /**
     * Gets page ID for a specific page type
     *
     * @access private
     * @param  string $page_type The page type identifier
     * @return int|null The page ID or null if not found
     */
    private function get_page_id_for_type(string $page_type): ?int
    {
        // Get page ID from settings
        $settings = get_option('attrua_pages_options', []);
        $page_id = $settings[$page_type] ?? null;

        // If page ID is not set or page doesn't exist, try to find by shortcode
        if (!$page_id || !get_post($page_id)) {
            // Get shortcode for this page type
            $page_defaults = $this->get_page_defaults();
            $shortcode = isset($page_defaults[$page_type]) ? $page_defaults[$page_type]['shortcode'] : '';

            if ($shortcode) {
                $page_id = $this->find_page_with_shortcode($shortcode);

                // Update the setting to maintain consistency
                if ($page_id) {
                    $settings[$page_type] = $page_id;
                    update_option('attrua_pages_options', $settings);
                }
            }
        }

        return $page_id;
    }

    /**
     * Find a page containing a specific shortcode.
     *
     * @since  1.1.0
     * @access private
     * @param  string $shortcode Full shortcode text to search for
     * @return int|null Page ID if found, null otherwise
     */
    private function find_page_with_shortcode(string $shortcode): ?int
    {
        global $wpdb;

        // Extract shortcode name without brackets and attributes
        preg_match('/^\[([\w_-]+).*?\]$/', $shortcode, $matches);
        $shortcode_name = $matches[1] ?? '';

        if (empty($shortcode_name)) {
            return null;
        }

        // Direct SQL search for efficiency
        $shortcode_pattern = $wpdb->esc_like($shortcode);

        // This is the correct way to prepare the SQL:
        $sql = $wpdb->prepare(
            "SELECT ID FROM {$wpdb->posts} 
            WHERE post_type = %s 
            AND post_status IN ('publish', 'draft', 'private') 
            AND post_content LIKE %s 
            LIMIT 1",
            'page',
            '%' . $shortcode_pattern . '%'
        );

        // Now $sql is a string, not a closure
        $page_id = $wpdb->get_var($sql);

        if ($page_id) {
            // Verify with has_shortcode for certainty
            $content = get_post_field('post_content', $page_id);

            if (has_shortcode($content, $shortcode_name)) {
                return (int) $page_id;
            }

            // Double check with direct string comparison
            if (strpos($content, $shortcode) !== false) {
                return (int) $page_id;
            }
        }

        /**
         * Filter to override page search results
         *
         * Allows Pro to implement more advanced search logic
         *

         * @param null|int $page_id The page ID found, or null
         * @param string $shortcode The shortcode to search for
         * @return null|int Modified page ID
         */
        return apply_filters('attrua_find_page_by_shortcode', null, $shortcode);
    }

    /**
     * Generate a unique slug for a page.
     *
     * @access private
     * @param  string $desired_slug The requested slug
     * @param  string $title The page title for fallback
     * @return string A unique slug
     */
    private function generate_unique_slug(string $desired_slug, string $title): string
    {
        // Check if the slug is already available
        $existing_page = get_page_by_path($desired_slug);

        if (!$existing_page) {
            return $desired_slug; // Slug is available, use it
        }

        // Try using WordPress built-in function
        $unique_slug = wp_unique_post_slug(
            $desired_slug,
            0,  // post ID (0 for new posts)
            'publish',
            'page',
            0   // parent ID
        );

        // If WordPress gives us something different, use it
        if ($unique_slug !== $desired_slug) {
            return $unique_slug;
        }

        // As a last resort, add a short random suffix
        $random_suffix = substr(md5(uniqid(wp_rand(), true)), 0, 6);
        return $desired_slug . '-' . $random_suffix;
    }

    /**
     * Clean page cache thoroughly.
     *
     * @access private
     * @param  int $page_id Page ID to clean cache for
     * @return void
     */
    private function clean_page_cache(int $page_id): void
    {
        // Basic WordPress cache cleaning
        clean_post_cache($page_id);

        // Clear object caches
        wp_cache_delete($page_id, 'posts');

        // Clear query caches that might include this page
        wp_cache_delete('all_page_ids', 'posts');
        wp_cache_delete('get_pages', 'posts');

        /**
         * Filter to determine if rewrite rules should be refreshed
         *

         * @param bool $refresh Whether to refresh rewrite rules
         * @return bool Modified decision
         */
        $refresh_rules = apply_filters('attrua_refresh_rewrite_rules', false);
        if ($refresh_rules) {
            flush_rewrite_rules(false);
        }

        /**
         * Action hook for plugins to do additional cache cleaning
         *

         * @param int $page_id The ID of the page being cleaned
         */
        do_action('attrua_after_clean_page_cache', $page_id);
    }

    /**
     * Handle AJAX page creation request.
     *
     * Creates a new WordPress page with the appropriate shortcode
     * while ensuring proper validation, error handling, and preventing duplicates.
     * Designed to be extensible for Pro plugin.
     *
     * @access public
     * @return void
     */
    public function handle_create_page(): void
    {
        // 1. Security validation
        check_ajax_referer('attrua_admin');

        if (!current_user_can('manage_options')) {
            wp_send_json_error([
                'message' => __('Permission denied.', 'attributes-user-access'),
                'code' => 'permission_denied'
            ]);
        }

        // 2. Validate and sanitize input data
        $page_type = isset($_POST['page_type']) ? sanitize_key($_POST['page_type']) : '';
        // Extract title and slug from the array structure used in the form
        $title = '';
        $slug = '';

        // This allows backward compatibility and alternative submission methods
        if (empty($title) && isset($_POST['title'])) {
            $title = sanitize_text_field(wp_unslash($_POST['title']));
        }

        if (empty($slug) && isset($_POST['slug'])) {
            $slug = sanitize_title(wp_unslash($_POST['slug']));
        }

        if (empty($page_type)) {
            wp_send_json_error([
                'message' => __('Missing page type.', 'attributes-user-access'),
                'code' => 'missing_page_type'
            ]);
        }

        // 3. Get page type configurations
        $page_defaults = $this->get_page_defaults();

        // Verify this is a supported page type
        if (!isset($page_defaults[$page_type])) {
            wp_send_json_error([
                'message' => sprintf(__('Unsupported page type: %s. Available types: %s', 'attributes-user-access'), $page_type, implode(', ', array_keys($page_defaults))),
                'code' => 'unsupported_page_type',
                'available_types' => array_keys($page_defaults),
                'requested_type' => $page_type
            ]);
        }

        // 4. Set page properties with default fallbacks
        $page_title = !empty($title) ? $title : $page_defaults[$page_type]['title'];
        $page_slug = !empty($slug) ? $slug : $page_defaults[$page_type]['slug'];
        $shortcode = $page_defaults[$page_type]['shortcode'];

        // 4.1 Validate the slug - prevent any slugs with numbers
        if (preg_match('/\d/', $page_slug)) {
            wp_send_json_error([
                'message' => __('Slugs with numbers are not allowed. Please choose a slug with only letters, hyphens, and underscores.', 'attributes-user-access'),
                'code' => 'invalid_slug_pattern',
                'field' => 'slug'  // Indicate which field has the error
            ]);
            return;
        }

        // 4.2 Check if slug already exists
        $existing_page = get_page_by_path($page_slug);
        if ($existing_page) {
            wp_send_json_error([
                'message' => __('This slug is already in use. Please choose a different, unique slug.', 'attributes-user-access'),
                'code' => 'slug_already_exists',
                'field' => 'slug'  // Indicate which field has the error
            ]);
            return;
        }

        // 5. Check for protection against duplicate submissions
        $transient_key = 'attrua_creating_' . $page_type . '_page';
        if (get_transient($transient_key)) {
            wp_send_json_error([
                'message' => __('Page creation already in progress. Please wait.', 'attributes-user-access'),
                'code' => 'creation_in_progress'
            ]);
        }

        // Set a short-lived transient to prevent duplicate submissions
        set_transient($transient_key, true, 30);

        // Allow Pro version to perform pre-creation actions or validations
        $pre_creation_result = apply_filters('attrua_before_page_creation', null, $page_type, $page_title, $page_slug, $shortcode);

        // Check if pre-creation filter wants to override the normal flow
        if ($pre_creation_result !== null) {
            delete_transient($transient_key);

            if (is_wp_error($pre_creation_result)) {
                wp_send_json_error([
                    'message' => $pre_creation_result->get_error_message(),
                    'code' => $pre_creation_result->get_error_code()
                ]);
            } elseif (is_array($pre_creation_result)) {
                wp_send_json_success($pre_creation_result);
            }

            return;
        }

        try {
            // 6. Check if page already exists in settings
            $existing_pages = $this->settings->get('pages', []);

            if (!empty($existing_pages[$page_type])) {
                $existing_id = intval($existing_pages[$page_type]);
                $existing_page = get_post($existing_id);

                if ($existing_page && $existing_page->post_status !== 'trash') {
                    delete_transient($transient_key);
                    wp_send_json_success([
                        'page_id' => $existing_id,
                        'title' => $existing_page->post_title,
                        'slug' => $existing_page->post_name,
                        'page_type' => $page_type,
                        'edit_url' => get_edit_post_link($existing_id, 'raw'),
                        'view_url' => get_permalink($existing_id),
                        'message' => __('Page already exists and is configured.', 'attributes-user-access'),
                        'already_exists' => true
                    ]);
                    return;
                }
            }

            // 7. Search for existing page with this shortcode
            $existing_id = $this->find_page_with_shortcode($shortcode);
            if ($existing_id) {
                // Update settings to use this existing page
                $this->settings->set("pages.{$page_type}", $existing_id);

                // Update page metadata
                update_post_meta($existing_id, '_attrua_page_type', $page_type);

                $existing_page = get_post($existing_id);
                delete_transient($transient_key);

                wp_send_json_success([
                    'page_id' => $existing_id,
                    'title' => $existing_page->post_title,
                    'slug' => $existing_page->post_name,
                    'page_type' => $page_type,
                    'edit_url' => get_edit_post_link($existing_id, 'raw'),
                    'view_url' => get_permalink($existing_id),
                    'message' => __('Found existing page with matching shortcode.', 'attributes-user-access'),
                    'found_existing' => true
                ]);
                return;
            }

            // 8. Create the page (no slug modification - using exact slug as specified)
            $page_data = [
                'post_title' => $page_title,
                'post_name' => $page_slug,
                'post_content' => $shortcode,
                'post_status' => 'publish',
                'post_type' => 'page'
            ];

            // Allow modification of page data before insertion
            $page_data = apply_filters('attrua_page_creation_data', $page_data, $page_type);

            // Insert the page
            $page_id = wp_insert_post($page_data, true);

            if (is_wp_error($page_id)) {
                delete_transient($transient_key);
                wp_send_json_error([
                    'message' => $page_id->get_error_message(),
                    'code' => $page_id->get_error_code()
                ]);
                return;
            }

            // 9. Update settings and metadata
            $this->settings->set("pages.{$page_type}", $page_id);
            update_post_meta($page_id, '_attrua_page_type', $page_type);

            // Allow additional post-creation actions from Pro
            do_action('attrua_after_page_creation', $page_id, $page_type, $page_data);

            // 10. Clean caches
            $this->clean_page_cache($page_id);

            // 11. Remove transient protection
            delete_transient($transient_key);

            // 12. Generate success message
            $message = __('Page created successfully.', 'attributes-user-access');

            // Allow customization of the response
            $response_data = apply_filters('attrua_page_creation_response', [
                'page_id' => $page_id,
                'title' => $page_title,
                'slug' => $page_slug,
                'page_type' => $page_type,
                'edit_url' => get_edit_post_link($page_id, 'raw'),
                'view_url' => get_permalink($page_id),
                'message' => $message
            ], $page_type);

            wp_send_json_success($response_data);
        } catch (Exception $e) {
            delete_transient($transient_key);
            wp_send_json_error([
                'message' => $e->getMessage(),
                'code' => 'exception'
            ]);
        }
    }

    /**
     * Handle AJAX page check existence request.
     *
     * Used as a recovery mechanism when the initial page creation AJAX
     * might have succeeded but the response failed to reach the client.
     *
     * @access public
     * @return void
     */
    public function handle_check_page_exists(): void
    {
        // Security checks
        check_ajax_referer('attrua_admin');

        if (!current_user_can('manage_options')) {
            wp_send_json_error([
                'message' => __('Permission denied.', 'attributes-user-access'),
                'code' => 'permission_denied'
            ]);
        }

        // Get page type from request
        $page_type = isset($_POST['page_type']) ? sanitize_key($_POST['page_type']) : '';

        if (empty($page_type)) {
            wp_send_json_error([
                'message' => __('Missing page type.', 'attributes-user-access'),
                'code' => 'missing_page_type'
            ]);
        }

        // Prepare response
        $response = [
            'exists' => false,
            'page_type' => $page_type,
        ];

        // Check if page exists in settings
        $page_id = $this->settings->get("pages.{$page_type}");

        if ($page_id) {
            $page = get_post($page_id);

            if ($page && $page->post_status === 'publish') {
                $response['exists'] = true;
                $response['page_data'] = [
                    'page_id' => $page_id,
                    'title' => $page->post_title,
                    'slug' => $page->post_name,
                    'edit_url' => get_edit_post_link($page_id, 'raw'),
                    'view_url' => get_permalink($page_id)
                ];
            }
        }

        // If not found in settings, check by shortcode
        if (!$response['exists']) {
            $page_defaults = $this->get_page_defaults();

            if (isset($page_defaults[$page_type])) {
                $shortcode = $page_defaults[$page_type]['shortcode'];
                $found_id = $this->find_page_with_shortcode($shortcode);

                if ($found_id) {
                    $page = get_post($found_id);
                    $response['exists'] = true;
                    $response['page_data'] = [
                        'page_id' => $found_id,
                        'title' => $page->post_title,
                        'slug' => $page->post_name,
                        'edit_url' => get_edit_post_link($found_id, 'raw'),
                        'view_url' => get_permalink($found_id),
                        'found_by' => 'shortcode'
                    ];

                    // Update settings to maintain consistency
                    $this->settings->set("pages.{$page_type}", $found_id);
                }
            }
        }

        wp_send_json_success($response);
    }

    /**
     * Handle AJAX page deletion request.
     *
     * @access public
     * @return void
     */
    public function handle_delete_page(): void
    {
        check_ajax_referer('attrua_admin');

        if (!current_user_can('manage_options')) {
            wp_send_json_error([
                'message' => __('Permission denied.', 'attributes-user-access'),
                'code' => 'permission_denied'
            ]);
        }

        $page_id = intval($_POST['page_id'] ?? 0);
        $page_type = isset($_POST['page_type']) ? sanitize_key($_POST['page_type']) : '';

        if (!$page_id || !$page_type) {
            wp_send_json_error([
                'message' => __('Invalid request.', 'attributes-user-access'),
                'code' => 'invalid_request'
            ]);
        }

        $result = wp_delete_post($page_id, true);

        if (!$result) {
            wp_send_json_error([
                'message' => __('Failed to delete page.', 'attributes-user-access'),
                'code' => 'delete_failed'
            ]);
        }

        // Remove from settings using settings manager
        $this->settings->set("pages.{$page_type}", null);
        $this->settings->set("redirects.{$page_type}", false);

        wp_send_json_success([
            'message' => __('Page deleted successfully.', 'attributes-user-access')
        ]);
    }

    /**
     * Handle AJAX redirect toggle request.
     *
     * @access public
     * @return void
     */
    public function handle_toggle_redirect(): void
    {
        check_ajax_referer('attrua_admin');

        if (!current_user_can('manage_options')) {
            wp_send_json_error([
                'message' => __('Permission denied.', 'attributes-user-access'),
                'code' => 'permission_denied'
            ]);
        }

        $page_type = isset($_POST['page_type']) ? sanitize_key($_POST['page_type']) : '';
        $enabled = isset($_POST['enabled']) ? filter_var(wp_unslash($_POST['enabled']), FILTER_VALIDATE_BOOLEAN) : false;

        if (!$page_type) {
            wp_send_json_error([
                'message' => __('Invalid request.', 'attributes-user-access'),
                'code' => 'invalid_request'
            ]);
        }

        // Update redirect settings using settings manager
        $this->settings->set("redirects.{$page_type}", $enabled);

        wp_send_json_success([
            'message' => __('Setting updated successfully.', 'attributes-user-access'),
            'page_type' => $page_type,
            'enabled' => $enabled
        ]);
    }

    /**
     * Add post state to Attributes pages in the pages list
     * 
     * @param array   $post_states Array of post states
     * @param WP_Post $post        Post object
     * @return array Modified post states
     */
    public function add_post_state($post_states, $post): array
    {
        // Get all Attributes pages
        $pages_option = get_option('attrua_pages_options', []);

        // Filter out empty values 
        $page_ids = array_filter($pages_option, function ($value) {
            return !empty($value) && is_numeric($value);
        });

        // Check if current post is an Attributes page
        if (in_array($post->ID, $page_ids, true)) {
            // Find what type of page this is
            $page_type = array_search($post->ID, $pages_option, true);

            $post_states['attrua_page'] = 'Attributes';
        }

        return $post_states;
    }

    /**
     * Sanitize pages settings
     *
     * @param array $input The input array to sanitize
     * @return array Sanitized input
     */
    public function sanitize_pages_settings($input): array
    {
        return $this->sanitize_settings_array($input, 'pages');
    }

    /**
     * Sanitize redirect settings
     *
     * @param array $input The input array to sanitize
     * @return array Sanitized input
     */
    public function sanitize_redirect_settings($input): array
    {
        return $this->sanitize_settings_array($input, 'redirects');
    }

    /**
     * Generic function to sanitize settings arrays
     *
     * @param array  $input Input array to sanitize
     * @param string $type  Type of settings (pages, redirects)
     * @return array Sanitized array
     */
    private function sanitize_settings_array($input, $type): array
    {
        // Get existing values
        $option_name = $type === 'pages' ? 'attrua_pages_options' : 'attrua_redirect_options';
        $existing_values = get_option($option_name, []);

        // If input is null or empty, preserve existing values
        if (empty($input)) {
            return $existing_values;
        }

        $sanitized = [];
        $page_types = array_keys($this->get_page_defaults());

        foreach ($page_types as $key) {
            if ($type === 'pages') {
                // Sanitize as integer or null for page IDs
                $sanitized[$key] = isset($input[$key]) ? absint($input[$key]) : ($existing_values[$key] ?? null);
            } else {
                // Sanitize as boolean for redirects
                $sanitized[$key] = isset($input[$key]) ? (bool) $input[$key] : ($existing_values[$key] ?? false);
            }
        }

        return $sanitized;
    }

    /**
     * Get WordPress URL for page type
     *
     * @param string $page_type Page type identifier
     * @return string WordPress URL
     */
    private function get_wp_url(string $page_type): string
    {
        $url = '';

        switch ($page_type) {
            case 'login':
                $url = wp_login_url();
                break;
            default:
                $url = home_url('/');
        }

        return apply_filters('attrua_get_wp_url', $url, $page_type);
    }

    /**
     * Register Pro submenus directly (bypassing hook timing issues)
     *
     * @access public
     * @return void
     */
    public function register_pro_submenus_directly(): void
    {
        // Prevent duplicate registration
        if ($this->pro_submenus_registered) {
            return;
        }

        // Check if Pro plugin is active and class exists
        if (!class_exists('\Attributes\Pro\Core\Hooks')) {
            return;
        }

        // CRITICAL: Check Pro license status before allowing Pro features
        if (!$this->is_pro_license_valid()) {
            return;
        }

        // Check if the register_pro_submenus method exists
        if (!method_exists('\Attributes\Pro\Core\Hooks', 'register_pro_submenus')) {
            return;
        }

        try {
            // Directly call the Pro plugin's submenu registration
            \Attributes\Pro\Core\Hooks::register_pro_submenus();

            // Mark as registered to prevent duplication
            $this->pro_submenus_registered = true;
        } catch (Exception $e) {
            // Silent error for production
        }
    }

    /**
     * Check if Pro license is valid
     *
     * @access private
     * @return bool
     */
    private function is_pro_license_valid(): bool
    {
        // Check if Pro license manager exists
        if (!class_exists('\Attributes\Pro\License\Manager')) {
            return false;
        }

        try {
            // Get Pro license manager instance
            $license_manager = new \Attributes\Pro\License\Manager();

            // Check if license is active
            return $license_manager->is_active();
        } catch (Exception $e) {
            // Silent error for production
            return false;
        }
    }
}
