using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Serilog.Events;
using SlnMesnac.Config;
using System;
using System.IO;

#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* 版权所有 (c) 2024 WenJY 保留所有权利。
* CLR版本：4.0.30319.42000
* 机器名称：LAPTOP-E0N2L34V
* 命名空间：SlnMesnac.Serilog
* 唯一标识：496f8d2b-70e3-4a05-ae18-a9b0fcd06b82
*
* 创建者：WenJY
* 电子邮箱：wenjy@mesnac.com
* 创建时间：2024-03-27 21:58:35
* 版本：V1.0.0
* 描述：
*
*--------------------------------------------------------------------
* 修改人：
* 时间：
* 修改说明：
*
* 版本：V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.Serilog
{
    /// <summary>
    /// Serilog
    /// </summary>
    public static class SerilogExtensions
    {
        public static void UseSerilogExtensions(this IServiceProvider service)
        {
            #region 通过配置文件读取日志存放位置
            var appConfig = service.GetService<AppConfig>();
            var logPath = appConfig?.logPath ?? "Logs";

            // 如果是多实例，使用实例专用的日志路径
            // 注意：App类中的InstanceDataPath已经是实例专用的路径
            if (appConfig?.InstanceDataPath != null)
            {
                // 使用实例数据路径下的Logs目录
                logPath = Path.Combine(appConfig.InstanceDataPath, "Logs");
            }
            Console.WriteLine($"[DEBUG] Serilog 日志路径: {logPath}");
            Console.WriteLine($"[DEBUG] InstanceDataPath: {appConfig?.InstanceDataPath}");
            // 确保日志目录存在
            EnsureLogDirectories(logPath);

            #endregion
    //        Log.Logger = new LoggerConfiguration()
    //.MinimumLevel.Information()
    //.Enrich.WithProperty("InstanceId", appConfig?.InstanceId ?? "Unknown")
    //.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3} {InstanceId}] {Message:lj}{NewLine}{Exception}")
    //// ✅ 先用最简单的配置测试，去掉所有 Filter
    //.WriteTo.File(
    //    Path.Combine(logPath, "app.log"),
    //    rollingInterval: RollingInterval.Day,
    //    shared: true)
    //.CreateLogger();
            // 构建日志配置，包含实例ID作为上下文
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Information()

                .Enrich.WithProperty("InstanceId", appConfig?.InstanceId ?? "Unknown")
                .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3} {InstanceId}] {Message:lj}{NewLine}{Exception}")
                .WriteTo.Logger(lc => lc
                    //.Filter.ByIncludingOnly(logEvent =>
                    //    logEvent.Properties.ContainsKey("Module") &&
                    //    logEvent.Properties["Module"].ToString().Contains("Info"))

                    .WriteTo.File(
                        Path.Combine($"{logPath}/Info/", "Info.log"),
                        rollingInterval: RollingInterval.Day,
                        outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3} {InstanceId}] {Message:lj}{NewLine}{Exception}",
                                            shared: true,
                        retainedFileCountLimit: 7)) // 保留最近7天的日志文件
                .WriteTo.Logger(lc => lc
                    .Filter.ByIncludingOnly(logEvent =>
                        logEvent.Properties.ContainsKey("Module") &&
                        logEvent.Properties["Module"].ToString().Contains("Data"))
                    .WriteTo.File(
                        Path.Combine($"{logPath}/Data/", "Data.log"),
                        rollingInterval: RollingInterval.Day,
                        outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3} {InstanceId}] {Message:lj}{NewLine}{Exception}",
                                            shared: true,
                        retainedFileCountLimit: 7))
                .WriteTo.Logger(lc => lc
                    .Filter.ByIncludingOnly(logEvent =>
                        logEvent.Properties.ContainsKey("Module") &&
                        logEvent.Properties["Module"].ToString().Contains("Error"))
                    .WriteTo.File(
                        Path.Combine($"{logPath}/Error/", "Error.log"),
                        rollingInterval: RollingInterval.Day,
                        outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3} {InstanceId}] {Message:lj}{NewLine}{Exception}",
                        shared: true,
                        retainedFileCountLimit: 30)) // 错误日志保留更长时间
                .CreateLogger();
        }

        /// <summary>
        /// 确保日志目录存在
        /// </summary>
        private static void EnsureLogDirectories(string baseLogPath)
        {
            try
            {
                // 确保基础日志目录存在
                if (!Directory.Exists(baseLogPath))
                {
                    Directory.CreateDirectory(baseLogPath);
                }

                // 确保各模块日志子目录存在
                string[] subDirectories = { "Info", "Data", "Error"};
                foreach (var subDir in subDirectories)
                {
                    string dirPath = Path.Combine(baseLogPath, subDir);
                    if (!Directory.Exists(dirPath))
                    {
                        Directory.CreateDirectory(dirPath);
                    }
                }

                // 创建当前实例的启动日志文件
                //string startupLog = Path.Combine(baseLogPath, "Startup.log");
                //File.AppendAllText(startupLog,
                //    $"=== Instance Startup ===\r\n" +
                //    $"Time: {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}\r\n" +
                //    $"Base Log Path: {baseLogPath}\r\n" +
                //    $"=================================================================\r\n");
            }
            catch (Exception ex)
            {
                // 如果无法创建目录，使用临时目录
                Console.WriteLine($"无法创建日志目录 {baseLogPath}: {ex.Message}");

                // 尝试使用临时目录作为后备
                string tempLogPath = Path.Combine(Path.GetTempPath(), "SlnMesnac", "Logs");
                if (!Directory.Exists(tempLogPath))
                {
                    Directory.CreateDirectory(tempLogPath);
                }
            }
        }
    }
}
