<?php
namespace App\Utils;

// Ensure constants are loaded
if (!defined('LOG_FILE')) {
    require_once __DIR__ . '/../config/constants.php';
}

/**
 * Logger Utility Class
 */
class Logger
{
    private static $lastRotationCheck = [];

    /**
     * Write log entry
     */
    public static function writeLog($message, $level = 'INFO', $context = [])
    {
        $timestamp = date('Y-m-d H:i:s');
        $logEntry = sprintf(
            "[%s] [%s] %s %s\n",
            $timestamp,
            $level,
            $message,
            !empty($context) ? json_encode($context, JSON_UNESCAPED_UNICODE) : ''
        );
        
        self::maybeRotateLogFile(LOG_FILE);
        if (in_array($level, ['ERROR', 'CRITICAL'])) {
            self::maybeRotateLogFile(ERROR_LOG_FILE);
        }

        // Write to general log
        @file_put_contents(LOG_FILE, $logEntry, FILE_APPEND | LOCK_EX);
        
        // Write to error log if error
        if (in_array($level, ['ERROR', 'CRITICAL'])) {
            @file_put_contents(ERROR_LOG_FILE, $logEntry, FILE_APPEND | LOCK_EX);
        }
        
        // Also log to PHP error_log for server logs
        if (in_array($level, ['ERROR', 'CRITICAL', 'WARNING'])) {
            error_log($logEntry);
        }
    }

    public static function logError($message, $exception = null, $context = [])
    {
        $context['exception'] = $exception ? [
            'message' => $exception->getMessage(),
            'file' => $exception->getFile(),
            'line' => $exception->getLine(),
            'trace' => $exception->getTraceAsString()
        ] : null;
        self::writeLog($message, 'ERROR', $context);
    }

    public static function logInfo($message, $context = [])
    {
        self::writeLog($message, 'INFO', $context);
    }

    public static function logWarning($message, $context = [])
    {
        self::writeLog($message, 'WARNING', $context);
    }

    public static function logDebug($message, $context = [])
    {
        self::writeLog($message, 'DEBUG', $context);
    }

    private static function maybeRotateLogFile($filePath)
    {
        if (empty($filePath)) {
            return;
        }

        $maxBytes = (int)(getenv('LOG_ROTATE_MAX_BYTES') ?: 20 * 1024 * 1024); // 20MB default
        if ($maxBytes <= 0) {
            return;
        }

        $now = time();
        $lastChecked = self::$lastRotationCheck[$filePath] ?? 0;
        if (($now - $lastChecked) < 5) {
            return;
        }
        self::$lastRotationCheck[$filePath] = $now;

        clearstatcache(true, $filePath);
        if (!is_file($filePath)) {
            return;
        }

        $size = @filesize($filePath);
        if ($size === false || $size < $maxBytes) {
            return;
        }

        $rotatedPath = $filePath . '.' . date('Ymd_His');
        if (!@rename($filePath, $rotatedPath)) {
            return;
        }

        self::pruneRotatedLogs($filePath);
    }

    private static function pruneRotatedLogs($filePath)
    {
        $keepFiles = (int)(getenv('LOG_ROTATE_KEEP_FILES') ?: 5);
        if ($keepFiles < 1) {
            $keepFiles = 1;
        }

        $rotatedFiles = glob($filePath . '.*');
        if (!is_array($rotatedFiles) || count($rotatedFiles) <= $keepFiles) {
            return;
        }

        usort($rotatedFiles, function ($a, $b) {
            $timeA = @filemtime($a) ?: 0;
            $timeB = @filemtime($b) ?: 0;
            return $timeB <=> $timeA;
        });

        foreach (array_slice($rotatedFiles, $keepFiles) as $oldFile) {
            @unlink($oldFile);
        }
    }
}

