using Microsoft.EntityFrameworkCore;
using HoneyBox.Admin.Entities;

namespace HoneyBox.Admin.Data;

/// <summary>
/// 后台管理系统数据库上下文
/// </summary>
public class AdminDbContext : DbContext
{
    public AdminDbContext(DbContextOptions<AdminDbContext> options) : base(options)
    {
    }

    #region DbSet Properties

    /// <summary>
    /// 管理员
    /// </summary>
    public DbSet<AdminUser> AdminUsers { get; set; } = null!;

    /// <summary>
    /// 角色
    /// </summary>
    public DbSet<Role> Roles { get; set; } = null!;

    /// <summary>
    /// 菜单
    /// </summary>
    public DbSet<Menu> Menus { get; set; } = null!;

    /// <summary>
    /// 部门
    /// </summary>
    public DbSet<Department> Departments { get; set; } = null!;

    /// <summary>
    /// 权限
    /// </summary>
    public DbSet<Permission> Permissions { get; set; } = null!;

    /// <summary>
    /// 管理员-角色关联
    /// </summary>
    public DbSet<AdminUserRole> AdminUserRoles { get; set; } = null!;

    /// <summary>
    /// 管理员-菜单关联（用户专属菜单）
    /// </summary>
    public DbSet<AdminUserMenu> AdminUserMenus { get; set; } = null!;

    /// <summary>
    /// 角色-菜单关联
    /// </summary>
    public DbSet<RoleMenu> RoleMenus { get; set; } = null!;

    /// <summary>
    /// 角色-权限关联
    /// </summary>
    public DbSet<RolePermission> RolePermissions { get; set; } = null!;

    /// <summary>
    /// 部门-菜单关联
    /// </summary>
    public DbSet<DepartmentMenu> DepartmentMenus { get; set; } = null!;

    /// <summary>
    /// 操作日志
    /// </summary>
    public DbSet<OperationLog> OperationLogs { get; set; } = null!;

    /// <summary>
    /// 刷新令牌
    /// </summary>
    public DbSet<RefreshToken> RefreshTokens { get; set; } = null!;

    #endregion

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // ========== 主实体唯一索引配置 ==========

        // AdminUser - 用户名唯一
        modelBuilder.Entity<AdminUser>()
            .HasIndex(e => e.Username)
            .IsUnique()
            .HasDatabaseName("IX_admin_users_username");

        // Role - 角色编码唯一
        modelBuilder.Entity<Role>()
            .HasIndex(e => e.Code)
            .IsUnique()
            .HasDatabaseName("IX_roles_code");

        // Permission - 权限编码唯一
        modelBuilder.Entity<Permission>()
            .HasIndex(e => e.Code)
            .IsUnique()
            .HasDatabaseName("IX_permissions_code");

        // Department - 部门编码唯一（允许为空，但非空值必须唯一）
        modelBuilder.Entity<Department>()
            .HasIndex(e => e.Code)
            .IsUnique()
            .HasFilter("[Code] IS NOT NULL")
            .HasDatabaseName("IX_departments_code");

        // ========== 关联表复合唯一索引配置 ==========

        // AdminUserRole - 管理员ID + 角色ID 唯一
        modelBuilder.Entity<AdminUserRole>()
            .HasIndex(e => new { e.AdminUserId, e.RoleId })
            .IsUnique()
            .HasDatabaseName("IX_admin_user_roles_user_role");

        // AdminUserMenu - 管理员ID + 菜单ID 唯一
        modelBuilder.Entity<AdminUserMenu>()
            .HasIndex(e => new { e.AdminUserId, e.MenuId })
            .IsUnique()
            .HasDatabaseName("IX_admin_user_menus_user_menu");

        // RoleMenu - 角色ID + 菜单ID 唯一
        modelBuilder.Entity<RoleMenu>()
            .HasIndex(e => new { e.RoleId, e.MenuId })
            .IsUnique()
            .HasDatabaseName("IX_role_menus_role_menu");

        // RolePermission - 角色ID + 权限ID 唯一
        modelBuilder.Entity<RolePermission>()
            .HasIndex(e => new { e.RoleId, e.PermissionId })
            .IsUnique()
            .HasDatabaseName("IX_role_permissions_role_permission");

        // DepartmentMenu - 部门ID + 菜单ID 唯一
        modelBuilder.Entity<DepartmentMenu>()
            .HasIndex(e => new { e.DepartmentId, e.MenuId })
            .IsUnique()
            .HasDatabaseName("IX_department_menus_department_menu");

        // ========== 查询优化索引 ==========

        // OperationLog - 按管理员ID查询
        modelBuilder.Entity<OperationLog>()
            .HasIndex(e => e.AdminUserId)
            .HasDatabaseName("IX_operation_logs_admin_user_id");

        // OperationLog - 按创建时间查询
        modelBuilder.Entity<OperationLog>()
            .HasIndex(e => e.CreatedAt)
            .HasDatabaseName("IX_operation_logs_created_at");

