<?php
/**
 * HVAC Health Monitor
 * 
 * Provides automated testing and health monitoring for critical plugin functionality
 * 
 * @package HVAC_Community_Events
 * @since 1.0.8
 */

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

/**
 * HVAC_Health_Monitor class
 */
class HVAC_Health_Monitor {
    
    /**
     * Health check types
     */
    const CHECK_TYPES = [
        'database' => 'Database Connectivity',
        'cache' => 'Cache System',
        'authentication' => 'User Authentication',
        'events' => 'Event Management',
        'certificates' => 'Certificate Generation',
        'background_jobs' => 'Background Jobs',
        'file_permissions' => 'File Permissions',
        'third_party' => 'Third Party Integrations'
    ];
    
    /**
     * Health status constants
     */
    const STATUS_HEALTHY = 'healthy';
    const STATUS_WARNING = 'warning';
    const STATUS_CRITICAL = 'critical';
    
    /**
     * Health check results cache
     */
    const CACHE_KEY = 'hvac_health_checks';
    const CACHE_DURATION = 300; // 5 minutes
    
    /**
     * Initialize health monitoring
     */
    public static function init() {
        // Schedule recurring health checks
        if (!wp_next_scheduled('hvac_health_check')) {
            wp_schedule_event(time(), 'hourly', 'hvac_health_check');
        }
        
        // Hook health check action
        add_action('hvac_health_check', [__CLASS__, 'run_automated_checks']);
        
        // Admin integration
        if (is_admin()) {
            add_action('admin_menu', [__CLASS__, 'add_admin_menu']);
            add_action('wp_ajax_hvac_run_health_check', [__CLASS__, 'ajax_run_health_check']);
            add_action('admin_notices', [__CLASS__, 'show_health_warnings']);
        }
        
        // REST API endpoint for external monitoring
        add_action('rest_api_init', [__CLASS__, 'register_rest_endpoints']);
        
        // WP-CLI integration
        if (defined('WP_CLI') && WP_CLI) {
            WP_CLI::add_command('hvac health', [__CLASS__, 'wp_cli_health_check']);
        }
    }
    
    /**
     * Run all health checks
     * 
     * @param bool $force_refresh Force refresh cached results
     * @return array Health check results
     */
    public static function run_all_checks($force_refresh = false) {
        if (!$force_refresh) {
            $cached_results = get_transient(self::CACHE_KEY);
            if ($cached_results !== false) {
                return $cached_results;
            }
        }
        
        $results = [
            'timestamp' => time(),
            'overall_status' => self::STATUS_HEALTHY,
            'checks' => []
        ];
        
        foreach (self::CHECK_TYPES as $type => $name) {
            $check_result = self::run_health_check($type);
            $results['checks'][$type] = $check_result;
            
            // Update overall status based on worst result
            if ($check_result['status'] === self::STATUS_CRITICAL) {
                $results['overall_status'] = self::STATUS_CRITICAL;
            } elseif ($check_result['status'] === self::STATUS_WARNING && 
                     $results['overall_status'] !== self::STATUS_CRITICAL) {
                $results['overall_status'] = self::STATUS_WARNING;
            }
        }
        
        // Cache results
        set_transient(self::CACHE_KEY, $results, self::CACHE_DURATION);
        
        // Log critical issues
        if ($results['overall_status'] === self::STATUS_CRITICAL) {
            $critical_checks = array_filter($results['checks'], function($check) {
                return $check['status'] === self::STATUS_CRITICAL;
            });
            
            $critical_names = array_keys($critical_checks);
            HVAC_Logger::error(
                'Critical health check failures: ' . implode(', ', $critical_names),
                'Health Monitor'
            );
        }
        
        return $results;
    }
    
