using DrinkRateAPI.DbEntities;
using Microsoft.EntityFrameworkCore;

namespace DrinkRateAPI.Contexts;

public class ApplicationDbContext : DbContext
{
    public DbSet<DbCompany> Companies { get; set; }
    public DbSet<DbCompanyRating> CompanyRatings { get; set; }
    public DbSet<DbCompanyTable> CompanyTables { get; set; }
    public DbSet<DbCompanyTableView> CompanyTableViews { get; set; }

    public DbSet<DbProduct> Product { get; set; }
    public DbSet<DbProductRating> ProductRating { get; set; }
    public DbSet<DbProductTable> ProductTable { get; set; }
    public DbSet<DbProductTableView> ProductTableView { get; set; }

    public DbSet<DbUser> Users { get; set; }
    public DbSet<DbUserCompanyTableStat> UserCompanyTableStats { get; set; }
    public DbSet<DbUserProductTableStat> UserProductTableStats { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json")
            .Build();

        optionsBuilder.UseNpgsql(configuration.GetConnectionString("Local"));
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Company
        modelBuilder.Entity<DbCompany>(c =>
        {
            c.HasKey(c => c.Id);

            c.HasMany(c => c.Products)
                .WithOne(p => p.Company)
                .HasForeignKey(p => p.CompanyId);

            c.HasMany(c => c.CompanyRatings)
                .WithOne(cr => cr.Company)
                .HasForeignKey(cr => cr.CompanyId);

            c.Property(c => c.CompanyName)
                .IsRequired()
                .HasMaxLength(50);

            c.HasIndex(c => c.CompanyName)
                .IsUnique();

            // to do: index by Sum / Count
        });

        // Company Rating
        modelBuilder.Entity<DbCompanyRating>(cr =>
        {
            cr.HasKey(cr => new { cr.UserId, cr.CompanyId });

            cr.HasOne(cr => cr.User)
                .WithMany(u => u.CompanyRatings);

            cr.HasOne(cr => cr.Company)
                .WithMany(c => c.CompanyRatings);
        });

        // to do: othe objects
    }
}