using System;
using System.IO;
using System.Text;

namespace StandardScene.Fass2Simulator
{
    public static class Fass2SimFileLogger
    {
        private static readonly object SyncRoot = new object();
        private static StreamWriter _writer;
        private static bool _enabled = true;
        private static string _logDirectory;

        public static string CurrentFilePath { get; private set; }

        public static void Configure(Fass2SimConfig config)
        {
            _enabled = config == null || config.EnableFileLog;
            _logDirectory = ResolveLogDirectory(config?.LogDirectory);
        }

        public static void BeginSession(Fass2SimConfig config)
        {
            if (config == null || !config.EnableFileLog)
            {
                return;
            }

            lock (SyncRoot)
            {
                CloseWriter();
                Directory.CreateDirectory(_logDirectory);
                var fileName = $"car{config.VehicleCode}_{DateTime.Now:yyyyMMdd_HHmmss}.log";
                CurrentFilePath = Path.Combine(_logDirectory, fileName);
                _writer = new StreamWriter(CurrentFilePath, false, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false))
                {
                    AutoFlush = true
                };

                WriteDirect("===== FASS2 车体模拟器会话开始 =====");
                WriteDirect($"时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                WriteDirect($"车号: {config.VehicleCode}");
                WriteDirect($"车体监听: {config.VehicleListenAddress}:{config.VehicleListenPort}");
                WriteDirect($"调度目标: {config.SchedulerHost}:{config.SchedulerListenPort}");
                WriteDirect($"上报周期: {config.ReportIntervalMs} ms");
                WriteDirect($"日志文件: {CurrentFilePath}");
                WriteDirect("====================================");
            }
        }

        public static void Write(string message)
        {
            if (!_enabled || string.IsNullOrEmpty(message))
            {
                return;
            }

            lock (SyncRoot)
            {
                if (_writer == null)
                {
                    EnsureDefaultWriter();
                }

                if (_writer == null)
                {
                    return;
                }

                _writer.WriteLine(message);
            }
        }

        public static void Shutdown()
        {
            lock (SyncRoot)
            {
                if (_writer != null)
                {
                    WriteDirect($"===== 会话结束 {DateTime.Now:yyyy-MM-dd HH:mm:ss} =====");
                }

                CloseWriter();
            }
        }

        public static string GetLogDirectory()
        {
            return _logDirectory ?? ResolveLogDirectory("logs");
        }

        private static void EnsureDefaultWriter()
        {
            if (!_enabled)
            {
                return;
            }

            Directory.CreateDirectory(_logDirectory);
            var fileName = $"app_{DateTime.Now:yyyyMMdd}.log";
            CurrentFilePath = Path.Combine(_logDirectory, fileName);
            _writer = new StreamWriter(CurrentFilePath, true, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false))
            {
                AutoFlush = true
            };
            WriteDirect($"[{DateTime.Now:HH:mm:ss}] 文件日志已启用: {CurrentFilePath}");
        }

        private static void WriteDirect(string message)
        {
            _writer?.WriteLine(message);
        }

        private static void CloseWriter()
        {
            try
            {
                _writer?.Flush();
                _writer?.Dispose();
            }
            catch
            {
            }

            _writer = null;
        }

        private static string ResolveLogDirectory(string configuredPath)
        {
            if (string.IsNullOrWhiteSpace(configuredPath))
            {
                return Path.Combine(AppContext.BaseDirectory, "logs");
            }

            return Path.IsPathRooted(configuredPath)
                ? configuredPath
                : Path.Combine(AppContext.BaseDirectory, configuredPath);
        }
    }
}
