<?php
/**
 * Assets Management Trait
 *
 * Handles asset enqueuing and script/style management.
 *
 * @package Opti_Behavior
 * @version 1.0.3
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Assets Trait
 *
 * Provides asset management functionality.
 *
 * @since 1.0.0
 */
trait Opti_Behavior_Assets_Trait {
	/**
	 * Enqueue dashboard assets.
	 *
	 * @since 1.0.0
	 * @param string $hook_suffix Current admin page hook suffix.
	 */
	private function enqueue_dashboard_assets_impl( $hook_suffix ) {
        // Normalise $hook_suffix — on some edge-case admin page loads (activation screen,
        // hidden pages, etc.) WordPress may pass null. PHP 8.2 deprecates strpos(null, …).
        $hook_suffix = $hook_suffix ?? '';

        // Enqueue admin menu styles globally on all admin pages (includes menu icon sizing)
        wp_enqueue_style(
            'opti-behavior-admin-menu',
            OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/admin-menu.css',
            array(),
            '2.1.3' // Version bump - PRO badge in menu
        );

        // Only load plugin-specific assets on plugin pages
        if ( strpos( $hook_suffix, 'opti-behavior-' ) === false ) {
            return;
        }

        // Enqueue Lucide Icons (bundled locally, MIT licensed)
        wp_enqueue_script( 'lucide-icons', OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'js/lucide.min.js', array(), OPTI_BEHAVIOR_HEATMAP_VERSION, true );

        // Enqueue Chart.js (bundled locally, MIT licensed) - Updated to v4.5.0
        wp_enqueue_script( 'chart-js', OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'js/chart.umd.min.js', array(), OPTI_BEHAVIOR_HEATMAP_VERSION, true );

        // Load Leaflet early (in head) so the map shows immediately (bundled locally, BSD-2-Clause licensed)
        wp_enqueue_style( 'leaflet', OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/leaflet.min.css', array(), OPTI_BEHAVIOR_HEATMAP_VERSION );
        wp_enqueue_script( 'leaflet', OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'js/leaflet.min.js', array(), OPTI_BEHAVIOR_HEATMAP_VERSION, false );

        // Enqueue Leaflet configuration script (moved to external file: assets/js/leaflet-config.js)
        wp_enqueue_script(
            'opti-behavior-leaflet-config',
            OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'js/leaflet-config.js',
            array( 'leaflet' ),
            OPTI_BEHAVIOR_HEATMAP_VERSION,
            false // Load in head after Leaflet
        );

        // Pass Leaflet image path to JavaScript
        wp_localize_script(
            'opti-behavior-leaflet-config',
            'opti_behaviorLeafletConfig',
            array(
                'imagePath' => OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'images/leaflet/',
            )
        );

        // Enqueue dashboard styles
        wp_enqueue_style(
            'opti-behavior-dashboard',
            OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/dashboard.css',
            array(),
            OPTI_BEHAVIOR_HEATMAP_VERSION // Version bump to force cache refresh for Top Countries native scrollbar (same as Bot Traffic)
        );

        // Enqueue main plugin styles (includes toggle switches, etc.)
        wp_enqueue_style(
            'opti-behavior-style',
            OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/style.css',
            array(),
            OPTI_BEHAVIOR_HEATMAP_VERSION // Version bump to force cache refresh
        );

        // Enqueue admin utility styles (loading states, forms, etc.)
        wp_enqueue_style(
            'opti-behavior-admin-utilities',
            OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/admin-utilities.css',
            array(),
            OPTI_BEHAVIOR_HEATMAP_VERSION
        );

        // Enqueue tooltip styles (user-friendly help tooltips across all pages)
        wp_enqueue_style(
            'opti-behavior-tooltips',
            OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/tooltips.css',
            array(),
            OPTI_BEHAVIOR_HEATMAP_VERSION
        );

        // Override CSS tooltip labels with translated text
        $simple_label = esc_html__( 'In simple terms:', 'opti-behavior' ) . ' ';
        $example_label = esc_html__( 'Example:', 'opti-behavior' ) . ' ';
        $tooltip_i18n_css = '.ob-tooltip-simple::before { content: "' . $simple_label . '"; }';
        $tooltip_i18n_css .= ' .ob-tooltip-example::before { content: "' . $example_label . '"; }';
        wp_add_inline_style( 'opti-behavior-tooltips', $tooltip_i18n_css );

        // Enqueue tooltip smart positioning script
        wp_enqueue_script(
            'opti-behavior-tooltips',
            OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'js/tooltips.js',
            array(),
            OPTI_BEHAVIOR_HEATMAP_VERSION,
            true
        );

        // Enqueue admin utility scripts (confirmation dialogs, etc.)
        wp_enqueue_script(
            'opti-behavior-admin-utilities',
            OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'js/admin-utilities.js',
            array(),
            OPTI_BEHAVIOR_HEATMAP_VERSION,
            true
        );

        // Initialize Lucide Icons after page load
        wp_add_inline_script(
            'lucide-icons',
            'document.addEventListener("DOMContentLoaded", function() {
                if (typeof lucide !== "undefined") {
                    lucide.createIcons();
                }
            });'
        );

