<?php

namespace App\Core;

/**
 * Error Handler - معالج الأخطاء المركزي
 */
class ErrorHandler
{
    private static ?Logger $logger = null;
    private static bool $registered = false;

    /**
     * تسجيل معالج الأخطاء
     */
    public static function register(?Logger $logger = null): void
    {
        if (self::$registered) {
            return;
        }

        self::$logger = $logger;

        // تسجيل معالج الاستثناءات
        set_exception_handler([self::class, 'handleException']);

        // تسجيل معالج الأخطاء
        set_error_handler([self::class, 'handleError'], E_ALL | E_STRICT);

        // تسجيل معالج الأخطاء القاتلة
        register_shutdown_function([self::class, 'handleShutdown']);

        self::$registered = true;
    }

    /**
     * معالجة الاستثناءات
     */
    public static function handleException(\Throwable $exception): void
    {
        // إنشاء معرف فريد للخطأ لتسهيل التتبع
        $errorId = uniqid('ERR_', true);
        
        // جمع معلومات إضافية عن الطلب
        $requestContext = [
            'error_id' => $errorId,
            'method' => $_SERVER['REQUEST_METHOD'] ?? 'UNKNOWN',
            'uri' => $_SERVER['REQUEST_URI'] ?? 'UNKNOWN',
            'ip' => $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN',
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'UNKNOWN',
            'referer' => $_SERVER['HTTP_REFERER'] ?? null,
        ];
        
        // إضافة بيانات POST إذا كانت موجودة (مع حماية البيانات الحساسة)
        if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST' && !empty($_POST)) {
            $sanitizedPost = $_POST;
            // إخفاء البيانات الحساسة
            $sensitiveKeys = ['password', 'password_hash', 'api_key', 'token', 'secret'];
            foreach ($sensitiveKeys as $key) {
                if (isset($sanitizedPost[$key])) {
                    $sanitizedPost[$key] = '***HIDDEN***';
                }
            }
            $requestContext['post_data'] = $sanitizedPost;
        }
        
        // تسجيل الخطأ مع السياق الكامل
        try {
            if (self::$logger) {
                $requestContext['exception_message'] = $exception->getMessage();
                $requestContext['exception_file'] = $exception->getFile();
                $requestContext['exception_line'] = $exception->getLine();
                $requestContext['exception_trace'] = $exception->getTraceAsString();
                self::$logger->exception($exception, $requestContext);
            } else {
                // إذا لم يكن Logger متاحاً، استخدم error_log
                error_log("SMARTLAB Error [{$errorId}]: " . $exception->getMessage() . " in " . $exception->getFile() . ":" . $exception->getLine());
            }
        } catch (\Throwable $logError) {
            // حتى لو فشل التسجيل، استمر في معالجة الخطأ
            error_log("SMARTLAB Error Handler: Failed to log error. Original: " . $exception->getMessage() . " | Logger Error: " . $logError->getMessage());
        }

        // في بيئة الإنتاج، لا نعرض تفاصيل الخطأ
        $isProduction = !defined('DEBUG_MODE') || !DEBUG_MODE;

        // تحديد نوع المحتوى
        $isJsonRequest = (
            isset($_SERVER['HTTP_ACCEPT']) && 
            strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false
        ) || (
            isset($_SERVER['CONTENT_TYPE']) && 
            strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false
        );

