<?php

namespace App\Core;

/**
 * Logger - نظام تسجيل مركزي
 */
class Logger
{
    private string $logDir;
    private string $logFile;
    private const MAX_LOG_SIZE = 10 * 1024 * 1024; // 10MB
    private const MAX_LOG_FILES = 5;

    public function __construct(?string $logDir = null)
    {
        $this->logDir = $logDir ?? __DIR__ . '/../../logs';
        if (!is_dir($this->logDir)) {
            if (!@mkdir($this->logDir, 0755, true) && !is_dir($this->logDir)) {
                // إذا فشل إنشاء المجلد، استخدم مجلد النظام المؤقت
                $this->logDir = sys_get_temp_dir() . '/smartlab_logs';
                @mkdir($this->logDir, 0755, true);
            }
        }
        
        // التأكد من أن المجلد قابل للكتابة
        if (!is_writable($this->logDir)) {
            // محاولة تغيير الصلاحيات
            @chmod($this->logDir, 0755);
        }
        
        $this->logFile = $this->logDir . '/app_' . date('Y-m-d') . '.log';
    }

    /**
     * تسجيل رسالة معلومات
     */
    public function info(string $message, array $context = []): void
    {
        $this->log('INFO', $message, $context);
    }

    /**
     * تسجيل رسالة تحذير
     */
    public function warning(string $message, array $context = []): void
    {
        $this->log('WARNING', $message, $context);
    }

    /**
     * تسجيل رسالة خطأ
     */
    public function error(string $message, array $context = []): void
    {
        $this->log('ERROR', $message, $context);
    }

    /**
     * تسجيل رسالة debug
     */
    public function debug(string $message, array $context = []): void
    {
        if (defined('DEBUG_MODE') && DEBUG_MODE) {
            $this->log('DEBUG', $message, $context);
        }
    }

    /**
     * تسجيل رسالة حرجة
     */
    public function critical(string $message, array $context = []): void
    {
        $this->log('CRITICAL', $message, $context);
        
        // إرسال إشعار للـ critical errors
        $this->notifyCritical($message, $context);
    }

    /**
     * تسجيل الرسالة
     */
    private function log(string $level, string $message, array $context = []): void
    {
        $timestamp = date('Y-m-d H:i:s');
        $contextStr = !empty($context) ? ' ' . json_encode($context, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : '';
        $logEntry = "[{$timestamp}] [{$level}] {$message}{$contextStr}" . PHP_EOL;

        // كتابة في الملف مع معالجة الأخطاء
        $result = @file_put_contents($this->logFile, $logEntry, FILE_APPEND | LOCK_EX);
        
        // إذا فشلت الكتابة، حاول كتابة في error_log
        if ($result === false) {
            error_log("SMARTLAB Logger Error: Failed to write to {$this->logFile}. Message: {$message}");
        }

        // تدوير الملفات إذا لزم الأمر
        $this->rotateLogs();
    }

    /**
     * تدوير ملفات السجل
     */
    private function rotateLogs(): void
    {
        if (!file_exists($this->logFile)) {
            return;
        }

        // إذا تجاوز الملف الحد الأقصى، قم بتدويره
        if (filesize($this->logFile) > self::MAX_LOG_SIZE) {
            $backupFile = $this->logFile . '.' . time() . '.bak';
            @rename($this->logFile, $backupFile);
        }

        // حذف الملفات القديمة
        $files = glob($this->logDir . '/app_*.log*');
        if (count($files) > self::MAX_LOG_FILES) {
            usort($files, function($a, $b) {
                return filemtime($a) - filemtime($b);
            });
            
            $filesToDelete = array_slice($files, 0, count($files) - self::MAX_LOG_FILES);
            foreach ($filesToDelete as $file) {
                @unlink($file);
            }
        }
    }

    /**
     * إشعار للأخطاء الحرجة
     */
    private function notifyCritical(string $message, array $context): void
    {
        // يمكن إضافة إرسال email أو إشعارات أخرى هنا
        // حالياً نكتفي بتسجيل في ملف منفصل
        $criticalLog = $this->logDir . '/critical_' . date('Y-m-d') . '.log';
        $logEntry = '[' . date('Y-m-d H:i:s') . '] ' . $message . ' ' . json_encode($context, JSON_UNESCAPED_UNICODE) . PHP_EOL;
        @file_put_contents($criticalLog, $logEntry, FILE_APPEND | LOCK_EX);
    }

    /**
     * تسجيل استثناء
     */
    public function exception(\Throwable $exception, array $context = []): void
    {
        $message = get_class($exception) . ': ' . $exception->getMessage();
        
        // إضافة معلومات الاستثناء الأساسية
        $exceptionContext = [
            'file' => $exception->getFile(),
            'line' => $exception->getLine(),
            'trace' => $exception->getTraceAsString(),
            'code' => $exception->getCode(),
        ];
        
        // دمج السياق الممرر مع سياق الاستثناء
        $fullContext = array_merge($exceptionContext, $context);
        
        // تسجيل كخطأ حرج للاستثناءات
        $this->critical($message, $fullContext);
    }

    /**
     * تسجيل طلب HTTP
     */
    public function request(string $method, string $uri, array $data = []): void
    {
        $context = [
            'method' => $method,
            'uri' => $uri,
            'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'unknown'
        ];
        
        if (!empty($data)) {
            $context['data'] = $data;
        }
        
        $this->info("HTTP Request: {$method} {$uri}", $context);
    }
}
