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

namespace TeleWave.Infrastructure.Persistence.Configurations;

public class ScheduleTemplateConfiguration : IEntityTypeConfiguration<ScheduleTemplate>
{
    public void Configure(EntityTypeBuilder<ScheduleTemplate> builder)
    {
        builder.Property(x => x.Name).IsRequired().HasMaxLength(256);
        builder.Property(x => x.RulesJson).HasColumnType("jsonb");
        builder.Property(x => x.AppliedSnapshotJson).HasColumnType("jsonb");
        builder.HasIndex(x => x.ChannelId);

        builder
            .HasMany(x => x.Layers)
            .WithOne()
            .HasForeignKey(l => l.TemplateId)
            .OnDelete(DeleteBehavior.Cascade);
        builder.Navigation(x => x.Layers).UsePropertyAccessMode(PropertyAccessMode.Field);
    }
}

public class GridLayerConfiguration : IEntityTypeConfiguration<GridLayer>
{
    public void Configure(EntityTypeBuilder<GridLayer> builder)
    {
        builder.Property(x => x.Name).IsRequired().HasMaxLength(128);
        builder.Property(x => x.ApplicabilityJson).HasColumnType("jsonb");
        builder.HasIndex(x => new { x.TemplateId, x.Priority });

        builder
            .HasMany(x => x.Slots)
            .WithOne()
            .HasForeignKey(s => s.LayerId)
            .OnDelete(DeleteBehavior.Cascade);
        builder.Navigation(x => x.Slots).UsePropertyAccessMode(PropertyAccessMode.Field);
    }
}

public class SlotConfiguration : IEntityTypeConfiguration<Slot>
{
    public void Configure(EntityTypeBuilder<Slot> builder)
    {
        builder.Property(x => x.Title).IsRequired().HasMaxLength(256);
        builder.Property(x => x.StrategyJson).HasColumnType("jsonb");
        builder.Property(x => x.RepeatSourceJson).HasColumnType("jsonb");
        builder.HasIndex(x => new { x.LayerId, x.TargetStart });
        builder.HasIndex(x => x.GroupId);

        // Группа не удаляется, пока на неё ссылается слот: иначе слот молча превратился бы в дыру,
        // и админ узнал бы об этом только из эфира.
        builder
            .HasOne<Group>()
            .WithMany()
            .HasForeignKey(x => x.GroupId)
            .OnDelete(DeleteBehavior.Restrict);
    }
}

public class SlotStateConfiguration : IEntityTypeConfiguration<SlotState>
{
    public void Configure(EntityTypeBuilder<SlotState> builder)
    {
        builder.HasKey(x => x.SlotId);

        // Состояние живёт ровно столько же, сколько слот.
        builder
            .HasOne<Slot>()
            .WithOne()
            .HasForeignKey<SlotState>(x => x.SlotId)
            .OnDelete(DeleteBehavior.Cascade);
    }
}
