using System;
using System.Data.SQLite;
using System.IO;

namespace NavisworksTransport.Core.Database
{
    /// <summary>
    /// 简单数据库备份管理器
    /// 直接备份整个 SQLite 数据库文件，100% 保留所有数据
    /// </summary>
    public class BackupManager
    {
        private readonly PathDatabase _database;
        private readonly string _dbPath;

        public BackupManager(PathDatabase database)
        {
            _database = database ?? throw new ArgumentNullException(nameof(database));
            _dbPath = GetDatabaseFilePath(database);
        }

        /// <summary>
        /// 获取数据库文件路径
        /// </summary>
        private string GetDatabaseFilePath(PathDatabase database)
        {
            // 通过反射获取私有字段 _dbPath
            var field = typeof(PathDatabase).GetField("_dbPath", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            return field?.GetValue(database) as string ?? "";
        }

        /// <summary>
        /// 获取数据库版本号
        /// </summary>
        public int GetDatabaseVersion()
        {
            try
            {
                using (var cmd = new SQLiteCommand("PRAGMA user_version", _database.Connection))
                {
                    return Convert.ToInt32(cmd.ExecuteScalar());
                }
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 格式化版本号显示
        /// </summary>
        public static string FormatVersion(int version)
        {
            if (version == 0) return "未知版本";
            int major = version / 10000;
            int minor = (version % 10000) / 100;
            int patch = version % 100;
            return $"v{major}.{minor}.{patch}";
        }

        /// <summary>
        /// 检查两个版本是否兼容（主版本必须相同）
        /// </summary>
        public static bool IsVersionCompatible(int sourceVersion, int targetVersion)
        {
            if (sourceVersion == 0 || targetVersion == 0) return false;
            int sourceMajor = sourceVersion / 10000;
            int targetMajor = targetVersion / 10000;
            return sourceMajor == targetMajor;
        }

        /// <summary>
        /// 备份数据库（直接复制文件）
        /// </summary>
        public string BackupDatabase(string exportDirectory = null)
        {
            try
            {
                if (string.IsNullOrEmpty(_dbPath) || !File.Exists(_dbPath))
                {
                    throw new InvalidOperationException("数据库文件不存在");
                }

                // 确保目录存在
                if (string.IsNullOrEmpty(exportDirectory))
                {
                    exportDirectory = Path.Combine(
                        Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                        "NavisworksTransport", "Backups");
                }

                if (!Directory.Exists(exportDirectory))
                    Directory.CreateDirectory(exportDirectory);

                // 获取当前版本号
                int version = GetDatabaseVersion();
                string versionStr = FormatVersion(version).Replace(".", "_");

                // 生成备份文件名（包含版本号）
                string fileName = $"NavisworksTransport_{versionStr}_{DateTime.Now:yyyyMMdd_HHmmss}.db";
                string backupPath = Path.Combine(exportDirectory, fileName);

                // 关闭数据库连接以释放文件锁
                _database.Connection.Close();

                try
                {
                    // 复制数据库文件
                    File.Copy(_dbPath, backupPath, true);
                }
                finally
                {
                    // 重新打开连接
                    _database.Connection.Open();
                }

                LogManager.Info($"数据库备份完成: {backupPath}");
                return backupPath;
            }
            catch (Exception ex)
            {
                LogManager.Error($"数据库备份失败: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 获取指定数据库文件的版本号
        /// </summary>
        private int GetBackupFileVersion(string backupFilePath)
        {
            try
            {
                using (var connection = new SQLiteConnection($"Data Source={backupFilePath};Version=3;"))
                {
                    connection.Open();
                    using (var cmd = new SQLiteCommand("PRAGMA user_version", connection))
                    {
                        return Convert.ToInt32(cmd.ExecuteScalar());
                    }
                }
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 恢复数据库（直接替换文件）
        /// </summary>
        public void RestoreDatabase(string backupFilePath)
        {
            try
            {
                if (!File.Exists(backupFilePath))
                {
                    throw new FileNotFoundException("备份文件不存在", backupFilePath);
                }

                if (string.IsNullOrEmpty(_dbPath))
                {
                    throw new InvalidOperationException("数据库路径未知");
                }

                // 获取版本信息
                int currentVersion = GetDatabaseVersion();
                int backupVersion = GetBackupFileVersion(backupFilePath);

                LogManager.Info($"数据库版本检查: 当前={FormatVersion(currentVersion)}, 备份={FormatVersion(backupVersion)}");

                // 版本兼容性检查
                if (!IsVersionCompatible(backupVersion, currentVersion))
                {
                    throw new InvalidOperationException(
                        $"版本不兼容!\n\n" +
                        $"备份版本: {FormatVersion(backupVersion)}\n" +
                        $"当前版本: {FormatVersion(currentVersion)}\n\n" +
                        $"主版本号必须相同才能恢复。\n" +
                        $"请使用相同版本的插件进行恢复，或联系管理员进行数据库升级。");
                }

                // 关闭数据库连接
                _database.Connection.Close();

                try
                {
                    // 备份当前数据库（以防万一）
                    if (File.Exists(_dbPath))
                    {
                        string safetyBackup = _dbPath + $".backup_{DateTime.Now:yyyyMMdd_HHmmss}";
                        File.Copy(_dbPath, safetyBackup, true);
                        LogManager.Info($"已创建安全备份: {safetyBackup}");
                    }

                    // 替换数据库文件
                    File.Copy(backupFilePath, _dbPath, true);
                }
                finally
                {
                    // 重新打开连接
                    try { _database.Connection.Open(); }
                    catch (Exception ex)
                    {
                        LogManager.Error($"[数据库恢复] 重新打开连接失败: {ex.Message}");
                        throw;
                    }
                }

                LogManager.Info($"数据库恢复完成: {backupFilePath}");
            }
            catch (Exception ex)
            {
                LogManager.Error($"数据库恢复失败: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 获取数据库信息
        /// </summary>
        public DatabaseInfo GetDatabaseInfo()
        {
            try
            {
                var info = new DatabaseInfo
                {
                    FilePath = _dbPath,
                    FileSize = File.Exists(_dbPath) ? new FileInfo(_dbPath).Length : 0,
                    Version = GetDatabaseVersion()
                };

                // 获取表行数
                info.PathRoutesCount = GetTableCount("PathRoutes");
                info.PathPointsCount = GetTableCount("PathPoints");
                info.PathEdgesCount = GetTableCount("PathEdges");
                info.DetectionRecordsCount = GetTableCount("CollisionDetectionRecords");
                info.ScreenshotsCount = GetTableCount("CollisionReportScreenshots");

                return info;
            }
            catch (Exception ex)
            {
                LogManager.Error($"获取数据库信息失败: {ex.Message}");
                return new DatabaseInfo();
            }
        }

        private int GetTableCount(string tableName)
        {
            try
            {
                var sql = $"SELECT COUNT(*) FROM {tableName}";
                using (var cmd = new SQLiteCommand(sql, _database.Connection))
                {
                    return Convert.ToInt32(cmd.ExecuteScalar());
                }
            }
            catch
            {
                return 0;
            }
        }
    }

    public class DatabaseInfo
    {
        public string FilePath { get; set; }
        public long FileSize { get; set; }
        public int Version { get; set; }
        public int PathRoutesCount { get; set; }
        public int PathPointsCount { get; set; }
        public int PathEdgesCount { get; set; }
        public int DetectionRecordsCount { get; set; }
        public int ScreenshotsCount { get; set; }

        public string FileSizeFormatted => $"{FileSize / 1024} KB";
        public string VersionFormatted => BackupManager.FormatVersion(Version);
    }
}