    /**
     * Run individual health check
     * 
     * @param string $type Check type
     * @return array Check result
     */
    private static function run_health_check($type) {
        $start_time = microtime(true);
        
        try {
            switch ($type) {
                case 'database':
                    $result = self::check_database();
                    break;
                    
                case 'cache':
                    $result = self::check_cache_system();
                    break;
                    
                case 'authentication':
                    $result = self::check_authentication();
                    break;
                    
                case 'events':
                    $result = self::check_event_management();
                    break;
                    
                case 'certificates':
                    $result = self::check_certificate_system();
                    break;
                    
                case 'background_jobs':
                    $result = self::check_background_jobs();
                    break;
                    
                case 'file_permissions':
                    $result = self::check_file_permissions();
                    break;
                    
                case 'third_party':
                    $result = self::check_third_party_integrations();
                    break;
                    
                default:
                    $result = [
                        'status' => self::STATUS_WARNING,
                        'message' => 'Unknown check type',
                        'details' => []
                    ];
            }
            
        } catch (Exception $e) {
            $result = [
                'status' => self::STATUS_CRITICAL,
                'message' => 'Check failed with exception: ' . $e->getMessage(),
                'details' => ['exception' => get_class($e)]
            ];
        }
        
        $result['execution_time'] = round(microtime(true) - $start_time, 4);
        $result['timestamp'] = time();
        $result['name'] = self::CHECK_TYPES[$type];
        
        return $result;
    }
    
