using Microsoft.Extensions.Configuration;

namespace Logger;

/// <summary>
/// Factory for creating logger instances
/// </summary>
public static class LoggerFactory
{
    /// <summary>
    /// Create a logger that writes to console and file
    /// </summary>
    public static ILogger CreateCompositeLogger(
        LogLevel consoleLevel = LogLevel.Trace,
        FileLoggerOptions? fileOptions = null)
    {
        var consoleLogger = new ConsoleLogger(consoleLevel);
        var fileLogger = new FileLogger(fileOptions ?? new FileLoggerOptions());
        
        return new CompositeLogger(consoleLogger, fileLogger);
    }

    /// <summary>
    /// Create a logger from configuration section
    /// </summary>
    public static ILogger CreateFromConfiguration(IConfiguration configuration)
    {
        if (configuration == null) throw new ArgumentNullException(nameof(configuration));

        var section = configuration.GetSection("Logger");
        var consoleLevelString = section.GetValue("ConsoleMinimumLevel", "Trace");
        var consoleLevel = ParseLogLevel(consoleLevelString);

        var fileOptions = section.GetSection("File").Get<FileLoggerOptions>() ?? new FileLoggerOptions();

        return CreateCompositeLogger(consoleLevel, fileOptions);
    }

    private static LogLevel ParseLogLevel(string? level)
    {
        if (string.IsNullOrWhiteSpace(level))
            return LogLevel.Trace;

        return level.Trim().ToLowerInvariant() switch
        {
            "trace" => LogLevel.Trace,
            "debug" => LogLevel.Debug,
            "info" => LogLevel.Info,
            "information" => LogLevel.Info,
            "warn" => LogLevel.Warning,
            "warning" => LogLevel.Warning,
            "error" => LogLevel.Error,
            "fatal" => LogLevel.Fatal,
            _ => LogLevel.Trace
        };
    }

    /// <summary>
    /// Create a console-only logger
    /// </summary>
    public static ILogger CreateConsoleLogger(LogLevel minimumLevel = LogLevel.Trace)
    {
        return new ConsoleLogger(minimumLevel);
    }

    /// <summary>
    /// Create a file-only logger
    /// </summary>
    public static ILogger CreateFileLogger(FileLoggerOptions? options = null)
    {
        return new FileLogger(options ?? new FileLoggerOptions());
    }
}
