using ColaFlow.Modules.Identity.Domain.Aggregates.Users;
using ColaFlow.Modules.Identity.Domain.Aggregates.Tenants;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace ColaFlow.Modules.Identity.Infrastructure.Persistence.Configurations;

public class UserTenantRoleConfiguration : IEntityTypeConfiguration<UserTenantRole>
{
    public void Configure(EntityTypeBuilder<UserTenantRole> builder)
    {
        builder.ToTable("user_tenant_roles", "identity");

        // Primary key
        builder.HasKey(utr => utr.Id);

        // Properties
        builder.Property(utr => utr.Id)
            .HasColumnName("id")
            .IsRequired();

        builder.Property(utr => utr.Role)
            .HasColumnName("role")
            .HasConversion<string>() // Store as string (e.g., "TenantOwner")
            .HasMaxLength(50)
            .IsRequired();

        builder.Property(utr => utr.AssignedAt)
            .HasColumnName("assigned_at")
            .IsRequired();

        builder.Property(utr => utr.AssignedByUserId)
            .HasColumnName("assigned_by_user_id");

        // Value objects mapping (keep for application use)
        builder.Property(utr => utr.UserId)
            .HasColumnName("user_id")
            .HasConversion(
                id => id.Value,
                value => UserId.Create(value))
            .IsRequired();

        builder.Property(utr => utr.TenantId)
            .HasColumnName("tenant_id")
            .HasConversion(
                id => id.Value,
                value => TenantId.Create(value))
            .IsRequired();

        // SOLUTION: Ignore navigation properties to avoid automatic FK generation
        // This prevents EF Core from creating shadow properties for navigation relationships
        builder.Ignore(utr => utr.User);
        builder.Ignore(utr => utr.Tenant);

        // Manually create foreign key constraints using the converted value object columns
        // This reuses the same user_id and tenant_id columns for both data storage and FK constraints
        builder.HasIndex("UserId")
            .HasDatabaseName("ix_user_tenant_roles_user_id");

        builder.HasIndex("TenantId")
            .HasDatabaseName("ix_user_tenant_roles_tenant_id");

        builder.HasIndex(utr => utr.Role)
            .HasDatabaseName("ix_user_tenant_roles_role");

        // Performance index for tenant + role queries
        builder.HasIndex("TenantId", "Role")
            .HasDatabaseName("ix_user_tenant_roles_tenant_role");

        // Unique constraint
        builder.HasIndex("UserId", "TenantId")
            .IsUnique()
            .HasDatabaseName("uq_user_tenant_roles_user_tenant");

        // Add FK constraints using raw SQL (executed after table creation)
        // Note: This is configured via migrations, not here
    }
}
