using System.Diagnostics;
using LctMonolith.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using EventLog = LctMonolith.Models.EventLog;
namespace LctMonolith.Database.Data;
///
/// Main EF Core database context for gamification module (PostgreSQL provider expected).
///
public class AppDbContext : IdentityDbContext, Guid>
{
public AppDbContext(DbContextOptions options) : base(options) { }
public DbSet Ranks => Set();
public DbSet RankRequiredMissions => Set();
public DbSet RankRequiredCompetencies => Set();
public DbSet Missions => Set();
public DbSet UserMissions => Set();
public DbSet MissionCompetencyRewards => Set();
public DbSet MissionArtifactRewards => Set();
public DbSet Competencies => Set();
public DbSet UserCompetencies => Set();
public DbSet Artifacts => Set();
public DbSet UserArtifacts => Set();
public DbSet StoreItems => Set();
public DbSet UserInventoryItems => Set();
public DbSet Transactions => Set();
public DbSet EventLogs => Set();
public DbSet RefreshTokens => Set();
public DbSet Notifications => Set();
protected override void OnModelCreating(ModelBuilder b)
{
base.OnModelCreating(b);
// Rank required mission composite key
b.Entity().HasKey(x => new { x.RankId, x.MissionId });
b.Entity()
.HasOne(x => x.Rank).WithMany(r => r.RequiredMissions).HasForeignKey(x => x.RankId);
b.Entity()
.HasOne(x => x.Mission).WithMany(m => m.RanksRequiring).HasForeignKey(x => x.MissionId);
// Rank required competency composite key
b.Entity().HasKey(x => new { x.RankId, x.CompetencyId });
b.Entity()
.HasOne(x => x.Rank).WithMany(r => r.RequiredCompetencies).HasForeignKey(x => x.RankId);
b.Entity()
.HasOne(x => x.Competency).WithMany(c => c.RankRequirements).HasForeignKey(x => x.CompetencyId);
// UserMission composite key
b.Entity().HasKey(x => new { x.UserId, x.MissionId });
b.Entity()
.HasOne(x => x.User).WithMany(u => u.Missions).HasForeignKey(x => x.UserId);
b.Entity()
.HasOne(x => x.Mission).WithMany(m => m.UserMissions).HasForeignKey(x => x.MissionId);
// UserCompetency composite key
b.Entity().HasKey(x => new { x.UserId, x.CompetencyId });
b.Entity()
.HasOne(x => x.User).WithMany(u => u.Competencies).HasForeignKey(x => x.UserId);
b.Entity()
.HasOne(x => x.Competency).WithMany(c => c.UserCompetencies).HasForeignKey(x => x.CompetencyId);
// Mission competency reward composite key
b.Entity().HasKey(x => new { x.MissionId, x.CompetencyId });
// Mission artifact reward composite key
b.Entity().HasKey(x => new { x.MissionId, x.ArtifactId });
// UserArtifact composite key
b.Entity().HasKey(x => new { x.UserId, x.ArtifactId });
// UserInventory composite key
b.Entity().HasKey(x => new { x.UserId, x.StoreItemId });
// Refresh token index unique
b.Entity().HasIndex(x => x.Token).IsUnique();
// ---------- Added performance indexes ----------
b.Entity().HasIndex(u => u.RankId);
b.Entity().HasIndex(m => m.MinRankId);
b.Entity().HasIndex(um => new { um.UserId, um.Status });
b.Entity().HasIndex(uc => uc.CompetencyId); // for querying all users by competency
b.Entity().HasIndex(e => new { e.UserId, e.Type, e.CreatedAt });
b.Entity().HasIndex(i => i.IsActive);
b.Entity().HasIndex(t => new { t.UserId, t.CreatedAt });
b.Entity().HasIndex(n => new { n.UserId, n.IsRead, n.CreatedAt });
}
}