using System;
using System.IO;

namespace NavisworksTransport
{
    /// <summary>
    /// 日志级别枚举
    /// </summary>
    public enum LogLevel
    {
        Debug = 0,
        Info = 1,
        Warning = 2,
        Error = 3
    }

    /// <summary>
    /// 统一日志管理器
    /// 提供全局日志记录功能
    /// </summary>
    public static class LogManager
    {
        // 多实例支持：副实例通过环境变量 TRANSPORTPLUGIN_TEST_PORT 隔离日志文件（debug-{port}.log），
        // 避免多 Navisworks 进程写同一 debug.log 冲突/互清（静态构造 ClearLog 会清空主实例日志）。
        private static readonly string _logFilePath = ResolveLogFilePath();

        private static string ResolveLogFilePath()
        {
            string logDirectory = Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
                "Autodesk", "Navisworks Manage 2026", "plugins", "TransportPlugin", "logs");

            string portRaw = Environment.GetEnvironmentVariable("TRANSPORTPLUGIN_TEST_PORT");
            if (!string.IsNullOrWhiteSpace(portRaw) && int.TryParse(portRaw, out int port) && port > 0)
            {
                // 副实例：日志隔离到 debug-{port}.log（主实例端口 18777 仍用 debug.log）
                if (port != 18777)
                {
                    return Path.Combine(logDirectory, $"debug-{port}.log");
                }
            }

            return Path.Combine(logDirectory, "debug.log");
        }

        private static readonly object _lockObject = new object();

        /// <summary>
        /// 当前日志级别，默认为 Info
        /// </summary>
        private static LogLevel _currentLevel = LogLevel.Info;

        /// <summary>
        /// 静态构造函数，确保日志目录存在并清空旧日志
        /// </summary>
        static LogManager()
        {
            try
            {
                // 确保日志目录存在
                var logDirectory = Path.GetDirectoryName(_logFilePath);
                if (!Directory.Exists(logDirectory))
                {
                    Directory.CreateDirectory(logDirectory);
                }
                
                // 启动时清空日志文件
                ClearLog();
            }
            catch
            {
                // 忽略初始化错误
            }
        }

        /// <summary>
        /// 日志文件路径
        /// </summary>
        public static string LogFilePath => _logFilePath;

        /// <summary>
        /// 设置日志级别
        /// </summary>
        public static void SetLogLevel(LogLevel level)
        {
            _currentLevel = level;
            Info($"日志级别已设置为: {level}");
        }

        /// <summary>
        /// 获取当前日志级别
        /// </summary>
        public static LogLevel GetLogLevel()
        {
            return _currentLevel;
        }

        /// <summary>
        /// 检查是否应该记录指定级别的日志
        /// </summary>
        private static bool ShouldLog(LogLevel level)
        {
            return level >= _currentLevel;
        }

        /// <summary>
        /// 清空调试日志
        /// </summary>
        public static void ClearLog()
        {
            try
            {
                lock (_lockObject)
                {
                    if (File.Exists(_logFilePath))
                    {
                        // 如果文件太大，分两步删除：先清空内容，再删除文件
                        var fileInfo = new FileInfo(_logFilePath);
                        if (fileInfo.Length > 10 * 1024 * 1024) // 如果大于10MB
                        {
                            // 先创建一个空文件覆盖原文件
                            File.WriteAllText(_logFilePath, string.Empty);
                            System.Threading.Thread.Sleep(100); // 短暂等待
                        }
                        File.Delete(_logFilePath);
                    }
                }
            }
            catch
            {
                // 忽略文件删除错误，但尝试创建一个新的空文件
                try
                {
                    File.WriteAllText(_logFilePath, $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] 日志已重置\n");
                }
                catch
                {
                    // 完全忽略错误
                }
            }
        }

        /// <summary>
        /// 写入调试日志（同时输出到Debug和文件）- 私有方法，强制使用带级别的方法
        /// </summary>
        /// <param name="message">日志消息</param>
        private static void WriteLog(string message)
        {
            var logMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] {message}";
            System.Diagnostics.Debug.WriteLine(logMessage);
            
            try
            {
                lock (_lockObject)
                {
                    File.AppendAllText(_logFilePath, logMessage + Environment.NewLine);
                }
            }
            catch
            {
                // 忽略文件写入错误
            }
        }

        /// <summary>
        /// 写入信息级别日志
        /// </summary>
        /// <param name="message">日志消息</param>
        public static void Info(string message)
        {
            if (ShouldLog(LogLevel.Info))
            {
                WriteLog($"[INFO] {message}");
            }
        }

        /// <summary>
        /// 写入警告级别日志
        /// </summary>
        /// <param name="message">日志消息</param>
        public static void Warning(string message)
        {
            if (ShouldLog(LogLevel.Warning))
            {
                WriteLog($"[WARN] {message}");
            }
        }

        /// <summary>
        /// 写入错误级别日志
        /// </summary>
        /// <param name="message">日志消息</param>
        public static void Error(string message)
        {
            if (ShouldLog(LogLevel.Error))
            {
                WriteLog($"[ERROR] {message}");
            }
        }

        /// <summary>
        /// 写入错误级别日志（包含异常信息）
        /// </summary>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常对象</param>
        public static void Error(string message, Exception exception)
        {
            if (ShouldLog(LogLevel.Error))
            {
                WriteLog($"[ERROR] {message}: {exception.Message}");
                WriteLog($"[ERROR] 堆栈跟踪: {exception.StackTrace}");
            }
        }

        /// <summary>
        /// 写入调试级别日志
        /// </summary>
        /// <param name="message">日志消息</param>
        public static void Debug(string message)
        {
            if (ShouldLog(LogLevel.Debug))
            {
                WriteLog($"[DEBUG] {message}");
            }
        }

        /// <summary>
        /// 写入会话分隔符，标记新的操作会话开始
        /// </summary>
        public static void WriteSessionSeparator()
        {
            var separator = new string('=', 60);
            WriteLog($"{separator}");
            WriteLog($"[SESSION] 新会话开始 - {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
            WriteLog($"{separator}");
        }
    }
} 