        // Enqueue Pro Trial Banner assets (shown when Pro is not active)
        $opti_behavior_trial_state = $this->get_trial_banner_state();
        if ( 'hidden' !== $opti_behavior_trial_state['display'] ) {
            wp_enqueue_style(
                'opti-behavior-pro-trial-banner',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/pro-trial-banner.css',
                array(),
                OPTI_BEHAVIOR_HEATMAP_VERSION
            );

            wp_enqueue_script(
                'opti-behavior-pro-trial-banner',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'js/pro-trial-banner.js',
                array(),
                OPTI_BEHAVIOR_HEATMAP_VERSION,
                true
            );

            wp_localize_script(
                'opti-behavior-pro-trial-banner',
                'optiBehaviorTrial',
                array(
                    'ajaxUrl'               => admin_url( 'admin-ajax.php' ),
                    'startNonce'            => wp_create_nonce( 'opti_behavior_start_trial' ),
                    'dismissNonce'          => wp_create_nonce( 'opti_behavior_dismiss_trial' ),
                    'trialState'            => $opti_behavior_trial_state['display'],
                    'trialDaysLeft'         => $opti_behavior_trial_state['days_left'],
                    'trialExpiresTimestamp' => $opti_behavior_trial_state['expires_timestamp'],
                    'downloadUrl'           => $opti_behavior_trial_state['download_url'],
                    'i18n'                  => array(
                        'trialActivated' => __( 'Pro Trial Activated!', 'opti-behavior' ),
                        'trialActiveDesc' => __( 'You have 6 months of free access to all Pro features. Download the Pro plugin to get started!', 'opti-behavior' ),
                        'daysLeft'       => __( 'days left', 'opti-behavior' ),
                        'downloadPro'    => __( 'Download Pro Plugin', 'opti-behavior' ),
                        'dismiss'        => __( 'Dismiss', 'opti-behavior' ),
                        'trialExpired'   => __( 'Trial expired', 'opti-behavior' ),
                    ),
                )
            );
        }

        // Add modern sessions styles only for sessions page
        if ( strpos( $hook_suffix, 'opti-behavior-sessions' ) !== false ) {
            wp_enqueue_style(
                'opti-behavior-sessions',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/sessions.css',
                array( 'opti-behavior-dashboard' ),
                OPTI_BEHAVIOR_HEATMAP_VERSION
            );
        }

        // Add modern heatmaps styles for heatmaps page
        if ( strpos( $hook_suffix, 'opti-behavior-heatmaps' ) !== false ) {
            wp_enqueue_style(
                'opti-behavior-heatmaps',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/heatmaps.css',
                array( 'opti-behavior-dashboard' ),
                OPTI_BEHAVIOR_HEATMAP_VERSION
            );
            // Enqueue mobile simulator script from external file
            wp_enqueue_script(
                'opti-behavior-mobile-simulator',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'js/mobile-simulator.js',
                array(), // No dependencies
                OPTI_BEHAVIOR_HEATMAP_VERSION, // Version bump to force cache refresh for mobile parameter stripping fix
                true
            );
            // Enqueue heatmaps page scripts from external file
            wp_enqueue_script(
                'opti-behavior-heatmaps',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'js/heatmaps.js',
                array(), // No dependencies
                OPTI_BEHAVIOR_HEATMAP_VERSION . '.' . time(),
                true
            );
        }

