using EonaCat.Logger.EonaCatCoreLogger;
using EonaCat.Logger.Managers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

namespace System.Runtime.CompilerServices
{
    internal static class IsExternalInit { }
}

namespace EonaCat.Logger
{
    // 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 Logger
    {
        private LogManager _logManager;
        public LoggerSettings LoggerSettings { get; }
        public bool UseLocalTime { get; set; }
        public string LogFolder { get; set; } = Path.Combine(FileLoggerOptions.DefaultPath, "logs");
        public string CurrentLogFile => _logManager.CurrentLogFile;
        public bool IsDisabled { get; set; }

        /// <summary>
        /// Logger
        /// </summary>
        /// <param name="name"></param>
        /// <param name="typesToLog"></param>
        /// <param name="useLocalTime"></param>
        /// <param name="maxFileSize"></param>
        public Logger(string name = "EonaCatLogger", List<ELogType> typesToLog = null, bool useLocalTime = false, int maxFileSize = 20_000_000)
        {
            UseLocalTime = useLocalTime;

            LoggerSettings = new LoggerSettings
            {
                Id = name,
                TypesToLog = typesToLog,
                UseLocalTime = UseLocalTime,
                FileLoggerOptions =
                {
                    LogDirectory = LogFolder,
                    FileSizeLimit = maxFileSize,
                    UseLocalTime = UseLocalTime,
                    IsEnabled = true,
                },
            };
        }

        /// <summary>
        /// Deletes the current log file if logging is enabled.
        /// </summary>
        /// <remarks>If logging is disabled, this method performs no action. Use this method to remove the
        /// active log file and start fresh logging. This operation does not affect log files from previous
        /// sessions.</remarks>
        public void DeleteCurrentLogFile()
        {
            if (IsDisabled)
            {
                return;
            }

            _logManager.DeleteCurrentLogFile();
        }

        /// <summary>
        /// Asynchronously writes a log entry with the specified message and log type, optionally outputting to the
        /// console.
        /// </summary>
        /// <remarks>If logging is disabled, the method completes without writing the log entry. The
        /// method does not throw exceptions for disabled logging states.</remarks>
        /// <param name="message">The log message to record. Cannot be null.</param>
        /// <param name="logType">The severity level of the log entry. Defaults to <see cref="ELogType.INFO"/>.</param>
        /// <param name="writeToConsole">Indicates whether the log entry should also be written to the console. Set to <see langword="true"/> to
        /// output to the console; otherwise, <see langword="false"/>.</param>
        /// <returns>A task that represents the asynchronous logging operation.</returns>
        public async Task LogAsync(string message, ELogType logType = ELogType.INFO, bool writeToConsole = true)
        {
            if (IsDisabled)
            {
                return;
            }

            InitLogger();
            await _logManager.WriteAsync(message, logType, writeToConsole).ConfigureAwait(false);
        }

        private void InitLogger()
        {
            if (_logManager == null)
            {
                // Initialize LogManager
                _logManager = new LogManager(LoggerSettings);
                _logManager.Settings.TypesToLog.Clear();
            }
        }

        /// <summary>
        /// Asynchronously logs the specified exception and an optional message, with the option to also write the log
        /// entry to the console.
        /// </summary>
        /// <remarks>Logging occurs only if error logging is enabled in the logger settings. If logging is
        /// disabled, the method completes without performing any action.</remarks>
        /// <param name="exception">The exception to log. Cannot be null.</param>
        /// <param name="message">An optional message to include with the log entry. If not specified, an empty string is used.</param>
        /// <param name="writeToConsole">Specifies whether the log entry should also be written to the console. Set to <see langword="true"/> to
        /// write to the console; otherwise, <see langword="false"/>.</param>
        /// <returns>A task that represents the asynchronous logging operation.</returns>
        public async Task LogAsync(Exception exception, string message = "", bool writeToConsole = true)
        {
            if (IsDisabled)
            {
                return;
            }

            InitLogger();   
            if (LoggerSettings.TypesToLog.Contains(ELogType.ERROR))
            {
                await _logManager.WriteAsync(exception, message, writeToConsole: writeToConsole).ConfigureAwait(false);
            }
        }
    }
}
