namespace Server.DB;

using Documents;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

public class WonderkingContext : DbContext
{
    private readonly IConfiguration _configuration;
    private readonly ILoggerFactory _loggerFactory;

    public WonderkingContext(ILoggerFactory loggerFactory, IConfiguration configuration)
    {
        this._loggerFactory = loggerFactory;
        this._configuration = configuration;
    }

    public DbSet<Account> Accounts { get; set; }
    public DbSet<Character> Characters { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) =>
        optionsBuilder
            .UseNpgsql(
                $"Host={this._configuration["DB:Host"]};Username={this._configuration["DB:Username"]};Password={this._configuration["DB:Password"]};Database={this._configuration["DB:Database"]};Port={this._configuration["DB:Port"]}")
            .EnableSensitiveDataLogging().UseLoggerFactory(this._loggerFactory);

    protected override void OnModelCreating(ModelBuilder modelBuilder) =>
        modelBuilder.Entity<Account>(builder =>
        {
            builder.Property(b => b.Username).HasColumnType("varchar(20)");
            builder.HasIndex(b => b.Username).IsUnique();
            builder.Property(b => b.Password).HasColumnType("bytea");
            builder.Property(b => b.Salt).HasColumnType("bytea");
            builder.HasKey(b => b.Id);
            builder.HasMany(e => e.Characters).WithOne(e => e.Account).HasForeignKey(e => e.AccountId)
                .IsRequired();
        }).Entity<Character>(builder =>
        {
            builder.HasKey(c => c.Id);
            builder.Property(c => c.Name).HasColumnType("varchar(20)");
            builder.HasIndex(c => c.Name).IsUnique();
            builder.HasMany(e => e.InventoryItems).WithOne(e => e.Character)
                .HasForeignKey(e => e.CharacterId).IsRequired();
            builder.OwnsOne(p => p.BaseStats);
            builder.OwnsOne(p => p.JobData);
        }).Entity<InventoryItem>(builder => { builder.HasKey(i => i.Id); }).Entity<Guild>(builder =>
        {
            builder.HasKey(g => g.Id);
            builder.HasMany(g => g.GuildMembers).WithOne(g => g.Guild).HasForeignKey(g => g.GuildId)
                .IsRequired();
        });
}