        // Add AI Insights styles for AI Insights page
        if ( strpos( $hook_suffix, 'opti-behavior-ai-insights' ) !== false ) {
            wp_enqueue_style(
                'opti-behavior-ai-insights',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/ai-insights-page.css',
                array( 'opti-behavior-dashboard' ),
                OPTI_BEHAVIOR_HEATMAP_VERSION
            );

            // Enqueue support form script
            wp_enqueue_script(
                'opti-behavior-support-form',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'js/support-form.js',
                array(),
                OPTI_BEHAVIOR_HEATMAP_VERSION . '-v3',
                true
            );

            // Pass AJAX URL, nonce, and translated strings to support form script
            wp_localize_script(
                'opti-behavior-support-form',
                'optiBehaviorSupport',
                array(
                    'ajaxUrl' => admin_url( 'admin-ajax.php' ),
                    'nonce'   => wp_create_nonce( 'opti_behavior_support_email' ),
                    'i18n'    => array(
                        'sending'     => __( 'Sending...', 'opti-behavior' ),
                        'sendMessage' => __( 'Send Message', 'opti-behavior' ),
                        'error'       => __( 'An error occurred. Please try again.', 'opti-behavior' ),
                    ),
                )
            );
        }

        // Add recordings upgrade styles for free Session Recordings page
        if ( strpos( $hook_suffix, 'opti-behavior-recordings' ) !== false && ! opti_behavior_pro_active() ) {
            wp_enqueue_style(
                'opti-behavior-recordings-upgrade',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/recordings-upgrade.css',
                array( 'opti-behavior-dashboard' ),
                OPTI_BEHAVIOR_HEATMAP_VERSION
            );
        }

        // Add user journey upgrade styles for free User Journeys page
        if ( strpos( $hook_suffix, 'opti-behavior-user-journey' ) !== false && ! opti_behavior_pro_active() ) {
            wp_enqueue_style(
                'opti-behavior-user-journey-upgrade',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/recordings-upgrade.css',
                array( 'opti-behavior-dashboard' ),
                OPTI_BEHAVIOR_HEATMAP_VERSION
            );
        }

        // Add errors upgrade styles for free Errors Tracking page (uses recordings-upgrade.css for consistent header styling)
        if ( strpos( $hook_suffix, 'opti-behavior-errors' ) !== false && ! opti_behavior_pro_active() ) {
            wp_enqueue_style(
                'opti-behavior-errors-upgrade',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/recordings-upgrade.css',
                array( 'opti-behavior-dashboard' ),
                OPTI_BEHAVIOR_HEATMAP_VERSION
            );
        }

        // Add form analytics upgrade styles for free Form Analytics page
        if ( strpos( $hook_suffix, 'opti-behavior-form-analytics' ) !== false && ! opti_behavior_pro_active() ) {
            wp_enqueue_style(
                'opti-behavior-form-analytics-upgrade',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/recordings-upgrade.css',
                array( 'opti-behavior-dashboard' ),
                OPTI_BEHAVIOR_HEATMAP_VERSION
            );
        }

