using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Extensions.Logging;
using ILogger = Microsoft.Extensions.Logging.ILogger;

namespace JiShe.CollectBus.PluginFileWatcher
{
    /// <summary>
    /// 数据库操作工具类，用于命令行测试数据库功能
    /// </summary>
    public class DbUtility
    {
        private readonly EventDatabaseManager _dbManager;
        private readonly ILogger _logger;
        private readonly FileMonitorConfig _config;

        /// <summary>
        /// 初始化数据库工具类
        /// </summary>
        /// <param name="configPath">配置文件路径</param>
        public DbUtility(string configPath = "appsettings.json")
        {
            // 从配置文件加载配置
            var configuration = new ConfigurationBuilder()
                .AddJsonFile(configPath, optional: false, reloadOnChange: true)
                .Build();

            // 初始化日志
            var serilogLogger = new LoggerConfiguration()
                .ReadFrom.Configuration(configuration)
                .CreateLogger();

            // 将Serilog适配为Microsoft.Extensions.Logging.ILogger
            _logger = new SerilogLoggerFactory(serilogLogger).CreateLogger("DbUtility");

            // 创建配置对象
            _config = new FileMonitorConfig();
            configuration.GetSection("FileMonitor").Bind(_config);

            // 确保SQLite存储已启用
            _config.EventStorage.EnableEventStorage = true;
            _config.EventStorage.StorageType = "SQLite";

            // 创建数据库管理器
            _dbManager = new EventDatabaseManager(_config, _logger);
        }

        /// <summary>
        /// 执行数据库维护操作
        /// </summary>
        /// <param name="args">命令行参数</param>
        public async Task ExecuteAsync(string[] args)
        {
            if (args.Length == 0)
            {
                PrintUsage();
                return;
            }

            string command = args[0].ToLower();

            switch (command)
            {
                case "stats":
                    await ShowStatisticsAsync();
                    break;

                case "cleanup":
                    int days = args.Length > 1 && int.TryParse(args[1], out int d) ? d : _config.EventStorage.DataRetentionDays;
                    await _dbManager.CleanupOldDataAsync(days);
                    Console.WriteLine($"已清理 {days} 天前的旧数据");
                    break;

                case "query":
                    await QueryEventsAsync(args);
                    break;

                case "test":
                    await GenerateTestDataAsync(args);
                    break;

                default:
                    Console.WriteLine($"未知命令: {command}");
                    PrintUsage();
                    break;
            }
        }

        /// <summary>
        /// 显示帮助信息
        /// </summary>
        private void PrintUsage()
        {
            Console.WriteLine("数据库工具使用方法:");
            Console.WriteLine("  stats                 - 显示数据库统计信息");
            Console.WriteLine("  cleanup [days]        - 清理指定天数之前的数据（默认使用配置值）");
            Console.WriteLine("  query [limit]         - 查询最近的事件（默认10条）");
            Console.WriteLine("  query type:X ext:Y    - 按类型和扩展名查询事件");
            Console.WriteLine("  test [count]          - 生成测试数据（默认100条）");
        }

