using DHSoftware.Models;
using SqlSugar;

namespace DHSoftware.Utils
{
    public static class DatabaseUtil
    {
        private static readonly string DatabasePath = Path.Combine(
            Application.StartupPath,
            "db",
            "RBACSystem.sqlite"
        );

        public static void InitializeDatabase()
        {
            EnsureDirectoryExists();
            using (var db = GetDatabase())
            {
                // 检查初始化状态(通过检查是否存在系统表)
                bool isInitialized = db.DbMaintenance.IsAnyTable("RolePermission");

                if (!isInitialized)
                {
                    // 创建所有表
                    db.CodeFirst.InitTables(
                        typeof(User),
                        typeof(Role),
                        typeof(Permission),
                        typeof(UserRole),
                        typeof(RolePermission)
                    );

                    // 初始化基础数据
                    InitializeSeedData(db);
                }
            }
        }

        public static SqlSugarClient GetDatabase()
        {
            return new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = $"Data Source={DatabasePath};",
                DbType = DbType.Sqlite,
                IsAutoCloseConnection = true,
                InitKeyType = InitKeyType.Attribute
            });
        }

        private static void EnsureDirectoryExists()
        {
            var directory = Path.GetDirectoryName(DatabasePath);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }
        }

        private static void InitializeSeedData(SqlSugarClient db)
        {
            // 初始化角色
            var adminRole = GetOrCreateRole(db, "admin", "系统管理员");
            var userRole = GetOrCreateRole(db, "user", "普通用户");

            // 初始化权限
            var permissions = new List<Permission>
        {
            new Permission { Code = "system:access", Name = "访问系统" },
            new Permission { Code = "user:view", Name = "查看用户" },
            new Permission { Code = "user:edit", Name = "管理用户" },
            new Permission { Code = "role:manage", Name = "角色管理" },
            new Permission { Code = "system:config", Name = "配置权限" },
            new Permission { Code = "system:loadscheme", Name = "加载方案" },
            new Permission { Code = "system:addscheme", Name = "新增方案" },
            new Permission { Code = "system:deletescheme", Name = "删除方案" }
        };
            InitializePermissions(db, permissions);

            // 分配权限给管理员角色
            AssignPermissionsToRole(db, adminRole.Id, permissions.Select(p => p.Code).ToList());

            // 创建默认管理员
            CreateAdminUser(db);
        }

        private static Role GetOrCreateRole(SqlSugarClient db, string roleName, string description)
        {
            var role = db.Queryable<Role>()
                .First(r => r.RoleName == roleName);

            if (role == null)
            {
                role = new Role
                {
                    RoleName = roleName,
                    Description = description
                };
                role.Id = db.Insertable(role).ExecuteReturnIdentity();
            }
            return role;
        }

        private static void InitializePermissions(SqlSugarClient db, List<Permission> permissions)
        {
            foreach (var p in permissions)
            {
                if (!db.Queryable<Permission>().Any(x => x.Code == p.Code))
                {
                    db.Insertable(p).ExecuteCommand();
                }
            }
        }

        private static void AssignPermissionsToRole(SqlSugarClient db, int roleId, List<string> permissionCodes)
        {
            var existing = db.Queryable<RolePermission>()
                .Where(rp => rp.RoleId == roleId)
                .Select(rp => rp.PermissionCode)
                .ToList();

            foreach (var code in permissionCodes.Except(existing))
            {
                db.Insertable(new RolePermission
                {
                    RoleId = roleId,
                    PermissionCode = code
                }).ExecuteCommand();
            }
        }

        private static void CreateAdminUser(SqlSugarClient db)
        {
            if (!db.Queryable<User>().Any(u => u.UserName == "admin"))
            {
                var admin = new User
                {
                    UserName = "admin",
                    Password = HashHelper.MD5Encrypt("admin123"),
                    LastLoginTime = null
                };
                admin.Id = db.Insertable(admin).ExecuteReturnIdentity();

                db.Insertable(new UserRole
                {
                    UserId = admin.Id,
                    RoleId = db.Queryable<Role>().First(r => r.RoleName == "admin").Id
                }).ExecuteCommand();
            }
        }
    }
}