<?php

namespace App\Core;

/**
 * Health Check - فحص صحة النظام
 * للتحقق من حالة النظام والمكونات
 */
class HealthCheck
{
    private \PDO $db;
    private array $config;
    private Logger $logger;

    public function __construct(\PDO $db, array $config, Logger $logger)
    {
        $this->db = $db;
        $this->config = $config;
        $this->logger = $logger;
    }

    /**
     * فحص شامل للنظام
     */
    public function check(): array
    {
        return [
            'status' => 'healthy',
            'timestamp' => date('Y-m-d H:i:s'),
            'checks' => [
                'database' => $this->checkDatabase(),
                'cache' => $this->checkCache(),
                'redis' => $this->checkRedis(),
                'disk_space' => $this->checkDiskSpace(),
                'memory' => $this->checkMemory(),
                'writable_dirs' => $this->checkWritableDirs()
            ]
        ];
    }

    /**
     * فحص قاعدة البيانات
     */
    private function checkDatabase(): array
    {
        try {
            $this->db->query('SELECT 1');
            return ['status' => 'ok', 'message' => 'Database connection successful'];
        } catch (\Throwable $e) {
            return ['status' => 'error', 'message' => $e->getMessage()];
        }
    }

    /**
     * فحص Cache
     */
    private function checkCache(): array
    {
        $cacheDir = __DIR__ . '/../../cache';
        if (!is_dir($cacheDir)) {
            @mkdir($cacheDir, 0755, true);
        }
        
        $writable = is_writable($cacheDir);
        return [
            'status' => $writable ? 'ok' : 'error',
            'message' => $writable ? 'Cache directory is writable' : 'Cache directory is not writable'
        ];
    }

    /**
     * فحص Redis
     */
    private function checkRedis(): array
    {
        try {
            $redisConfig = $this->config['cache']['redis'] ?? [];
            $redis = new \App\Core\Cache\RedisCache($redisConfig);
            
            if ($redis->isAvailable()) {
                return ['status' => 'ok', 'message' => 'Redis is available'];
            }
            
            return ['status' => 'warning', 'message' => 'Redis is not available, using file cache'];
        } catch (\Throwable $e) {
            return ['status' => 'warning', 'message' => 'Redis check failed: ' . $e->getMessage()];
        }
    }

    /**
     * فحص مساحة القرص
     */
    private function checkDiskSpace(): array
    {
        $freeSpace = disk_free_space(__DIR__);
        $totalSpace = disk_total_space(__DIR__);
        $usedPercent = (($totalSpace - $freeSpace) / $totalSpace) * 100;
        
        $status = 'ok';
        if ($usedPercent > 90) {
            $status = 'critical';
        } elseif ($usedPercent > 80) {
            $status = 'warning';
        }
        
        return [
            'status' => $status,
            'free_space_mb' => round($freeSpace / 1024 / 1024, 2),
            'used_percent' => round($usedPercent, 2)
        ];
    }

    /**
     * فحص الذاكرة
     */
    private function checkMemory(): array
    {
        $memoryUsage = memory_get_usage(true);
        $memoryPeak = memory_get_peak_usage(true);
        $memoryLimit = ini_get('memory_limit');
        
        return [
            'status' => 'ok',
            'current_mb' => round($memoryUsage / 1024 / 1024, 2),
            'peak_mb' => round($memoryPeak / 1024 / 1024, 2),
            'limit' => $memoryLimit
        ];
    }

    /**
     * فحص المجلدات القابلة للكتابة
     */
    private function checkWritableDirs(): array
    {
        $dirs = [
            'cache' => __DIR__ . '/../../cache',
            'logs' => __DIR__ . '/../../logs',
            'uploads' => __DIR__ . '/../../uploads',
            'backups' => __DIR__ . '/../../backups'
        ];
        
        $results = [];
        foreach ($dirs as $name => $path) {
            if (!is_dir($path)) {
                @mkdir($path, 0755, true);
            }
            $results[$name] = [
                'writable' => is_writable($path),
                'exists' => is_dir($path)
            ];
        }
        
        return $results;
    }

    /**
     * API endpoint للـ health check
     */
    public function apiResponse(): void
    {
        $health = $this->check();
        $overallStatus = 'healthy';
        
        foreach ($health['checks'] as $check) {
            if (is_array($check) && isset($check['status'])) {
                if ($check['status'] === 'error' || $check['status'] === 'critical') {
                    $overallStatus = 'unhealthy';
                    break;
                } elseif ($check['status'] === 'warning' && $overallStatus === 'healthy') {
                    $overallStatus = 'degraded';
                }
            }
        }
        
        $health['status'] = $overallStatus;
        $statusCode = $overallStatus === 'healthy' ? 200 : ($overallStatus === 'degraded' ? 200 : 503);
        
        http_response_code($statusCode);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($health, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
        exit;
    }
}
