<?php
/**
 * HVAC Database Query Monitor
 * 
 * Monitors and optimizes database queries for performance issues
 * 
 * @package HVAC_Community_Events
 * @since 1.0.7
 */

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

/**
 * HVAC_Query_Monitor class
 */
class HVAC_Query_Monitor {
    
    /**
     * Slow query threshold in seconds
     */
    const SLOW_QUERY_THRESHOLD = 0.1;
    
    /**
     * Query log option name
     */
    const LOG_OPTION = 'hvac_query_log';
    
    /**
     * Maximum log entries to keep
     */
    const MAX_LOG_ENTRIES = 100;
    
    /**
     * Logged queries
     * 
     * @var array
     */
    private static $queries = [];
    
    /**
     * Query statistics
     * 
     * @var array
     */
    private static $stats = [
        'total_queries' => 0,
        'slow_queries' => 0,
        'total_time' => 0,
        'peak_memory' => 0
    ];
    
    /**
     * Initialize monitoring
     */
    public static function init() {
        // Only enable in development or when explicitly requested
        if (!self::should_monitor()) {
            return;
        }
        
        // Hook into WordPress query system
        add_filter('query', [__CLASS__, 'log_query'], 999);
        add_action('shutdown', [__CLASS__, 'analyze_queries']);
        
        // Admin hooks
        if (is_admin()) {
            add_action('admin_menu', [__CLASS__, 'add_admin_page']);
            add_action('wp_ajax_hvac_clear_query_log', [__CLASS__, 'ajax_clear_log']);
        }
        
        // WP-CLI integration (disabled - method not implemented)
        // if (defined('WP_CLI') && WP_CLI) {
        //     WP_CLI::add_command('hvac query-monitor', [__CLASS__, 'wp_cli_commands']);
        // }
    }
    
    /**
     * Check if monitoring should be enabled
     * 
     * @return bool
     */
    private static function should_monitor() {
        // Enable if WP_DEBUG is on
        if (defined('WP_DEBUG') && WP_DEBUG) {
            return true;
        }
        
        // Enable if explicitly requested
        if (defined('HVAC_QUERY_MONITOR') && HVAC_QUERY_MONITOR) {
            return true;
        }
        
        // Enable for admin users with specific parameter
        if (is_admin() && current_user_can('manage_options') && isset($_GET['hvac_monitor'])) {
            return true;
        }
        
        return false;
    }
    
    /**
     * Log database query
     * 
     * @param string $query SQL query
     * @return string Original query
     */
    public static function log_query($query) {
        $start_time = microtime(true);
        
        // Get calling function information
        $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
        $caller_info = self::get_caller_info($backtrace);
        
        // Execute query timing logic by hooking into WordPress
        add_action('wp_footer', function() use ($query, $start_time, $caller_info) {
            $end_time = microtime(true);
            $execution_time = $end_time - $start_time;
            
            self::record_query($query, $execution_time, $caller_info);
        }, 999);
        
        return $query;
    }
    
    /**
     * Record query information
     * 
     * @param string $query SQL query
     * @param float $execution_time Query execution time
     * @param array $caller_info Caller information
     */
    private static function record_query($query, $execution_time, $caller_info) {
        // Skip if query is too common or not from our plugin
        if (!self::should_log_query($query, $caller_info)) {
            return;
        }
        
        $is_slow = $execution_time > self::SLOW_QUERY_THRESHOLD;
        
        $query_data = [
            'query' => self::sanitize_query($query),
            'execution_time' => round($execution_time, 4),
            'is_slow' => $is_slow,
            'caller' => $caller_info,
            'memory_usage' => memory_get_usage(true),
            'timestamp' => time(),
            'url' => $_SERVER['REQUEST_URI'] ?? 'unknown'
        ];
        
        self::$queries[] = $query_data;
        
        // Update statistics
        self::$stats['total_queries']++;
        self::$stats['total_time'] += $execution_time;
        self::$stats['peak_memory'] = max(self::$stats['peak_memory'], $query_data['memory_usage']);
        
        if ($is_slow) {
            self::$stats['slow_queries']++;
            
            // Log slow queries immediately
            HVAC_Logger::warning(
                "Slow query detected ({$execution_time}s): " . substr($query, 0, 200),
                'Query Monitor'
            );
        }
    }
    
    /**
     * Get caller information from backtrace
     * 
     * @param array $backtrace Debug backtrace
     * @return array Caller info
     */
    private static function get_caller_info($backtrace) {
        foreach ($backtrace as $trace) {
            $file = $trace['file'] ?? '';
            $function = $trace['function'] ?? '';
            
            // Look for HVAC plugin functions
            if (strpos($file, 'hvac-community-events') !== false) {
                return [
                    'file' => basename($file),
                    'line' => $trace['line'] ?? 0,
                    'function' => $function,
                    'class' => $trace['class'] ?? ''
                ];
            }
        }
        
        // Fallback to first available trace
        $first = $backtrace[0] ?? [];
        return [
            'file' => basename($first['file'] ?? 'unknown'),
            'line' => $first['line'] ?? 0,
            'function' => $first['function'] ?? 'unknown',
            'class' => $first['class'] ?? ''
        ];
    }
    
