<?php
namespace Utils;

use Core\Config;

/**
 * Classe de logging centralizada
 * 
 * Versão melhorada que:
 * - Utiliza namespaces para organização
 * - Implementa níveis de log (debug, info, warning, error)
 * - Suporta múltiplos canais de log
 * - Rotação de arquivos de log
 */

class Logger {
    private $channel;
    private $logPath;
    private $config;
    private $maxFileSize = 5242880; // 5MB
    private $maxFiles = 5;
    
    /**
     * Construtor
     * 
     * @param string $channel Nome do canal de log
     */
    public function __construct($channel = 'app') {
        $this->channel = $channel;
        $this->config = Config::getInstance();
        $this->logPath = $this->config->get('log_path', __DIR__ . '/../../logs');
        
        // Criar diretório de logs se não existir
        if (!is_dir($this->logPath)) {
            mkdir($this->logPath, 0755, true);
        }
    }
    
    /**
     * Registra uma mensagem de debug
     * 
     * @param string $message Mensagem a ser registrada
     * @param array $context Contexto adicional
     */
    public function debug($message, array $context = []) {
        $this->log('DEBUG', $message, $context);
    }
    
    /**
     * Registra uma mensagem de informação
     * 
     * @param string $message Mensagem a ser registrada
     * @param array $context Contexto adicional
     */
    public function info($message, array $context = []) {
        $this->log('INFO', $message, $context);
    }
    
    /**
     * Registra uma mensagem de aviso
     * 
     * @param string $message Mensagem a ser registrada
     * @param array $context Contexto adicional
     */
    public function warning($message, array $context = []) {
        $this->log('WARNING', $message, $context);
    }
    
    /**
     * Registra uma mensagem de erro
     * 
     * @param string $message Mensagem a ser registrada
     * @param array $context Contexto adicional
     */
    public function error($message, array $context = []) {
        $this->log('ERROR', $message, $context);
    }
    
    /**
     * Registra uma mensagem no log
     * 
     * @param string $level Nível do log
     * @param string $message Mensagem a ser registrada
     * @param array $context Contexto adicional
     */
    private function log($level, $message, array $context = []) {
        $logFile = $this->getLogFile();
        
        // Verificar tamanho do arquivo e fazer rotação se necessário
        $this->rotateLogIfNeeded($logFile);
        
        // Formatar mensagem
        $timestamp = date('Y-m-d H:i:s');
        $formattedMessage = "[$timestamp] [$level] [$this->channel] $message";
        
        // Adicionar contexto se existir
        if (!empty($context)) {
            $formattedMessage .= ' ' . json_encode($context);
        }
        
        $formattedMessage .= PHP_EOL;
        
        // Escrever no arquivo
        file_put_contents($logFile, $formattedMessage, FILE_APPEND);
    }
    
    /**
     * Obtém o caminho do arquivo de log
     * 
     * @return string Caminho do arquivo de log
     */
    private function getLogFile() {
        return $this->logPath . '/' . $this->channel . '.log';
    }
    
    /**
     * Verifica se o arquivo de log precisa ser rotacionado
     * 
     * @param string $logFile Caminho do arquivo de log
     */
    private function rotateLogIfNeeded($logFile) {
        if (!file_exists($logFile)) {
            return;
        }
        
        if (filesize($logFile) >= $this->maxFileSize) {
            $this->rotateLog($logFile);
        }
    }
    
    /**
     * Rotaciona o arquivo de log
     * 
     * @param string $logFile Caminho do arquivo de log
     */
    private function rotateLog($logFile) {
        // Remover arquivo mais antigo se atingir o limite
        $oldestLog = $logFile . '.' . $this->maxFiles;
        if (file_exists($oldestLog)) {
            unlink($oldestLog);
        }
        
        // Mover arquivos existentes
        for ($i = $this->maxFiles - 1; $i >= 1; $i--) {
            $oldFile = $logFile . '.' . $i;
            $newFile = $logFile . '.' . ($i + 1);
            
            if (file_exists($oldFile)) {
                rename($oldFile, $newFile);
            }
        }
        
        // Mover arquivo atual
        if (file_exists($logFile)) {
            rename($logFile, $logFile . '.1');
        }
    }
}
