using Extrudex.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Extrudex.Infrastructure.Data.Configurations;

public class SpoolConfiguration : BaseEntityConfiguration<Spool>
{
    public override void Configure(EntityTypeBuilder<Spool> builder)
    {
        base.Configure(builder);

        builder.Property(e => e.MaterialBaseId)
            .HasColumnName("material_base_id")
            .IsRequired();

        builder.Property(e => e.MaterialFinishId)
            .HasColumnName("material_finish_id")
            .IsRequired();

        builder.Property(e => e.MaterialModifierId)
            .HasColumnName("material_modifier_id");

        builder.Property(e => e.Brand)
            .HasColumnName("brand")
            .IsRequired()
            .HasMaxLength(200);

        builder.Property(e => e.ColorName)
            .HasColumnName("color_name")
            .IsRequired()
            .HasMaxLength(200);

        builder.Property(e => e.ColorHex)
            .HasColumnName("color_hex")
            .IsRequired()
            .HasMaxLength(7); // "#RRGGBB" format

        builder.Property(e => e.WeightTotalGrams)
            .HasColumnName("weight_total_grams")
            .HasPrecision(10, 2)
            .IsRequired();

        builder.Property(e => e.WeightRemainingGrams)
            .HasColumnName("weight_remaining_grams")
            .HasPrecision(10, 2)
            .IsRequired();

        builder.Property(e => e.FilamentDiameterMm)
            .HasColumnName("filament_diameter_mm")
            .HasPrecision(6, 3)
            .IsRequired();

        builder.Property(e => e.SpoolSerial)
            .HasColumnName("spool_serial")
            .IsRequired()
            .HasMaxLength(200);

        builder.Property(e => e.PurchasePrice)
            .HasColumnName("purchase_price")
            .HasPrecision(10, 2);

        builder.Property(e => e.PurchaseDate)
            .HasColumnName("purchase_date");

        builder.Property(e => e.IsActive)
            .HasColumnName("is_active")
            .HasDefaultValue(true)
            .IsRequired();

        builder.Property(e => e.IsArchived)
            .HasColumnName("is_archived")
            .HasDefaultValue(false)
            .IsRequired();

        builder.Property(e => e.StorageLocation)
            .HasColumnName("storage_location")
            .HasMaxLength(200);

        // Unique index on spool_serial — critical for barcode/QR scanning
        builder.HasIndex(e => e.SpoolSerial)
            .IsUnique()
            .HasDatabaseName("ix_spools_spool_serial");

        // Index on material_base_id for spool filtering
        builder.HasIndex(e => e.MaterialBaseId)
            .HasDatabaseName("ix_spools_material_base_id");

        // Index on material_finish_id for spool filtering
        builder.HasIndex(e => e.MaterialFinishId)
            .HasDatabaseName("ix_spools_material_finish_id");

        // Index on material_modifier_id for spool filtering
        builder.HasIndex(e => e.MaterialModifierId)
            .HasDatabaseName("ix_spools_material_modifier_id");

        // Index on is_active for active spool queries
        builder.HasIndex(e => e.IsActive)
            .HasDatabaseName("ix_spools_is_active");

        // Index on is_archived for inventory filtering (exclude archived from default views)
        builder.HasIndex(e => e.IsArchived)
            .HasDatabaseName("ix_spools_is_archived");

        // Composite index on is_active + is_archived for common inventory queries
        builder.HasIndex(e => new { e.IsActive, e.IsArchived })
            .HasDatabaseName("ix_spools_active_archived");

        // Relationships
        builder.HasOne(e => e.MaterialBase)
            .WithMany(e => e.Spools)
            .HasForeignKey(e => e.MaterialBaseId)
            .HasConstraintName("fk_spools_material_base")
            .OnDelete(DeleteBehavior.Restrict);

        builder.HasOne(e => e.MaterialFinish)
            .WithMany(e => e.Spools)
            .HasForeignKey(e => e.MaterialFinishId)
            .HasConstraintName("fk_spools_material_finish")
            .OnDelete(DeleteBehavior.Restrict);

        builder.HasOne(e => e.MaterialModifier)
            .WithMany(e => e.Spools)
            .HasForeignKey(e => e.MaterialModifierId)
            .HasConstraintName("fk_spools_material_modifier")
            .OnDelete(DeleteBehavior.SetNull);

        builder.HasMany(e => e.AmsSlots)
            .WithOne(e => e.Spool!)
            .HasForeignKey(e => e.SpoolId)
            .HasConstraintName("fk_ams_slots_spool");

        builder.HasMany(e => e.PrintJobs)
            .WithOne(e => e.Spool)
            .HasForeignKey(e => e.SpoolId)
            .HasConstraintName("fk_print_jobs_spool");
    }
}