using Db.Models;
using Microsoft.EntityFrameworkCore;

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

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Configure your entity mappings here
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<VideoTag>(e =>
        {
            e.HasKey(vt => new { vt.VideoId, vt.TagId });
            e.HasOne(vt => vt.Video)
                .WithMany(v => v.VideoTags)
                .HasForeignKey(vt => vt.VideoId);
            e.HasOne(vt => vt.Tag)
                .WithMany(t => t.VideoTags)
                .HasForeignKey(vt => vt.TagId);
        });

        modelBuilder.Entity<Video>(e =>
        {
            e.HasKey(v => v.Id);
            e.Property(v => v.Id).IsRequired();
            e.Property(v => v.Extension).IsRequired();

            // delete videoTags when a video is deleted but not the tags
            e.HasMany(v => v.VideoTags)
                .WithOne(vt => vt.Video)
                .OnDelete(DeleteBehavior.Cascade);
        });

        modelBuilder.Entity<Tag>(e =>
        {
            e.HasKey(t => t.Name);
            e.Property(t => t.Name).IsRequired();

            // delete videoTags when a tag is deleted but not the videos
            e.HasMany(t => t.VideoTags)
                .WithOne(vt => vt.Tag)
                .OnDelete(DeleteBehavior.Cascade);
        });

        modelBuilder.Entity<Setting>(e =>
        {
            e.HasKey(s => s.Name);
            e.Property(s => s.Name).IsRequired();
            e.Property(s => s.Value).IsRequired();
        });

    }

    // Tags a video can have (e.g. "funny", "cat", "dog")
    public DbSet<Tag> Tags { get; set; }

    // Videos with tags, relative paths, and other metadata
    public DbSet<Video> Videos { get; set; }
    // Settings for the adapter, such as video path
    public DbSet<Setting> Settings { get; set; }
    public DbSet<VideoTag> VideoTags { get; set; }

    public async Task<T?> GetSettingAsync<T>(SettingName settingName)
    {
        var setting = await Settings.FindAsync(settingName);
        return setting != null ? (T?)Convert.ChangeType(setting.Value, typeof(T)) : default;
    }

    public async Task SetSettingAsync<T>(SettingName settingName, T value)
    {
        var setting = await Settings.FindAsync(settingName);
        if (setting == null)
        {
            setting = new Setting { Name = settingName, Value = value?.ToString() ?? string.Empty };
            Settings.Add(setting);
        }
        else
        {
            setting.Value = value?.ToString() ?? string.Empty;
            Settings.Update(setting);
        }
        await SaveChangesAsync();
    }
}