using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using TeleWave.Domain.Library;

namespace TeleWave.Infrastructure.Persistence.Configurations;

public class GenreConfiguration : IEntityTypeConfiguration<Genre>
{
    public void Configure(EntityTypeBuilder<Genre> builder)
    {
        builder.Property(x => x.Name).IsRequired().HasMaxLength(128);
        builder.Property(x => x.Slug).IsRequired().HasMaxLength(64);
        builder.HasIndex(x => x.Slug).IsUnique();

        builder
            .HasMany(x => x.Aliases)
            .WithOne()
            .HasForeignKey(a => a.GenreId)
            .OnDelete(DeleteBehavior.Cascade);
        builder.Navigation(x => x.Aliases).UsePropertyAccessMode(PropertyAccessMode.Field);
    }
}

public class GenreAliasConfiguration : IEntityTypeConfiguration<GenreAlias>
{
    public void Configure(EntityTypeBuilder<GenreAlias> builder)
    {
        builder.Property(x => x.Value).IsRequired().HasMaxLength(128);
        // Псевдоним однозначно указывает на жанр: иначе сопоставление метаданных стало бы неопределённым.
        builder.HasIndex(x => x.Value).IsUnique();
    }
}

public class ShowGenreConfiguration : IEntityTypeConfiguration<ShowGenre>
{
    public void Configure(EntityTypeBuilder<ShowGenre> builder)
    {
        builder.HasKey(x => new { x.ShowId, x.GenreId });
        builder.HasIndex(x => x.GenreId);

        // Restrict, а не Cascade: удаление жанра из справочника не должно молча снимать его со всех шоу.
        // Команда удаления проверяет использование заранее и возвращает управляемый конфликт.
        builder
            .HasOne<Genre>()
            .WithMany()
            .HasForeignKey(x => x.GenreId)
            .OnDelete(DeleteBehavior.Restrict);
    }
}