        // Add settings page styles for settings page
        if ( strpos( $hook_suffix, 'opti-behavior-settings' ) !== false ) {
            // Enqueue settings modal styles
            wp_enqueue_style(
                'opti-behavior-settings-modal',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/settings-modal.css',
                array(),
                OPTI_BEHAVIOR_HEATMAP_VERSION
            );

            wp_enqueue_style(
                'opti-behavior-settings',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/settings.css',
                array( 'opti-behavior-dashboard' ),
                OPTI_BEHAVIOR_HEATMAP_VERSION
            );
            // Enqueue settings page scripts from external file
            wp_enqueue_script(
                'opti-behavior-settings-js',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'js/settings.js',
                array( 'jquery' ), // Depends on jQuery
                OPTI_BEHAVIOR_HEATMAP_VERSION,
                true
            );
            // Pass nonces to settings script
            wp_localize_script(
                'opti-behavior-settings-js',
                'opti_behaviorSettings',
                array(
                    'ajaxUrl'            => admin_url( 'admin-ajax.php' ),
                    'viewLogNonce'       => wp_create_nonce( 'opti_behavior_view_log' ),
                    'cleanupNonce'       => wp_create_nonce( 'opti_behavior_cleanup' ),
                    'settingsNonce'      => wp_create_nonce( 'opti_behavior_settings_nonce' ),
                    'deleteAllNonce'     => wp_create_nonce( 'opti_behavior_delete_all_ajax' ),
                    'deleteRangeNonce'   => wp_create_nonce( 'opti_behavior_delete_range_ajax' ),
                    'smartCleanupNonce'  => wp_create_nonce( 'opti_behavior_smart_cleanup' ),
                    'strings'            => array(
                        'recalculating'     => __( 'Recalculating spam flags...', 'opti-behavior' ),
                        /* translators: %1$d: current session number, %2$d: total sessions */
                        'processing'        => __( 'Processing %1$d of %2$d sessions...', 'opti-behavior' ),
                        'completed'         => __( 'Spam recalculation completed successfully!', 'opti-behavior' ),
                        'error'             => __( 'Error during recalculation. Please try again.', 'opti-behavior' ),
                        'deleteError'       => __( 'Error during deletion. Please try again.', 'opti-behavior' ),
                        'deleteComplete'    => __( 'All analytics data has been deleted!', 'opti-behavior' ),
                        'invalidDateRange'  => __( 'Please select a valid date range.', 'opti-behavior' ),
                        'noConditions'      => __( 'Please select at least one condition.', 'opti-behavior' ),
                        'previewing'        => __( 'Checking...', 'opti-behavior' ),
                        'preview'           => __( 'Preview', 'opti-behavior' ),
                        'saving'            => __( 'Saving...', 'opti-behavior' ),
                        'saveSchedule'      => __( 'Save Schedule', 'opti-behavior' ),
                    ),
                )
            );
        }

        // Localize data for dashboard scripts (attach to chart-js handle so it's always available)
        wp_localize_script(
            'chart-js',
            'opti_behaviorData',
            array(
                'ajaxUrl'   => admin_url( 'admin-ajax.php' ),
                'nonce'     => wp_create_nonce( 'opti_behavior_dashboard_nonce' ),
                'strings'   => method_exists($this,'get_localized_strings') ? $this->get_localized_strings() : array(),
                'settings'  => method_exists($this,'get_dashboard_settings') ? $this->get_dashboard_settings() : array(),
            )
        );

