using GameList.Domain;
using Microsoft.EntityFrameworkCore;

namespace GameList.Data;

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }

    public DbSet<Player> Players => Set<Player>();
    public DbSet<Suggestion> Suggestions => Set<Suggestion>();
    public DbSet<Vote> Votes => Set<Vote>();
    public DbSet<AppState> AppState => Set<AppState>();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Player>(builder =>
        {
            builder.HasKey(p => p.Id);
            builder.Property(p => p.DisplayName).HasMaxLength(16);
            builder.Property(p => p.Username).IsRequired().HasMaxLength(24);
            builder.Property(p => p.NormalizedUsername).IsRequired().HasMaxLength(24);
            builder.HasIndex(p => p.NormalizedUsername).IsUnique();
            builder.Property(p => p.PasswordHash).IsRequired();
            builder.Property(p => p.PasswordSalt).IsRequired();
            builder.Property(p => p.IsAdmin).HasDefaultValue(false);
            builder.HasMany(p => p.Suggestions)
                   .WithOne(s => s.Player!)
                   .HasForeignKey(s => s.PlayerId)
                   .OnDelete(DeleteBehavior.Cascade);
            builder.HasMany(p => p.Votes)
                   .WithOne(v => v.Player!)
                   .HasForeignKey(v => v.PlayerId)
                   .OnDelete(DeleteBehavior.Cascade);
        });

        modelBuilder.Entity<Suggestion>(builder =>
        {
            builder.HasKey(s => s.Id);
            builder.Property(s => s.Name).IsRequired().HasMaxLength(100);
            builder.Property(s => s.Genre).HasMaxLength(50);
            builder.Property(s => s.Description).HasMaxLength(500);
            builder.Property(s => s.ScreenshotUrl).HasMaxLength(2048);
            builder.Property(s => s.YoutubeUrl).HasMaxLength(2048);
            builder.Property(s => s.GameUrl).HasMaxLength(2048);
            builder.Property(s => s.MinPlayers);
            builder.Property(s => s.MaxPlayers);
        });

        modelBuilder.Entity<Vote>(builder =>
        {
            builder.HasKey(v => v.Id);
            builder.Property(v => v.Score).IsRequired();
            builder.HasIndex(v => new { v.PlayerId, v.SuggestionId }).IsUnique();
        });

        modelBuilder.Entity<AppState>(builder =>
        {
            builder.HasKey(s => s.Id);
            builder.HasData(new AppState
            {
                Id = 1,
                CurrentPhase = Phase.Suggest,
                UpdatedAt = DateTimeOffset.UnixEpoch
            });
        });
    }
}
