using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using ScadaLink.Commons.Entities.Templates;

namespace ScadaLink.ConfigurationDatabase.Configurations;

public class TemplateConfiguration : IEntityTypeConfiguration<Template>
{
    public void Configure(EntityTypeBuilder<Template> builder)
    {
        builder.HasKey(t => t.Id);

        builder.Property(t => t.Name)
            .IsRequired()
            .HasMaxLength(200);

        builder.Property(t => t.Description)
            .HasMaxLength(2000);

        builder.HasIndex(t => t.Name).IsUnique();

        // Self-referencing parent template (inheritance)
        builder.HasOne<Template>()
            .WithMany()
            .HasForeignKey(t => t.ParentTemplateId)
            .OnDelete(DeleteBehavior.Restrict)
            .IsRequired(false);

        builder.HasOne<TemplateFolder>()
            .WithMany()
            .HasForeignKey(t => t.FolderId)
            .OnDelete(DeleteBehavior.Restrict)
            .IsRequired(false);

        builder.HasMany(t => t.Attributes)
            .WithOne()
            .HasForeignKey(a => a.TemplateId)
            .OnDelete(DeleteBehavior.Cascade);

        builder.HasMany(t => t.Alarms)
            .WithOne()
            .HasForeignKey(a => a.TemplateId)
            .OnDelete(DeleteBehavior.Cascade);

        builder.HasMany(t => t.Scripts)
            .WithOne()
            .HasForeignKey(s => s.TemplateId)
            .OnDelete(DeleteBehavior.Cascade);

        builder.HasMany(t => t.Compositions)
            .WithOne()
            .HasForeignKey(c => c.TemplateId)
            .OnDelete(DeleteBehavior.Cascade);
    }
}

public class TemplateAttributeConfiguration : IEntityTypeConfiguration<TemplateAttribute>
{
    public void Configure(EntityTypeBuilder<TemplateAttribute> builder)
    {
        builder.HasKey(a => a.Id);

        builder.Property(a => a.Name)
            .IsRequired()
            .HasMaxLength(200);

        builder.Property(a => a.Value)
            .HasMaxLength(4000);

        builder.Property(a => a.Description)
            .HasMaxLength(2000);

        builder.Property(a => a.DataSourceReference)
            .HasMaxLength(500);

        builder.Property(a => a.DataType)
            .HasConversion<string>()
            .HasMaxLength(50);

        builder.HasIndex(a => new { a.TemplateId, a.Name }).IsUnique();
    }
}

public class TemplateAlarmConfiguration : IEntityTypeConfiguration<TemplateAlarm>
{
    public void Configure(EntityTypeBuilder<TemplateAlarm> builder)
    {
        builder.HasKey(a => a.Id);

        builder.Property(a => a.Name)
            .IsRequired()
            .HasMaxLength(200);

        builder.Property(a => a.Description)
            .HasMaxLength(2000);

        builder.Property(a => a.TriggerType)
            .HasConversion<string>()
            .HasMaxLength(50);

        builder.Property(a => a.TriggerConfiguration)
            .HasMaxLength(4000);

        builder.HasIndex(a => new { a.TemplateId, a.Name }).IsUnique();
    }
}

public class TemplateScriptConfiguration : IEntityTypeConfiguration<TemplateScript>
{
    public void Configure(EntityTypeBuilder<TemplateScript> builder)
    {
        builder.HasKey(s => s.Id);

        builder.Property(s => s.Name)
            .IsRequired()
            .HasMaxLength(200);

        builder.Property(s => s.Code)
            .IsRequired();

        builder.Property(s => s.TriggerType)
            .HasMaxLength(50);

        builder.Property(s => s.TriggerConfiguration)
            .HasMaxLength(4000);

        builder.Property(s => s.ParameterDefinitions)
            .HasMaxLength(4000);

        builder.Property(s => s.ReturnDefinition)
            .HasMaxLength(4000);

        builder.HasIndex(s => new { s.TemplateId, s.Name }).IsUnique();
    }
}

public class TemplateCompositionConfiguration : IEntityTypeConfiguration<TemplateComposition>
{
    public void Configure(EntityTypeBuilder<TemplateComposition> builder)
    {
        builder.HasKey(c => c.Id);

        builder.Property(c => c.InstanceName)
            .IsRequired()
            .HasMaxLength(200);

        // The composed template reference
        builder.HasOne<Template>()
            .WithMany()
            .HasForeignKey(c => c.ComposedTemplateId)
            .OnDelete(DeleteBehavior.Restrict);

        builder.HasIndex(c => new { c.TemplateId, c.InstanceName }).IsUnique();
    }
}

public class TemplateFolderConfiguration : IEntityTypeConfiguration<TemplateFolder>
{
    public void Configure(EntityTypeBuilder<TemplateFolder> builder)
    {
        builder.HasKey(f => f.Id);

        builder.Property(f => f.Name)
            .IsRequired()
            .HasMaxLength(200);

        builder.HasOne<TemplateFolder>()
            .WithMany()
            .HasForeignKey(f => f.ParentFolderId)
            .OnDelete(DeleteBehavior.Restrict)
            .IsRequired(false);

        // Unique sibling name (case-insensitive enforced at service layer; this index is for fast lookup)
        builder.HasIndex(f => new { f.ParentFolderId, f.Name }).IsUnique();
    }
}