        // Add dashboard-specific dynamic styles if on analytics page
        if ( strpos( $hook_suffix, 'opti-behavior-analytics' ) !== false ) {
            wp_enqueue_style(
                'opti-behavior-dashboard-styles',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/dashboard_styles.css',
                array( 'opti-behavior-dashboard' ),
                OPTI_BEHAVIOR_HEATMAP_VERSION // Version bump: Removed fixed canvas dimensions to allow chart to fill widget height properly
            );

            // Enqueue dashboard page scripts from external file
            // Version 1.0.4: Top Pages now uses heatmap sessions count consistently (server + JS)
            wp_enqueue_script(
                'opti-behavior-dashboard-scripts',
                OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'js/dashboard.js',
                array( 'chart-js' ), // Depends on Chart.js
                OPTI_BEHAVIOR_HEATMAP_VERSION, // Version bump: Fixed Traffic Overview legend overlap with better layout padding
                true
            );

            // Pass AJAX URL, nonce, and translated strings to dashboard.js
            wp_localize_script(
                'opti-behavior-dashboard-scripts',
                'opti_behaviorDashboard',
                array(
                    'ajaxUrl' => admin_url( 'admin-ajax.php' ),
                    'nonce'   => wp_create_nonce( 'optibehavior_top_users' ),
                    'i18n'    => array(
                        'dayNames'                => array(
                            __( 'Sunday', 'opti-behavior' ),
                            __( 'Monday', 'opti-behavior' ),
                            __( 'Tuesday', 'opti-behavior' ),
                            __( 'Wednesday', 'opti-behavior' ),
                            __( 'Thursday', 'opti-behavior' ),
                            __( 'Friday', 'opti-behavior' ),
                            __( 'Saturday', 'opti-behavior' ),
                        ),
                        'visits'                  => __( 'visits', 'opti-behavior' ),
                        'high'                    => __( 'High', 'opti-behavior' ),
                        'low'                     => __( 'Low', 'opti-behavior' ),
                        'pc'                      => __( 'PC', 'opti-behavior' ),
                        'desktop'                 => __( 'Desktop', 'opti-behavior' ),
                        'mobile'                  => __( 'Mobile', 'opti-behavior' ),
                        'tablet'                  => __( 'Tablet', 'opti-behavior' ),
                        'vsLastPeriod'            => __( '% vs last period', 'opti-behavior' ),
                        'mapUnavailable'          => __( 'Map unavailable', 'opti-behavior' ),
                        'mapUnavailableOffline'   => __( 'Map unavailable (offline)', 'opti-behavior' ),
                        'noScreenResolutionData'  => __( 'No screen resolution data available', 'opti-behavior' ),
                        'tryBroadeningDateRange'  => __( 'Try broadening the date range or check back later.', 'opti-behavior' ),
                        'noCountryData'           => __( 'No country data available', 'opti-behavior' ),
                        'noReferrerData'          => __( 'No referrer data available', 'opti-behavior' ),
                        'humanTraffic'            => __( 'Human Traffic', 'opti-behavior' ),
                        'automated'               => __( 'Automated', 'opti-behavior' ),
                        'spamTraffic'             => __( 'Spam Traffic', 'opti-behavior' ),
                        'noActiveVisitors'        => __( 'No active visitors right now', 'opti-behavior' ),
                        'trafficUpdates'          => __( 'Traffic updates in real-time.', 'opti-behavior' ),
                        'excludeSpam'             => __( 'Exclude Spam', 'opti-behavior' ),
                        'includeSpam'             => __( 'Include Spam', 'opti-behavior' ),
                        'interactions'            => __( 'Heatmap sessions', 'opti-behavior' ),
                        'clicks'                  => __( 'Clicks', 'opti-behavior' ),
                        'directNone'              => __( 'Direct / None', 'opti-behavior' ),
                        'unknown'                 => __( 'Unknown', 'opti-behavior' ),
                        'justNow'                 => __( 'just now', 'opti-behavior' ),
                        /* translators: %s: number of minutes */
                        'minutesAgo'              => __( '%sm ago', 'opti-behavior' ),
                        /* translators: %s: number of hours */
                        'hoursAgo'                => __( '%sh ago', 'opti-behavior' ),
                        /* translators: %s: number of days */
                        'daysAgo'                 => __( '%sd ago', 'opti-behavior' ),
                        /* translators: %s: number of months */
                        'monthsAgo'               => __( '%smo ago', 'opti-behavior' ),
                        /* translators: %s: time duration */
                        'ago'                     => __( '%s ago', 'opti-behavior' ),
                        'visitorsLabel'           => __( 'Visitors', 'opti-behavior' ),
                        'sessionsLabel'           => __( 'Sessions', 'opti-behavior' ),
                        'pageViewsLabel'          => __( 'Page Views', 'opti-behavior' ),
                        'avgSessionTimeLabel'     => __( 'Avg. Session Time', 'opti-behavior' ),
                        'avgScrollDepthLabel'     => __( 'Avg. Scroll Depth', 'opti-behavior' ),
                        'bounceRateLabel'         => __( 'Bounce Rate', 'opti-behavior' ),
                    ),
                )
            );
        }

        // Enqueue onboarding popup assets on the dashboard page when conditions are met.
        if ( strpos( $hook_suffix, 'opti-behavior-analytics' ) !== false ) {
            $opti_behavior_onboarding = Opti_Behavior_Onboarding::init();
            if ( $opti_behavior_onboarding->should_show() ) {
                $opti_behavior_onboarding->enqueue_assets();
            }
        }

