using Microsoft.EntityFrameworkCore;
using Modules.Library.Database.Database.Models;
using Modules.Library.Database.Database.Models.Anime;
using Modules.Library.Database.Database.Models.CommonProperties;
using Modules.Library.Database.Database.Models.Genre;
using Modules.Library.Database.Database.Models.Language;

namespace Modules.Library.Database.Database;

public class LibraryDbContext : DbContext
{
    public DbSet<Genre> Genres { get; set; }
    public DbSet<Language> Languages { get; set; }
    public DbSet<MediaInfo> MediaInfos { get; set; }

    public DbSet<AnimeTitle> AnimeTitles { get; set; }
    public DbSet<AnimeSeason> AnimeSeasons { get; set; }
    public DbSet<AnimeEpisode> AnimeEpisodes { get; set; }

    public LibraryDbContext(DbContextOptions<LibraryDbContext> options) : base(options)
    {

    }

    protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
    {
        configurationBuilder.Properties<Enum>().HaveConversion<string>();
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        /* ** LANGUAGE ** */
        modelBuilder.Entity<Language>(q =>
        {
            q.HasKey(q => q.Id);
            q.Property(q => q.Name).HasMaxLength(64);
            q.Property(q => q.CodeIso3).HasMaxLength(3);
        });

        /* ** GENRE ** */
        modelBuilder.Entity<Genre>(q =>
        {
            q.HasKey(q => q.Id);
            q.Property(q => q.Name).HasMaxLength(64);
        });

        /* ** ANIME ** */
        modelBuilder.Entity<AnimeTitle>(q =>
        {
            q.HasKey(q => q.Id);
            q.HasOne(q => q.CommonProperties)
                .WithOne()
                .HasForeignKey<CommonProperties>("AnimeTitleId")
                .OnDelete(DeleteBehavior.Cascade);
            q.HasMany(q => q.Items)
                .WithOne(q => q.Title)
                .HasForeignKey(q => q.AnimeTitleId)
                .OnDelete(DeleteBehavior.Cascade);
        });

        modelBuilder.Entity<AnimeItem>(q =>
        {
            q.HasKey(q => q.Id);
            q.HasOne(q => q.CommonProperties)
                .WithOne()
                .HasForeignKey<CommonProperties>("AnimeItemId")
                .OnDelete(DeleteBehavior.Cascade);
            q.UseTpcMappingStrategy();
        });


        modelBuilder.Entity<AnimeSeason>(q =>
        {
            q.ToTable("Anime_Seasons");
            q.Property(q => q.OriginCountry).HasMaxLength(64);
            q.Property(q => q.Director).HasMaxLength(128);
            //q.OwnsOne(q => q.CommonProperties);
            //q.HasMany(q => q.CommonProperties.Names).WithOne();
            //q.HasMany(q => q.CommonProperties.Descriptions).WithOne();
            //q.HasMany(q => q.CommonProperties.Genres).WithOne();
            //q.HasMany(q => q.CommonProperties.RelatedContent).WithOne();
            //q.OwnsOne(q => q.CommonProperties.Preview);
            q.HasMany(q => q.Episodes)
                .WithOne(q => q.Season)
                //.HasForeignKey(q => q.SeasonId)
                .OnDelete(DeleteBehavior.Cascade);
        });
        modelBuilder.Entity<AnimeEpisode>(q =>
        {
            q.ToTable("Anime_Episodes");
        });

        /* COMMON PROPERTIES */
        modelBuilder.Entity<CommonProperties>(q =>
        {
            q.HasMany(q => q.Names).WithOne().OnDelete(DeleteBehavior.Cascade);
            q.HasMany(q => q.Descriptions).WithOne().OnDelete(DeleteBehavior.Cascade);
            q.HasMany(q => q.Genres).WithOne().OnDelete(DeleteBehavior.Cascade);
            q.HasMany(q => q.RelatedContent).WithOne().OnDelete(DeleteBehavior.Cascade);
            q.HasOne(q => q.Preview).WithMany().OnDelete(DeleteBehavior.Cascade);
        });
    }
}