        // OperationLog - 按模块查询
        modelBuilder.Entity<OperationLog>()
            .HasIndex(e => e.Module)
            .HasDatabaseName("IX_operation_logs_module");

        // AdminUser - 按部门ID查询
        modelBuilder.Entity<AdminUser>()
            .HasIndex(e => e.DepartmentId)
            .HasDatabaseName("IX_admin_users_department_id");

        // Menu - 按父菜单ID查询
        modelBuilder.Entity<Menu>()
            .HasIndex(e => e.ParentId)
            .HasDatabaseName("IX_menus_parent_id");

        // Department - 按父部门ID查询
        modelBuilder.Entity<Department>()
            .HasIndex(e => e.ParentId)
            .HasDatabaseName("IX_departments_parent_id");

        // ========== 实体关系配置 ==========

        // AdminUser -> Department (多对一)
        modelBuilder.Entity<AdminUser>()
            .HasOne(e => e.Department)
            .WithMany(d => d.AdminUsers)
            .HasForeignKey(e => e.DepartmentId)
            .OnDelete(DeleteBehavior.SetNull);

        // AdminUserRole 关系
        modelBuilder.Entity<AdminUserRole>()
            .HasOne(e => e.AdminUser)
            .WithMany(u => u.AdminUserRoles)
            .HasForeignKey(e => e.AdminUserId)
            .OnDelete(DeleteBehavior.Cascade);

        modelBuilder.Entity<AdminUserRole>()
            .HasOne(e => e.Role)
            .WithMany(r => r.AdminUserRoles)
            .HasForeignKey(e => e.RoleId)
            .OnDelete(DeleteBehavior.Cascade);

        // AdminUserMenu 关系
        modelBuilder.Entity<AdminUserMenu>()
            .HasOne(e => e.AdminUser)
            .WithMany(u => u.AdminUserMenus)
            .HasForeignKey(e => e.AdminUserId)
            .OnDelete(DeleteBehavior.Cascade);

        modelBuilder.Entity<AdminUserMenu>()
            .HasOne(e => e.Menu)
            .WithMany(m => m.AdminUserMenus)
            .HasForeignKey(e => e.MenuId)
            .OnDelete(DeleteBehavior.Cascade);

        // RoleMenu 关系
        modelBuilder.Entity<RoleMenu>()
            .HasOne(e => e.Role)
            .WithMany(r => r.RoleMenus)
            .HasForeignKey(e => e.RoleId)
            .OnDelete(DeleteBehavior.Cascade);

        modelBuilder.Entity<RoleMenu>()
            .HasOne(e => e.Menu)
            .WithMany(m => m.RoleMenus)
            .HasForeignKey(e => e.MenuId)
            .OnDelete(DeleteBehavior.Cascade);

        // RolePermission 关系
        modelBuilder.Entity<RolePermission>()
            .HasOne(e => e.Role)
            .WithMany(r => r.RolePermissions)
            .HasForeignKey(e => e.RoleId)
            .OnDelete(DeleteBehavior.Cascade);

        modelBuilder.Entity<RolePermission>()
            .HasOne(e => e.Permission)
            .WithMany(p => p.RolePermissions)
            .HasForeignKey(e => e.PermissionId)
            .OnDelete(DeleteBehavior.Cascade);

        // DepartmentMenu 关系
        modelBuilder.Entity<DepartmentMenu>()
            .HasOne(e => e.Department)
            .WithMany(d => d.DepartmentMenus)
            .HasForeignKey(e => e.DepartmentId)
            .OnDelete(DeleteBehavior.Cascade);

        modelBuilder.Entity<DepartmentMenu>()
            .HasOne(e => e.Menu)
            .WithMany(m => m.DepartmentMenus)
            .HasForeignKey(e => e.MenuId)
            .OnDelete(DeleteBehavior.Cascade);

        // ========== 字段配置 ==========

        // OperationLog - RequestData 和 ResponseData 使用 nvarchar(max)
        modelBuilder.Entity<OperationLog>()
            .Property(e => e.RequestData)
            .HasColumnType("nvarchar(max)");

        modelBuilder.Entity<OperationLog>()
            .Property(e => e.ResponseData)
            .HasColumnType("nvarchar(max)");

        // ========== RefreshToken 配置 ==========

        // RefreshToken - TokenHash 索引（用于快速查找）
        modelBuilder.Entity<RefreshToken>()
            .HasIndex(e => e.TokenHash)
            .HasDatabaseName("IX_refresh_tokens_token_hash");

        // RefreshToken - AdminUserId 索引（用于查询用户的所有Token）
        modelBuilder.Entity<RefreshToken>()
            .HasIndex(e => e.AdminUserId)
            .HasDatabaseName("IX_refresh_tokens_admin_user_id");

        // RefreshToken -> AdminUser 关系
        modelBuilder.Entity<RefreshToken>()
            .HasOne(e => e.AdminUser)
            .WithMany(u => u.RefreshTokens)
            .HasForeignKey(e => e.AdminUserId)
            .OnDelete(DeleteBehavior.Cascade);
    }
}