        // Note: Recordings page styles are now enqueued by the PRO plugin
        // See: opti-behavior-pro/includes/class-opti-behavior-pro-core.php
    }

    /**
     * Ensure critical scripts are not delayed by Cloudflare Rocket Loader.
     *
     * @since 1.0.0
     * @param string $tag    Script tag HTML.
     * @param string $handle Script handle.
     * @param string $src    Script source URL.
     * @return string Modified script tag.
     */
    private function filter_script_loader_tag_impl( $tag, $handle, $src ) {
        if ( $handle === 'leaflet' || $handle === 'opti-behavior-leaflet-config' ) {
            if ( strpos( $tag, 'data-cfasync' ) === false ) {
                $tag = str_replace( '<script ', '<script data-cfasync="false" ', $tag );
            }
        }
        return $tag;
    }

    /**
     * Suppress third-party admin notices on plugin pages.
     *
     * This comprehensive implementation uses multiple techniques to remove ALL admin notices:
     * 1. Removes WordPress admin_notices and user_admin_notices hooks
     * 2. Removes all_admin_notices hooks
     * 3. CSS hiding for any notices that slip through
     * 4. JavaScript cleanup for dynamically added notices
     *
     * @since 1.0.0
     * @global array $wp_filter WordPress filter hooks.
     */
    private function suppress_admin_notices_impl() {
        if ( ! function_exists('get_current_screen') ) { return; }
        $screen = get_current_screen();
        if ( ! $screen || empty($screen->id) ) { return; }

        // Check if we're on an opti-behavior page by looking for opti-behavior in the screen ID
        // This covers all variations: toplevel_page_opti-behavior-*, opti-behavior_page_opti-behavior-*, etc.
        if ( strpos( $screen->id, 'opti-behavior' ) === false &&
             strpos( $screen->id, 'opti_behavior' ) === false ) {
            return;
        }

        // TECHNIQUE 1: Remove all admin notice hooks
        $this->remove_all_admin_notice_hooks();

        // TECHNIQUE 2: Comprehensive CSS hiding - enqueue external CSS file
        wp_enqueue_style(
            'opti-behavior-admin-notices',
            OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'css/admin-notices.css',
            array(),
            OPTI_BEHAVIOR_HEATMAP_VERSION . '-admin-notices-v6'
        );

        // TECHNIQUE 3: JavaScript cleanup for dynamically added notices
        // Enqueue notice cleanup script from external file
        wp_enqueue_script(
            'opti-behavior-notice-cleanup',
            OPTI_BEHAVIOR_HEATMAP_ASSETS_URL . 'js/notice-cleanup.js',
            array( 'jquery' ), // Depends on jQuery
            OPTI_BEHAVIOR_HEATMAP_VERSION . '-v2', // v2: exclude ob-* prefixed elements from removal
            true // Load in footer
        );
    }

    /**
     * Remove all admin notice hooks from WordPress.
     *
     * This is the most effective method - prevents notices from being output at all.
     *
     * @since 1.0.0
     * @global array $wp_filter WordPress filter hooks.
     */
    private function remove_all_admin_notice_hooks() {
        global $wp_filter;

        // List of all admin notice hooks used by WordPress and plugins
        $notice_hooks = array(
            'admin_notices',
            'user_admin_notices',
            'network_admin_notices',
            'all_admin_notices',
        );

        foreach ( $notice_hooks as $hook ) {
            if ( isset( $wp_filter[$hook] ) ) {
                // Remove all callbacks except those from opti-behavior
                if ( is_object( $wp_filter[$hook] ) && method_exists( $wp_filter[$hook], 'callbacks' ) ) {
                    $callbacks = $wp_filter[$hook]->callbacks;
                } else {
                    $callbacks = isset( $wp_filter[$hook] ) ? $wp_filter[$hook] : array();
                }

                foreach ( $callbacks as $priority => $functions ) {
                    foreach ( $functions as $function ) {
                        // Keep only opti_behavior notices (if any)
                        $is_opti_behavior = false;

                        if ( is_array( $function['function'] ) ) {
                            $class_name = is_object( $function['function'][0] )
                                ? get_class( $function['function'][0] )
                                : $function['function'][0];

                            $class_lower = strtolower( $class_name );
                            if ( strpos( $class_lower, 'opti_behavior' ) !== false || strpos( $class_lower, 'opti-behavior' ) !== false ) {
                                $is_opti_behavior = true;
                            }
                        } elseif ( is_string( $function['function'] ) ) {
                            $func_lower = strtolower( $function['function'] );
                            if ( strpos( $func_lower, 'opti_behavior' ) !== false || strpos( $func_lower, 'opti-behavior' ) !== false ) {
                                $is_opti_behavior = true;
                            }
                        }

                        // Remove third-party notices
                        if ( ! $is_opti_behavior ) {
                            remove_action( $hook, $function['function'], $priority );
                        }
                    }
                }
            }
        }
    }

    /**
     * Determine the current trial banner display state.
     *
     * Returns an array with:
     *  - display: 'invite' | 'active' | 'expired' | 'hidden'
     *  - days_left: int (0 when not active)
     *  - expires_timestamp: int Unix timestamp (0 when not applicable)
     *  - download_url: string URL to download Pro
     *
     * @since 1.1.3
     * @return array Trial state data.
     */
    private function get_trial_banner_state() {
        $result = array(
            'display'           => 'hidden',
            'days_left'         => 0,
            'expires_timestamp' => 0,
            'download_url'      => '',
        );

        // If Pro plugin is active, check the manifest to decide banner visibility.
        // Only hide the banner if the user has a valid paid license (pro/premium/enterprise).
        // If their license/trial has expired, they should still see the banner.
        if ( function_exists( 'opti_behavior_pro_active' ) && opti_behavior_pro_active() ) {
            if ( class_exists( 'Opti_Behavior_Manifest_Manager' ) ) {
                $manifest_mgr = Opti_Behavior_Manifest_Manager::get_instance();

                // If trial expired → show expired banner so user can upgrade.
                // Guard with method_exists() for backward compatibility with older Pro versions.
                if ( method_exists( $manifest_mgr, 'is_trial_expired' ) && $manifest_mgr->is_trial_expired() ) {
                    $result['display']      = 'expired';
                    $result['download_url'] = $this->get_pro_download_url_for_banner();
                    return $result;
                }

                // If manifest confirms active Pro features → no banner needed.
                if ( method_exists( $manifest_mgr, 'is_pro' ) && $manifest_mgr->is_pro() ) {
                    return $result; // hidden
                }
            } else {
                // Manifest manager not available but Pro constant is defined.
                // Assume Pro is legitimately active → hide banner.
                return $result; // hidden
            }

            // Pro plugin active but no valid pro manifest (e.g. license expired,
            // free-tier fallback). Fall through to free-only logic below.
        }

        // --- Free-only mode: decide banner state ---

        $trial_started = (int) get_option( 'opti_behavior_pro_trial_started', 0 );

        // Trial never started
        if ( 0 === $trial_started ) {
            // Check if user dismissed the banner
            $dismissed = (int) get_option( 'opti_behavior_pro_trial_banner_dismissed', 0 );
            if ( $dismissed > 0 ) {
                // Re-show after 30 days
                if ( ( time() - $dismissed ) < ( 30 * DAY_IN_SECONDS ) ) {
                    return $result; // hidden
                }
            }
            $result['display']      = 'invite';
            $result['download_url'] = $this->get_pro_download_url_for_banner();
            return $result;
        }

        // Trial was started — check expiry
        $expires   = $trial_started + ( 180 * DAY_IN_SECONDS );
        $days_left = max( 0, (int) ceil( ( $expires - time() ) / DAY_IN_SECONDS ) );

        if ( $days_left > 0 ) {
            $result['display']           = 'active';
            $result['days_left']         = $days_left;
            $result['expires_timestamp'] = $expires;
            $result['download_url']      = $this->get_pro_download_url_for_banner();
        } else {
            // Check if dismissed
            $dismissed = (int) get_option( 'opti_behavior_pro_trial_banner_dismissed', 0 );
            if ( $dismissed > 0 && ( time() - $dismissed ) < ( 30 * DAY_IN_SECONDS ) ) {
                return $result; // hidden
            }
            $result['display']      = 'expired';
            $result['download_url'] = $this->get_pro_download_url_for_banner();
        }

        return $result;
    }

    /**
     * Build the Pro download URL for the trial banner (lightweight version).
     *
     * Uses cached access code when available, falls back to URL without code.
     *
     * @since 1.1.3
     * @return string Download URL.
     */
    private function get_pro_download_url_for_banner() {
        $current_user = wp_get_current_user();
        $cache_key    = 'ob_dl_access_' . md5( $current_user->user_login . site_url() );
        $access_code  = get_transient( $cache_key );

        return add_query_arg(
            array(
                'site_url'    => rawurlencode( site_url() ),
                'username'    => rawurlencode( $current_user->user_login ),
                'email'       => rawurlencode( $current_user->user_email ),
                'access_code' => rawurlencode( $access_code ? $access_code : '' ),
            ),
            'https://optiuser.com/opti-behavior/ob-download-pro/'
        );
    }
}