        /// <summary>
        /// 显示数据库统计信息
        /// </summary>
        private async Task ShowStatisticsAsync()
        {
            try
            {
                var stats = await _dbManager.GetDatabaseStatsAsync();

                Console.WriteLine("数据库统计信息:");
                Console.WriteLine($"事件总数: {stats.TotalEvents}");
                Console.WriteLine($"最早事件时间: {stats.OldestEventTime?.ToLocalTime()}");
                Console.WriteLine($"最新事件时间: {stats.NewestEventTime?.ToLocalTime()}");

                Console.WriteLine("\n事件类型分布:");
                if (stats.EventTypeCounts != null)
                {
                    foreach (var item in stats.EventTypeCounts)
                    {
                        Console.WriteLine($"  {item.Key}: {item.Value}");
                    }
                }

                Console.WriteLine("\n扩展名分布 (Top 10):");
                if (stats.TopExtensions != null)
                {
                    foreach (var item in stats.TopExtensions)
                    {
                        Console.WriteLine($"  {item.Key}: {item.Value}");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取统计信息出错: {ex.Message}");
                _logger.LogError(ex, "获取数据库统计信息时发生错误");
            }
        }

        /// <summary>
        /// 查询事件
        /// </summary>
        private async Task QueryEventsAsync(string[] args)
        {
            try
            {
                var queryParams = new EventQueryParams
                {
                    PageSize = 10,
                    PageIndex = 0
                };

                // 解析查询参数
                if (args.Length > 1)
                {
                    foreach (var arg in args.Skip(1))
                    {
                        if (int.TryParse(arg, out int limit))
                        {
                            queryParams.PageSize = limit;
                        }
                        else if (arg.StartsWith("type:", StringComparison.OrdinalIgnoreCase))
                        {
                            string typeValue = arg.Substring(5);
                            if (Enum.TryParse<FileEventType>(typeValue, true, out var eventType))
                            {
                                queryParams.EventType = eventType;
                            }
                        }
                        else if (arg.StartsWith("ext:", StringComparison.OrdinalIgnoreCase))
                        {
                            queryParams.ExtensionFilter = arg.Substring(4);
                            if (!queryParams.ExtensionFilter.StartsWith("."))
                            {
                                queryParams.ExtensionFilter = "." + queryParams.ExtensionFilter;
                            }
                        }
                        else if (arg.StartsWith("path:", StringComparison.OrdinalIgnoreCase))
                        {
                            queryParams.PathFilter = arg.Substring(5);
                        }
                    }
                }

                // 执行查询
                var result = await _dbManager.QueryEventsAsync(queryParams);

                Console.WriteLine($"查询结果 (总数: {result.TotalCount}):");
                foreach (var evt in result.Events)
                {
                    string typeStr = evt.EventType.ToString();
                    string timestamp = evt.Timestamp.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
                    Console.WriteLine($"[{timestamp}] {typeStr,-10} {evt.FileName} ({evt.Extension})");
                }

                if (result.HasMore)
                {
                    Console.WriteLine($"... 还有更多结果，共 {result.TotalCount} 条");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"查询事件出错: {ex.Message}");
                _logger.LogError(ex, "查询事件时发生错误");
            }
        }

        /// <summary>
        /// 生成测试数据
        /// </summary>
        private async Task GenerateTestDataAsync(string[] args)
        {
            try
            {
                int count = args.Length > 1 && int.TryParse(args[1], out int c) ? c : 100;

                var events = new List<FileEvent>();
                var rnd = new Random();
                string[] extensions = { ".dll", ".exe", ".txt", ".cs", ".xml", ".json", ".png", ".jpg" };
                string[] directories = { "C:\\Temp", "D:\\Work", "C:\\Program Files", "D:\\Projects", "E:\\Data" };

                DateTime startTime = DateTime.Now.AddHours(-24);

                for (int i = 0; i < count; i++)
                {
                    var eventType = (FileEventType)rnd.Next(0, 5);
                    var ext = extensions[rnd.Next(extensions.Length)];
                    var dir = directories[rnd.Next(directories.Length)];
                    var fileName = $"TestFile_{i:D5}{ext}";
                    var timestamp = startTime.AddMinutes(i);

                    var fileEvent = new FileEvent
                    {
                        Id = Guid.NewGuid(),
                        Timestamp = timestamp,
                        EventType = eventType,
                        FullPath = $"{dir}\\{fileName}",
                        FileName = fileName,
                        Directory = dir,
                        Extension = ext,
                        FileSize = rnd.Next(1024, 1024 * 1024)
                    };

                    // 如果是重命名事件，添加旧文件名
                    if (eventType == FileEventType.Renamed)
                    {
                        fileEvent.OldFileName = $"OldFile_{i:D5}{ext}";
                        fileEvent.OldFullPath = $"{dir}\\{fileEvent.OldFileName}";
                    }

                    // 添加一些元数据
                    fileEvent.Metadata["CreationTime"] = timestamp.AddMinutes(-rnd.Next(1, 60)).ToString("o");
                    fileEvent.Metadata["LastWriteTime"] = timestamp.ToString("o");
                    fileEvent.Metadata["IsReadOnly"] = (rnd.Next(10) < 2).ToString();
                    fileEvent.Metadata["TestData"] = $"测试数据 {i}";

                    events.Add(fileEvent);
                }

                Console.WriteLine($"正在生成 {count} 条测试数据...");
                await _dbManager.SaveEventsAsync(events);
                Console.WriteLine("测试数据生成完成！");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"生成测试数据出错: {ex.Message}");
                _logger.LogError(ex, "生成测试数据时发生错误");
            }
        }
    }
}