<?php

namespace App\Helpers;

class Logger
{
    private const LOG_RETENTION_DAYS = 30;
    private static string $basePath = '';
    private static bool $cleanupDone = false;

    public static function setBasePath(string $path): void
    {
        self::$basePath = rtrim($path, '/');
    }

    public static function info(string $message, string $channel = 'app'): void
    {
        self::write('INFO', $message, $channel);
    }

    public static function error(string $message, string $channel = 'app'): void
    {
        self::write('ERROR', $message, $channel);
    }

    public static function warning(string $message, string $channel = 'app'): void
    {
        self::write('WARNING', $message, $channel);
    }

    private static function write(string $level, string $message, string $channel): void
    {
        $time = date('Y-m-d H:i:s');
        if ($channel === 'publish') {
            // Zapis do bazy
            try {
                $db = \App\Core\Database::getInstance();
                $stmt = $db->prepare("INSERT INTO cron_logs (datetime, level, message, channel) VALUES (:dt, :level, :msg, :ch)");
                $stmt->execute([
                    'dt' => $time,
                    'level' => $level,
                    'msg' => $message,
                    'ch' => $channel,
                ]);
                // Usuwanie starszych niż 30 dni
                $db->exec("DELETE FROM cron_logs WHERE datetime < (NOW() - INTERVAL 30 DAY)");
            } catch (\Throwable $e) {
                // Fallback do pliku jeśli błąd bazy
                self::writeFileFallback($level, $message, $channel, $time);
            }
            return;
        }
        // Standardowy plikowy log
        self::writeFileFallback($level, $message, $channel, $time);
    }

    private static function writeFileFallback(string $level, string $message, string $channel, string $time): void
    {
        $date = substr($time, 0, 10);
        $logDir = self::$basePath . '/storage/logs';
        if (!is_dir($logDir)) {
            mkdir($logDir, 0755, true);
        }
        self::cleanupOldLogs($logDir);
        $logFile = "{$logDir}/{$channel}_{$date}.log";
        $line = "[{$time}] {$level}: {$message}" . PHP_EOL;
        file_put_contents($logFile, $line, FILE_APPEND | LOCK_EX);
    }

    private static function cleanupOldLogs(string $logDir): void
    {
        if (self::$cleanupDone) {
            return;
        }
        self::$cleanupDone = true;

        $files = glob($logDir . '/*.log');
        if ($files === false) {
            return;
        }

        $maxAge = self::LOG_RETENTION_DAYS * 86400;
        $now = time();

        foreach ($files as $file) {
            if (!is_file($file)) {
                continue;
            }

            $mtime = @filemtime($file);
            if ($mtime === false) {
                continue;
            }

            if (($now - $mtime) > $maxAge) {
                @unlink($file);
            }
        }
    }
}
