<?php

declare(strict_types=1);

namespace App\Framework\Logging\ValueObjects;

use App\Framework\Logging\LogLevel;

/**
 * Configuration Value Object for LogViewer
 * Immutable configuration for log viewing behavior
 */
final readonly class LogViewerConfig
{
    /**
     * @param string $storageLogsPath Base path for log storage
     * @param array<int, string> $logDirectories Subdirectories to scan for logs
     * @param int $defaultLimit Default number of log entries to return
     * @param array<int, LogLevel> $logLevels Available log levels
     */
    public function __construct(
        public string $storageLogsPath,
        public array $logDirectories,
        public int $defaultLimit = 100,
        public array $logLevels = [
            LogLevel::DEBUG,
            LogLevel::INFO,
            LogLevel::WARNING,
            LogLevel::ERROR,
            LogLevel::CRITICAL,
        ]
    ) {
        if ($defaultLimit < 1) {
            throw new \InvalidArgumentException('Default limit must be at least 1');
        }

        if (empty($logDirectories)) {
            throw new \InvalidArgumentException('At least one log directory must be specified');
        }

        if (empty($logLevels)) {
            throw new \InvalidArgumentException('At least one log level must be specified');
        }
    }

    /**
     * Create default configuration for production
     */
    public static function createDefault(): self
    {
        return new self(
            storageLogsPath: '/var/www/html/storage/logs',
            logDirectories: ['app', 'debug', 'security'],
            defaultLimit: 100
        );
    }

    /**
     * Create configuration for development with more verbose logging
     */
    public static function createForDevelopment(): self
    {
        return new self(
            storageLogsPath: '/var/www/html/storage/logs',
            logDirectories: ['app', 'debug', 'security', 'performance'],
            defaultLimit: 500,
            logLevels: [
                LogLevel::DEBUG,
                LogLevel::INFO,
                LogLevel::NOTICE,
                LogLevel::WARNING,
                LogLevel::ERROR,
                LogLevel::CRITICAL,
                LogLevel::ALERT,
                LogLevel::EMERGENCY,
            ]
        );
    }

    /**
     * Get full path for a subdirectory
     */
    public function getSubdirectoryPath(string $subdirectory): string
    {
        return $this->storageLogsPath . '/' . $subdirectory;
    }

    /**
     * Check if a log level is configured
     */
    public function hasLogLevel(LogLevel $level): bool
    {
        foreach ($this->logLevels as $configuredLevel) {
            if ($configuredLevel === $level) {
                return true;
            }
        }
        return false;
    }

    /**
     * Get log level names as array
     *
     * @return array<int, string>
     */
    public function getLogLevelNames(): array
    {
        return array_map(
            fn(LogLevel $level) => $level->getName(),
            $this->logLevels
        );
    }
}
