using System;
using EonaCat.Logger.EonaCatCoreLogger.Models;
using EonaCat.Logger.Extensions;
using EonaCat.Logger.Managers;
using Microsoft.Extensions.Logging;

namespace EonaCat.Logger.EonaCatCoreLogger.Internal
{
    // This file is part of the EonaCat project(s) which is released under the Apache License.
    // See the LICENSE file or go to https://EonaCat.com/License for full license details.

    public class BatchingLogger : ILogger
    {
        private LoggerSettings _loggerSettings;
        private readonly BatchingLoggerProvider _provider;
        private readonly string _category;
        private DateTimeOffset CurrentDateTimeOffset => _loggerSettings.UseLocalTime ? DateTimeOffset.Now : DateTimeOffset.UtcNow;
        private DateTime CurrentDateTme => _loggerSettings.UseLocalTime ? DateTime.Now : DateTime.UtcNow;

        public BatchingLogger(BatchingLoggerProvider loggerProvider, string categoryName, LoggerSettings loggerSettings)
        {
            _loggerSettings = loggerSettings;
            _provider = loggerProvider;
            _category = categoryName;
        }

        public IDisposable BeginScope<TState>(TState state)
        {
            return null;
        }

        public bool IsEnabled(LogLevel logLevel)
        {
            return logLevel != LogLevel.None;
        }

        public void Log<TState>(DateTimeOffset timestamp, LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel)) return;
            
            if (_loggerSettings == null)
            {
                _loggerSettings = new LoggerSettings();
            }

            var message = LogHelper.FormatMessageWithHeader(_loggerSettings, logLevel.FromLogLevel(), formatter(state, exception), timestamp.DateTime) + Environment.NewLine;
            if (exception != null)
            { 
                message = exception.FormatExceptionToMessage() + Environment.NewLine;
            }

            _provider.AddMessage(timestamp, message);

            var currentMessage = new EonaCatLogMessage 
            {
                DateTime = timestamp.DateTime, 
                Message = message, 
                LogType = logLevel.FromLogLevel()
            };

            if (_loggerSettings == null) return;
            currentMessage.Origin = string.IsNullOrWhiteSpace(_loggerSettings.LogOrigin) ? "BatchingLogger" : _loggerSettings.LogOrigin;
            _loggerSettings?.OnLogEvent(currentMessage);
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            Log(CurrentDateTimeOffset, logLevel, eventId, state, exception, formatter);
        }
    }
}