    /**
     * Check database connectivity and integrity
     */
    private static function check_database() {
        global $wpdb;
        
        // Test basic connection
        $test_query = $wpdb->get_var("SELECT 1");
        if ($test_query !== '1') {
            return [
                'status' => self::STATUS_CRITICAL,
                'message' => 'Database connection failed',
                'details' => ['error' => $wpdb->last_error]
            ];
        }
        
        // Check plugin tables exist
        $required_tables = [
            $wpdb->prefix . 'posts',
            $wpdb->prefix . 'postmeta',
            $wpdb->prefix . 'users',
            $wpdb->prefix . 'usermeta'
        ];
        
        $missing_tables = [];
        foreach ($required_tables as $table) {
            $exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table));
            if (!$exists) {
                $missing_tables[] = $table;
            }
        }
        
        if (!empty($missing_tables)) {
            return [
                'status' => self::STATUS_CRITICAL,
                'message' => 'Required tables missing',
                'details' => ['missing_tables' => $missing_tables]
            ];
        }
        
        // Check for recent database errors
        if ($wpdb->last_error) {
            return [
                'status' => self::STATUS_WARNING,
                'message' => 'Recent database error detected',
                'details' => ['last_error' => $wpdb->last_error]
            ];
        }
        
        return [
            'status' => self::STATUS_HEALTHY,
            'message' => 'Database connectivity is healthy',
            'details' => ['tables_checked' => count($required_tables)]
        ];
    }
    
    /**
     * Check cache system functionality
     */
    private static function check_cache_system() {
        // Test WordPress object cache
        $test_key = 'hvac_health_test_' . time();
        $test_value = 'test_data_' . wp_generate_password(10, false);
        
        // Set cache
        $set_result = wp_cache_set($test_key, $test_value, 'hvac_health', 60);
        if (!$set_result) {
            return [
                'status' => self::STATUS_WARNING,
                'message' => 'Cache set operation failed',
                'details' => []
            ];
        }
        
        // Get cache
        $cached_value = wp_cache_get($test_key, 'hvac_health');
        if ($cached_value !== $test_value) {
            return [
                'status' => self::STATUS_WARNING,
                'message' => 'Cache retrieval failed or returned incorrect data',
                'details' => ['expected' => $test_value, 'actual' => $cached_value]
            ];
        }
        
        // Test master dashboard cache
        if (class_exists('HVAC_Master_Dashboard_Data')) {
            $dashboard_data = new HVAC_Master_Dashboard_Data();
            $events_count = $dashboard_data->get_total_events_count();
            
            if (!is_numeric($events_count)) {
                return [
                    'status' => self::STATUS_WARNING,
                    'message' => 'Master dashboard cache returning invalid data',
                    'details' => ['events_count' => $events_count]
                ];
            }
        }
        
        // Clean up test cache
        wp_cache_delete($test_key, 'hvac_health');
        
        return [
            'status' => self::STATUS_HEALTHY,
            'message' => 'Cache system is functioning correctly',
            'details' => ['test_key' => $test_key]
        ];
    }
    
    /**
     * Check authentication system
     */
    private static function check_authentication() {
        // Check if trainer roles exist
        $required_roles = ['hvac_trainer', 'hvac_master_trainer'];
        $missing_roles = [];
        
        foreach ($required_roles as $role) {
            if (!get_role($role)) {
                $missing_roles[] = $role;
            }
        }
        
        if (!empty($missing_roles)) {
            return [
                'status' => self::STATUS_CRITICAL,
                'message' => 'Required user roles are missing',
                'details' => ['missing_roles' => $missing_roles]
            ];
        }
        
        // Check for users with trainer roles
        $trainer_count = count(get_users(['role__in' => $required_roles]));
        if ($trainer_count === 0) {
            return [
                'status' => self::STATUS_WARNING,
                'message' => 'No users found with trainer roles',
                'details' => ['trainer_count' => $trainer_count]
            ];
        }
        
        // Test capability system
        if (!current_user_can('read')) {
            return [
                'status' => self::STATUS_WARNING,
                'message' => 'Capability system may have issues',
                'details' => []
            ];
        }
        
        return [
            'status' => self::STATUS_HEALTHY,
            'message' => 'Authentication system is healthy',
            'details' => ['trainer_count' => $trainer_count]
        ];
    }
    
    /**
     * Check event management system
     */
    private static function check_event_management() {
        // Check if The Events Calendar is active
        if (!class_exists('Tribe__Events__Main')) {
            return [
                'status' => self::STATUS_CRITICAL,
                'message' => 'The Events Calendar plugin is not active',
                'details' => []
            ];
        }
        
        // Check for events
        $events_count = wp_count_posts('tribe_events');
        $total_events = ($events_count->publish ?? 0) + ($events_count->private ?? 0);
        
        if ($total_events === 0) {
            return [
                'status' => self::STATUS_WARNING,
                'message' => 'No events found in the system',
                'details' => ['events_count' => $total_events]
            ];
        }
        
        // Check event creation capability
        $can_create_events = post_type_exists('tribe_events');
        if (!$can_create_events) {
            return [
                'status' => self::STATUS_CRITICAL,
                'message' => 'Event post type is not registered',
                'details' => []
            ];
        }
        
        return [
            'status' => self::STATUS_HEALTHY,
            'message' => 'Event management system is functioning',
            'details' => ['total_events' => $total_events]
        ];
    }
    
    /**
     * Check certificate system
     */
    private static function check_certificate_system() {
        // Check if certificate pages exist
        $certificate_pages = [
            'trainer/certificate-reports',
            'trainer/generate-certificates'
        ];
        
        $missing_pages = [];
        foreach ($certificate_pages as $page_slug) {
            if (!get_page_by_path($page_slug)) {
                $missing_pages[] = $page_slug;
            }
        }
        
        if (!empty($missing_pages)) {
            return [
                'status' => self::STATUS_WARNING,
                'message' => 'Certificate pages are missing',
                'details' => ['missing_pages' => $missing_pages]
            ];
        }
        
        // Check uploads directory permissions
        $upload_dir = wp_upload_dir();
        if (!wp_is_writable($upload_dir['basedir'])) {
            return [
                'status' => self::STATUS_CRITICAL,
                'message' => 'Uploads directory is not writable',
                'details' => ['upload_dir' => $upload_dir['basedir']]
            ];
        }
        
        return [
            'status' => self::STATUS_HEALTHY,
            'message' => 'Certificate system appears functional',
            'details' => ['pages_found' => count($certificate_pages) - count($missing_pages)]
        ];
    }
    
    /**
     * Check background jobs system
     */
    private static function check_background_jobs() {
        if (!class_exists('HVAC_Background_Jobs')) {
            return [
                'status' => self::STATUS_WARNING,
                'message' => 'Background jobs system not available',
                'details' => []
            ];
        }
        
        // Check if cron is working
        $cron_test = wp_next_scheduled('hvac_process_background_jobs');
        if (!$cron_test) {
            return [
                'status' => self::STATUS_WARNING,
                'message' => 'Background job processing is not scheduled',
                'details' => []
            ];
        }
        
        // Check queue stats
        $stats = HVAC_Background_Jobs::get_queue_stats();
        if ($stats['total'] > 100) {
            return [
                'status' => self::STATUS_WARNING,
                'message' => 'Background job queue is very large',
                'details' => ['queue_size' => $stats['total']]
            ];
        }
        
        return [
            'status' => self::STATUS_HEALTHY,
            'message' => 'Background jobs system is operational',
            'details' => ['queue_size' => $stats['total']]
        ];
    }
    
    /**
     * Check file permissions
     */
    private static function check_file_permissions() {
        $critical_paths = [
            WP_CONTENT_DIR,
            wp_upload_dir()['basedir'],
            HVAC_PLUGIN_DIR . 'assets'
        ];
        
        $permission_issues = [];
        foreach ($critical_paths as $path) {
            if (!is_dir($path) || !wp_is_writable($path)) {
                $permission_issues[] = $path;
            }
        }
        
        if (!empty($permission_issues)) {
            return [
                'status' => self::STATUS_CRITICAL,
                'message' => 'Critical directories have permission issues',
                'details' => ['problematic_paths' => $permission_issues]
            ];
        }
        
        return [
            'status' => self::STATUS_HEALTHY,
            'message' => 'File permissions are correct',
            'details' => ['paths_checked' => count($critical_paths)]
        ];
    }
    
    /**
     * Check third-party integrations
     */
    private static function check_third_party_integrations() {
        $integrations = [];
        
        // Check The Events Calendar
        if (class_exists('Tribe__Events__Main')) {
            $integrations['events_calendar'] = 'active';
        } else {
            $integrations['events_calendar'] = 'missing';
        }
        
        // Check Astra theme integration
        if (defined('ASTRA_THEME_VERSION')) {
            $integrations['astra_theme'] = 'active';
        } else {
            $integrations['astra_theme'] = 'not_detected';
        }
        
        // Check for critical missing integrations
        if ($integrations['events_calendar'] === 'missing') {
            return [
                'status' => self::STATUS_CRITICAL,
                'message' => 'Critical integration missing: The Events Calendar',
                'details' => $integrations
            ];
        }
        
        return [
            'status' => self::STATUS_HEALTHY,
            'message' => 'Third-party integrations are functional',
            'details' => $integrations
        ];
    }
    
    /**
     * Run automated health checks
     */
    public static function run_automated_checks() {
        $results = self::run_all_checks(true);
        
        // Send alerts for critical issues
        if ($results['overall_status'] === self::STATUS_CRITICAL) {
            self::send_health_alert($results);
        }
        
        HVAC_Logger::info(
            "Health check completed: {$results['overall_status']}",
            'Health Monitor'
        );
    }
    
    /**
     * Send health alert
     * 
     * @param array $results Health check results
     */
    private static function send_health_alert($results) {
        $admin_email = get_option('admin_email');
        $site_name = get_bloginfo('name');
        
        $critical_issues = array_filter($results['checks'], function($check) {
            return $check['status'] === self::STATUS_CRITICAL;
        });
        
        $subject = "[$site_name] Critical Health Check Alert";
        $message = "Critical issues detected in HVAC Community Events plugin:\n\n";
        
        foreach ($critical_issues as $type => $check) {
            $message .= "• {$check['name']}: {$check['message']}\n";
        }
        
        $message .= "\nPlease check the admin dashboard for more details.";
        
        wp_mail($admin_email, $subject, $message);
    }
    
    /**
     * Add admin menu
     */
    public static function add_admin_menu() {
        if (current_user_can('manage_options')) {
            add_management_page(
                'HVAC Health Monitor',
                'HVAC Health',
                'manage_options',
                'hvac-health-monitor',
                [__CLASS__, 'admin_page']
            );
        }
    }
    
    /**
     * Admin page
     */
    public static function admin_page() {
        $results = self::run_all_checks();
        
        ?>
        <div class="wrap">
            <h1>HVAC Health Monitor</h1>
            
            <div class="card">
                <h2>Overall Status: 
                    <span class="status-<?php echo esc_attr($results['overall_status']); ?>">
                        <?php echo esc_html(strtoupper($results['overall_status'])); ?>
                    </span>
                </h2>
                <p>Last checked: <?php echo date('Y-m-d H:i:s', $results['timestamp']); ?></p>
                <p>
                    <button type="button" id="run-health-check" class="button button-primary">Run Health Check</button>
                </p>
            </div>
            
            <div class="health-checks">
                <?php foreach ($results['checks'] as $type => $check): ?>
                <div class="card health-check status-<?php echo esc_attr($check['status']); ?>">
                    <h3><?php echo esc_html($check['name']); ?></h3>
                    <p class="status">Status: <?php echo esc_html(strtoupper($check['status'])); ?></p>
                    <p class="message"><?php echo esc_html($check['message']); ?></p>
                    <p class="execution-time">Checked in: <?php echo $check['execution_time']; ?>s</p>
                    
                    <?php if (!empty($check['details'])): ?>
                    <details>
                        <summary>Details</summary>
                        <pre><?php echo esc_html(json_encode($check['details'], JSON_PRETTY_PRINT)); ?></pre>
                    </details>
                    <?php endif; ?>
                </div>
                <?php endforeach; ?>
            </div>
            
            <style>
            .status-healthy { color: #46b450; }
            .status-warning { color: #ffb900; }
            .status-critical { color: #dc3232; }
            .health-check { margin: 10px 0; }
            .health-check.status-critical { border-left: 4px solid #dc3232; }
            .health-check.status-warning { border-left: 4px solid #ffb900; }
            .health-check.status-healthy { border-left: 4px solid #46b450; }
            </style>
            
            <script>
            document.getElementById('run-health-check').addEventListener('click', function() {
                this.disabled = true;
                this.textContent = 'Running...';
                
                fetch(ajaxurl, {
                    method: 'POST',
                    body: new URLSearchParams({
                        action: 'hvac_run_health_check',
                        nonce: '<?php echo wp_create_nonce('hvac_health_check'); ?>'
                    })
                })
                .then(response => response.json())
                .then(data => {
                    location.reload();
                })
                .catch(error => {
                    console.error('Health check failed:', error);
                    this.disabled = false;
                    this.textContent = 'Run Health Check';
                });
            });
            </script>
        </div>
        <?php
    }
    
    /**
     * AJAX health check
     */
    public static function ajax_run_health_check() {
        check_ajax_referer('hvac_health_check', 'nonce');
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Insufficient permissions');
        }
        
        $results = self::run_all_checks(true);
        wp_send_json_success($results);
    }
    
    /**
     * Show admin warnings
     */
    public static function show_health_warnings() {
        if (!current_user_can('manage_options')) {
            return;
        }
        
        $results = self::run_all_checks();
        
        if ($results['overall_status'] === self::STATUS_CRITICAL) {
            echo '<div class="notice notice-error"><p>';
            echo '<strong>HVAC Plugin Health Alert:</strong> Critical issues detected. ';
            echo '<a href="' . admin_url('tools.php?page=hvac-health-monitor') . '">View Details</a>';
            echo '</p></div>';
        }
    }
    
    /**
     * Register REST endpoints
     */
    public static function register_rest_endpoints() {
        register_rest_route('hvac/v1', '/health', [
            'methods' => 'GET',
            'callback' => [__CLASS__, 'rest_health_check'],
            'permission_callback' => function() {
                return current_user_can('manage_options');
            }
        ]);
    }
    
    /**
     * REST API health check
     */
    public static function rest_health_check() {
        $results = self::run_all_checks();
        
        return new WP_REST_Response([
            'status' => $results['overall_status'],
            'timestamp' => $results['timestamp'],
            'checks' => $results['checks']
        ], 200);
    }
    
    /**
     * WP-CLI health check command
     */
    public static function wp_cli_health_check($args, $assoc_args) {
        WP_CLI::line('Running HVAC health checks...');
        
        $results = self::run_all_checks(true);
        
        WP_CLI::line('Overall Status: ' . strtoupper($results['overall_status']));
        WP_CLI::line('');
        
        foreach ($results['checks'] as $type => $check) {
            $status_color = $check['status'] === self::STATUS_HEALTHY ? '%G' : 
                           ($check['status'] === self::STATUS_WARNING ? '%Y' : '%R');
            
            WP_CLI::line(sprintf(
                '%s: ' . $status_color . '%s%n - %s',
                $check['name'],
                strtoupper($check['status']),
                $check['message']
            ));
        }
        
        if ($results['overall_status'] !== self::STATUS_HEALTHY) {
            WP_CLI::error('Health checks failed with issues', false);
        } else {
            WP_CLI::success('All health checks passed');
        }
    }
}