    /**
     * Check if query should be logged
     * 
     * @param string $query SQL query
     * @param array $caller_info Caller information
     * @return bool
     */
    private static function should_log_query($query, $caller_info) {
        // Only log queries from our plugin
        $hvac_files = ['hvac-', 'HVAC_'];
        $is_hvac_query = false;
        
        foreach ($hvac_files as $prefix) {
            if (strpos($caller_info['file'], $prefix) !== false || 
                strpos($caller_info['class'], $prefix) !== false) {
                $is_hvac_query = true;
                break;
            }
        }
        
        if (!$is_hvac_query) {
            return false;
        }
        
        // Skip common WordPress core queries
        $skip_patterns = [
            'SELECT option_value FROM',
            'SELECT autoload FROM',
            'SELECT meta_value FROM.*_usermeta WHERE meta_key = \'wp_',
            'UPDATE.*_options SET option_value'
        ];
        
        foreach ($skip_patterns as $pattern) {
            if (preg_match('/' . $pattern . '/i', $query)) {
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * Sanitize query for logging
     * 
     * @param string $query SQL query
     * @return string Sanitized query
     */
    private static function sanitize_query($query) {
        // Remove potential sensitive data
        $query = preg_replace('/\'[^\']*\'/', "'[DATA]'", $query);
        $query = preg_replace('/\b\d+\b/', '[NUM]', $query);
        
        return trim($query);
    }
    
    /**
     * Analyze queries on shutdown
     */
    public static function analyze_queries() {
        if (empty(self::$queries)) {
            return;
        }
        
        // Store queries in log
        self::store_query_log();
        
        // Generate recommendations
        $recommendations = self::generate_recommendations();
        
        if (!empty($recommendations)) {
            HVAC_Logger::info(
                'Query optimization recommendations: ' . implode('; ', $recommendations),
                'Query Monitor'
            );
        }
        
        // Add debug output for admin users
        if (current_user_can('manage_options') && isset($_GET['hvac_debug_queries'])) {
            self::output_debug_info();
        }
    }
    
    /**
     * Store query log
     */
    private static function store_query_log() {
        $existing_log = get_option(self::LOG_OPTION, []);
        
        // Add new queries
        $new_log = array_merge($existing_log, self::$queries);
        
        // Keep only recent entries
        $new_log = array_slice($new_log, -self::MAX_LOG_ENTRIES);
        
        update_option(self::LOG_OPTION, $new_log);
    }
    
    /**
     * Generate optimization recommendations
     * 
     * @return array Recommendations
     */
    private static function generate_recommendations() {
        $recommendations = [];
        
        // Check for slow queries
        if (self::$stats['slow_queries'] > 0) {
            $recommendations[] = "Found " . self::$stats['slow_queries'] . " slow queries - consider adding indexes or caching";
        }
        
        // Check total query time
        if (self::$stats['total_time'] > 1.0) {
            $recommendations[] = "Total query time is high (" . round(self::$stats['total_time'], 2) . "s) - consider query optimization";
        }
        
        // Check for duplicate queries
        $query_counts = array_count_values(array_column(self::$queries, 'query'));
        $duplicates = array_filter($query_counts, function($count) { return $count > 1; });
        
        if (!empty($duplicates)) {
            $recommendations[] = "Found " . count($duplicates) . " duplicate query patterns - consider caching";
        }
        
        // Check memory usage
        if (self::$stats['peak_memory'] > 50 * 1024 * 1024) { // 50MB
            $recommendations[] = "High memory usage detected - consider result set optimization";
        }
        
        return $recommendations;
    }
    
    /**
     * Output debug information
     */
    private static function output_debug_info() {
        echo "\n<!-- HVAC Query Monitor Debug -->\n";
        echo "<div style='position:fixed;bottom:0;left:0;background:#000;color:#fff;padding:10px;max-width:50%;max-height:300px;overflow:auto;z-index:9999;font-size:11px;'>";
        echo "<h4>HVAC Query Monitor</h4>";
        echo "<p>Total Queries: " . self::$stats['total_queries'] . " | ";
        echo "Slow Queries: " . self::$stats['slow_queries'] . " | ";
        echo "Total Time: " . round(self::$stats['total_time'], 3) . "s | ";
        echo "Peak Memory: " . size_format(self::$stats['peak_memory']) . "</p>";
        
        if (!empty(self::$queries)) {
            echo "<details><summary>Query Details</summary>";
            foreach (array_slice(self::$queries, -10) as $query) {
                echo "<div style='margin:5px 0;padding:5px;background:#333;'>";
                echo "<strong>" . $query['execution_time'] . "s</strong> - ";
                echo htmlspecialchars(substr($query['query'], 0, 100)) . "...";
                echo "<br><small>Called from: " . $query['caller']['file'] . ":" . $query['caller']['line'] . "</small>";
                echo "</div>";
            }
            echo "</details>";
        }
        echo "</div>\n";
    }
    
    /**
     * Add admin page
     */
    public static function add_admin_page() {
        if (current_user_can('manage_options')) {
            add_management_page(
                'HVAC Query Monitor',
                'HVAC Query Monitor',
                'manage_options',
                'hvac-query-monitor',
                [__CLASS__, 'admin_page']
            );
        }
    }
    
    /**
     * Admin page content
     */
    public static function admin_page() {
        $log = get_option(self::LOG_OPTION, []);
        $recent_log = array_slice($log, -20);
        
        ?>
        <div class="wrap">
            <h1>HVAC Query Monitor</h1>
            
            <div class="card">
                <h3>Query Statistics</h3>
                <p>Total logged queries: <?php echo count($log); ?></p>
                
                <?php if (!empty($log)): ?>
                    <?php 
                    $slow_count = count(array_filter($log, function($q) { return $q['is_slow']; }));
                    $avg_time = array_sum(array_column($log, 'execution_time')) / count($log);
                    ?>
                    <p>Slow queries: <?php echo $slow_count; ?></p>
                    <p>Average execution time: <?php echo round($avg_time, 4); ?>s</p>
                <?php endif; ?>
                
                <p>
                    <a href="?page=hvac-query-monitor&action=clear" class="button button-secondary">Clear Log</a>
                    <a href="?hvac_debug_queries=1" class="button button-primary" target="_blank">Enable Debug Output</a>
                </p>
            </div>
            
            <?php if (!empty($recent_log)): ?>
            <div class="card">
                <h3>Recent Queries (Last 20)</h3>
                <table class="wp-list-table widefat fixed striped">
                    <thead>
                        <tr>
                            <th>Time</th>
                            <th>Duration</th>
                            <th>Query</th>
                            <th>Caller</th>
                            <th>URL</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach (array_reverse($recent_log) as $query): ?>
                        <tr <?php echo $query['is_slow'] ? 'style="background:#ffebee;"' : ''; ?>>
                            <td><?php echo date('H:i:s', $query['timestamp']); ?></td>
                            <td><?php echo $query['execution_time']; ?>s</td>
                            <td title="<?php echo esc_attr($query['query']); ?>">
                                <?php echo esc_html(substr($query['query'], 0, 80)) . '...'; ?>
                            </td>
                            <td><?php echo esc_html($query['caller']['file'] . ':' . $query['caller']['line']); ?></td>
                            <td><?php echo esc_html($query['url']); ?></td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
            <?php endif; ?>
        </div>
        <?php
    }
    
    /**
     * AJAX handler to clear log
     */
    public static function ajax_clear_log() {
        if (!current_user_can('manage_options') || 
            !check_ajax_referer('hvac_ajax_nonce', 'nonce', false)) {
            wp_send_json_error('Unauthorized');
        }
        
        delete_option(self::LOG_OPTION);
        wp_send_json_success('Query log cleared');
    }
    
    /**
     * Get query statistics
     * 
     * @return array Statistics
     */
    public static function get_stats() {
        $log = get_option(self::LOG_OPTION, []);
        
        if (empty($log)) {
            return [
                'total_queries' => 0,
                'slow_queries' => 0,
                'average_time' => 0,
                'recommendations' => []
            ];
        }
        
        $slow_queries = array_filter($log, function($q) { return $q['is_slow']; });
        $total_time = array_sum(array_column($log, 'execution_time'));
        
        return [
            'total_queries' => count($log),
            'slow_queries' => count($slow_queries),
            'average_time' => $total_time / count($log),
            'total_time' => $total_time,
            'recommendations' => self::generate_recommendations_from_log($log)
        ];
    }
    
    /**
     * Generate recommendations from stored log
     * 
     * @param array $log Query log
     * @return array Recommendations
     */
    private static function generate_recommendations_from_log($log) {
        $recommendations = [];
        
        // Analyze patterns in stored log
        $query_patterns = [];
        foreach ($log as $query_data) {
            $pattern = preg_replace('/\[DATA\]|\[NUM\]/', 'X', $query_data['query']);
            $query_patterns[$pattern] = ($query_patterns[$pattern] ?? 0) + 1;
        }
        
        // Find frequently repeated queries
        $frequent_queries = array_filter($query_patterns, function($count) { return $count > 5; });
        if (!empty($frequent_queries)) {
            $recommendations[] = "Consider caching for " . count($frequent_queries) . " frequently repeated queries";
        }
        
        return $recommendations;
    }
}