using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json.Serialization;

namespace JiShe.CollectBus.PluginFileWatcher
{
    /// <summary>
    /// 表示一个文件系统事件的数据模型，用于序列化和存储
    /// </summary>
    public class FileEvent
    {
        /// <summary>
        /// 事件唯一标识
        /// </summary>
        public Guid Id { get; set; } = Guid.NewGuid();

        /// <summary>
        /// 事件发生时间
        /// </summary>
        public DateTime Timestamp { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 事件类型
        /// </summary>
        public FileEventType EventType { get; set; }

        /// <summary>
        /// 文件完整路径
        /// </summary>
        public string FullPath { get; set; }

        /// <summary>
        /// 文件名
        /// </summary>
        public string FileName { get; set; }

        /// <summary>
        /// 文件所在目录
        /// </summary>
        public string Directory { get; set; }

        /// <summary>
        /// 文件扩展名
        /// </summary>
        public string Extension { get; set; }

        /// <summary>
        /// 重命名前的旧文件名（仅在重命名事件中有效）
        /// </summary>
        public string OldFileName { get; set; }

        /// <summary>
        /// 重命名前的旧路径（仅在重命名事件中有效）
        /// </summary>
        public string OldFullPath { get; set; }

        /// <summary>
        /// 文件大小（字节），如果可获取
        /// </summary>
        public long? FileSize { get; set; }

        /// <summary>
        /// 自定义属性，可用于存储其他元数据
        /// </summary>
        public Dictionary<string, string> Metadata { get; set; } = new Dictionary<string, string>();

        /// <summary>
        /// 从FileSystemEventArgs创建FileEvent
        /// </summary>
        /// <param name="e">FileSystemEventArgs参数</param>
        /// <returns>FileEvent对象</returns>
        public static FileEvent FromFileSystemEventArgs(FileSystemEventArgs e)
        {
            var fileEvent = new FileEvent
            {
                EventType = GetEventType(e.ChangeType),
                FullPath = e.FullPath,
                FileName = e.Name ?? Path.GetFileName(e.FullPath),
                Directory = Path.GetDirectoryName(e.FullPath),
                Extension = Path.GetExtension(e.FullPath)
            };

            // 如果是重命名事件，添加旧文件名信息
            if (e is RenamedEventArgs renamedEvent)
            {
                fileEvent.OldFileName = Path.GetFileName(renamedEvent.OldFullPath);
                fileEvent.OldFullPath = renamedEvent.OldFullPath;
            }

            // 尝试获取文件大小（如果文件存在且可访问）
            try
            {
                if (File.Exists(e.FullPath) && e.ChangeType != WatcherChangeTypes.Deleted)
                {
                    var fileInfo = new FileInfo(e.FullPath);
                    fileEvent.FileSize = fileInfo.Length;

                    // 添加一些额外的元数据
                    fileEvent.Metadata["CreationTime"] = fileInfo.CreationTime.ToString("o");
                    fileEvent.Metadata["LastWriteTime"] = fileInfo.LastWriteTime.ToString("o");
                    fileEvent.Metadata["IsReadOnly"] = fileInfo.IsReadOnly.ToString();
                }
            }
            catch
            {
                // 忽略任何获取文件信息时的错误
            }

            return fileEvent;
        }

        /// <summary>
        /// 将WatcherChangeTypes转换为FileEventType
        /// </summary>
        /// <param name="changeType">WatcherChangeTypes枚举值</param>
        /// <returns>对应的FileEventType</returns>
        public static FileEventType GetEventType(WatcherChangeTypes changeType)
        {
            return changeType switch
            {
                WatcherChangeTypes.Created => FileEventType.Created,
                WatcherChangeTypes.Deleted => FileEventType.Deleted,
                WatcherChangeTypes.Changed => FileEventType.Modified,
                WatcherChangeTypes.Renamed => FileEventType.Renamed,
                _ => FileEventType.Other
            };
        }
    }

    /// <summary>
    /// 文件事件类型
    /// </summary>
    public enum FileEventType
    {
        /// <summary>
        /// 文件被创建
        /// </summary>
        Created,

        /// <summary>
        /// 文件被修改
        /// </summary>
        Modified,

        /// <summary>
        /// 文件被删除
        /// </summary>
        Deleted,

        /// <summary>
        /// 文件被重命名
        /// </summary>
        Renamed,

        /// <summary>
        /// 其他类型事件
        /// </summary>
        Other
    }

    /// <summary>
    /// 表示一个事件日志文件
    /// </summary>
    public class EventLogFile
    {
        /// <summary>
        /// 日志文件创建时间
        /// </summary>
        public DateTime CreatedTime { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 日志文件包含的事件列表
        /// </summary>
        public List<FileEvent> Events { get; set; } = new List<FileEvent>();
    }

    /// <summary>
    /// 事件查询结果
    /// </summary>
    public class EventQueryResult
    {
        /// <summary>
        /// 查询到的事件列表
        /// </summary>
        public List<FileEvent> Events { get; set; } = new List<FileEvent>();

        /// <summary>
        /// 匹配的事件总数
        /// </summary>
        public int TotalCount { get; set; }

        /// <summary>
        /// 查询是否有更多结果
        /// </summary>
        public bool HasMore { get; set; }

        /// <summary>
        /// 查询时间范围的开始时间
        /// </summary>
        public DateTime StartTime { get; set; }

        /// <summary>
        /// 查询时间范围的结束时间
        /// </summary>
        public DateTime EndTime { get; set; }
    }

    /// <summary>
    /// 事件查询参数
    /// </summary>
    public class EventQueryParams
    {
        /// <summary>
        /// 查询开始时间
        /// </summary>
        public DateTime? StartTime { get; set; }

        /// <summary>
        /// 查询结束时间
        /// </summary>
        public DateTime? EndTime { get; set; }

        /// <summary>
        /// 事件类型过滤
        /// </summary>
        public FileEventType? EventType { get; set; }

        /// <summary>
        /// 文件路径过滤（支持包含关系）
        /// </summary>
        public string PathFilter { get; set; }

        /// <summary>
        /// 文件扩展名过滤
        /// </summary>
        public string ExtensionFilter { get; set; }

        /// <summary>
        /// 分页大小
        /// </summary>
        public int PageSize { get; set; } = 100;

        /// <summary>
        /// 分页索引（从0开始）
        /// </summary>
        public int PageIndex { get; set; } = 0;

        /// <summary>
        /// 排序方向，true为升序，false为降序
        /// </summary>
        public bool AscendingOrder { get; set; } = false;
    }
}