        if ($isProduction) {
            http_response_code(500);
            
            if ($isJsonRequest) {
                header('Content-Type: application/json; charset=utf-8');
                echo json_encode([
                    'error' => 'حدث خطأ داخلي في الخادم',
                    'message' => 'يرجى المحاولة لاحقاً أو الاتصال بالدعم الفني',
                    'error_id' => $errorId
                ], JSON_UNESCAPED_UNICODE);
            } else {
                header('Content-Type: text/html; charset=utf-8');
                echo '<!DOCTYPE html>
<html dir="rtl" lang="ar">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>خطأ في الخادم</title>
    <style>
        body { font-family: Arial, sans-serif; text-align: center; padding: 50px; background: #f5f5f5; }
        .error-box { background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); max-width: 600px; margin: 0 auto; }
        h1 { color: #d32f2f; margin-bottom: 20px; }
        p { color: #666; line-height: 1.6; }
        .error-id { background: #f5f5f5; padding: 10px; border-radius: 4px; margin-top: 20px; font-family: monospace; font-size: 12px; }
    </style>
</head>
<body>
    <div class="error-box">
        <h1>حدث خطأ داخلي في الخادم</h1>
        <p>نعتذر، حدث خطأ غير متوقع. يرجى المحاولة لاحقاً أو الاتصال بالدعم الفني.</p>
        <div class="error-id">معرف الخطأ: ' . htmlspecialchars($errorId, ENT_QUOTES, 'UTF-8') . '</div>
    </div>
</body>
</html>';
            }
        } else {
            // في بيئة التطوير، عرض تفاصيل الخطأ
            http_response_code(500);
            header('Content-Type: text/html; charset=utf-8');
            echo '<!DOCTYPE html>
<html dir="rtl" lang="ar">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>خطأ في التطبيق</title>
    <style>
        body { font-family: Arial, sans-serif; padding: 20px; background: #f5f5f5; }
        .error-box { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        h1 { color: #d32f2f; }
        pre { background: #f5f5f5; padding: 15px; border-radius: 4px; overflow-x: auto; direction: ltr; text-align: left; }
    </style>
</head>
<body>
    <div class="error-box">
        <h1>خطأ في التطبيق</h1>
        <pre>';
            echo 'معرف الخطأ: ' . htmlspecialchars($errorId, ENT_QUOTES, 'UTF-8') . PHP_EOL;
            echo 'الرسالة: ' . htmlspecialchars($exception->getMessage(), ENT_QUOTES, 'UTF-8') . PHP_EOL;
            echo 'الملف: ' . htmlspecialchars($exception->getFile(), ENT_QUOTES, 'UTF-8') . PHP_EOL;
            echo 'السطر: ' . $exception->getLine() . PHP_EOL;
            echo PHP_EOL . 'Stack Trace:' . PHP_EOL;
            echo htmlspecialchars($exception->getTraceAsString(), ENT_QUOTES, 'UTF-8');
            echo '</pre>
    </div>
</body>
</html>';
        }

        exit(1);
    }

    /**
     * معالجة الأخطاء
     */
    public static function handleError(int $severity, string $message, string $file, int $line): bool
    {
        // تجاهل الأخطاء التي تم قمعها بـ @
        if (!(error_reporting() & $severity)) {
            return false;
        }

        $errorTypes = [
            E_ERROR => 'ERROR',
            E_WARNING => 'WARNING',
            E_PARSE => 'PARSE',
            E_NOTICE => 'NOTICE',
            E_CORE_ERROR => 'CORE_ERROR',
            E_CORE_WARNING => 'CORE_WARNING',
            E_COMPILE_ERROR => 'COMPILE_ERROR',
            E_COMPILE_WARNING => 'COMPILE_WARNING',
            E_USER_ERROR => 'USER_ERROR',
            E_USER_WARNING => 'USER_WARNING',
            E_USER_NOTICE => 'USER_NOTICE',
            E_STRICT => 'STRICT',
            E_RECOVERABLE_ERROR => 'RECOVERABLE_ERROR',
            E_DEPRECATED => 'DEPRECATED',
            E_USER_DEPRECATED => 'USER_DEPRECATED',
        ];

        $errorType = $errorTypes[$severity] ?? 'UNKNOWN';

        if (self::$logger) {
            self::$logger->error("PHP {$errorType}: {$message}", [
                'file' => $file,
                'line' => $line,
                'severity' => $severity
            ]);
        }

        // للأخطاء الحرجة، إيقاف التنفيذ
        if ($severity === E_ERROR || $severity === E_CORE_ERROR || $severity === E_COMPILE_ERROR) {
            throw new \ErrorException($message, 0, $severity, $file, $line);
        }

        return true;
    }

    /**
     * معالجة الأخطاء القاتلة
     */
    public static function handleShutdown(): void
    {
        $error = error_get_last();

        if ($error !== null && in_array($error['type'], [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE], true)) {
            $errorId = uniqid('FATAL_', true);
            
            $requestContext = [
                'error_id' => $errorId,
                'method' => $_SERVER['REQUEST_METHOD'] ?? 'UNKNOWN',
                'uri' => $_SERVER['REQUEST_URI'] ?? 'UNKNOWN',
                'ip' => $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN',
            ];
            
            if (self::$logger) {
                self::$logger->critical('Fatal Error: ' . $error['message'], array_merge($requestContext, [
                    'file' => $error['file'],
                    'line' => $error['line'],
                    'type' => $error['type']
                ]));
            }

            // تحديد نوع المحتوى
            $isJsonRequest = (
                isset($_SERVER['HTTP_ACCEPT']) && 
                strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false
            );

            http_response_code(500);
            
            if ($isJsonRequest) {
                header('Content-Type: application/json; charset=utf-8');
                echo json_encode([
                    'error' => 'حدث خطأ قاتل في التطبيق',
                    'message' => 'يرجى المحاولة لاحقاً أو الاتصال بالدعم الفني',
                    'error_id' => $errorId
                ], JSON_UNESCAPED_UNICODE);
            } else {
                header('Content-Type: text/html; charset=utf-8');
                echo '<!DOCTYPE html>
<html dir="rtl" lang="ar">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>خطأ قاتل</title>
    <style>
        body { font-family: Arial, sans-serif; text-align: center; padding: 50px; background: #f5f5f5; }
        .error-box { background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); max-width: 600px; margin: 0 auto; }
        h1 { color: #d32f2f; margin-bottom: 20px; }
        p { color: #666; line-height: 1.6; }
        .error-id { background: #f5f5f5; padding: 10px; border-radius: 4px; margin-top: 20px; font-family: monospace; font-size: 12px; }
    </style>
</head>
<body>
    <div class="error-box">
        <h1>حدث خطأ قاتل في التطبيق</h1>
        <p>نعتذر، حدث خطأ غير متوقع. يرجى المحاولة لاحقاً أو الاتصال بالدعم الفني.</p>
        <div class="error-id">معرف الخطأ: ' . htmlspecialchars($errorId, ENT_QUOTES, 'UTF-8') . '</div>
    </div>
</body>
</html>';
            }
        }
    }
}
