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 UserConfiguration : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        builder.ToTable("users", "identity");

        // Primary Key
        builder.HasKey(u => u.Id);

        builder.Property(u => u.Id)
            .HasConversion(
                id => (Guid)id,
                value => UserId.Create(value))
            .HasColumnName("id");

        // Tenant ID (foreign key)
        builder.Property(u => u.TenantId)
            .HasConversion(
                id => (Guid)id,
                value => TenantId.Create(value))
            .IsRequired()
            .HasColumnName("tenant_id");

        // Optional: Create foreign key relationship
        // builder.HasOne<Tenant>()
        //     .WithMany()
        //     .HasForeignKey(u => u.TenantId)
        //     .OnDelete(DeleteBehavior.Restrict);

        // Value Object mappings
        builder.Property(u => u.Email)
            .HasConversion(
                email => email.Value,
                value => Email.Create(value))
            .HasMaxLength(255)
            .IsRequired()
            .HasColumnName("email");

        builder.Property(u => u.FullName)
            .HasConversion(
                name => name.Value,
                value => FullName.Create(value))
            .HasMaxLength(100)
            .IsRequired()
            .HasColumnName("full_name");

        // Composite unique index (email unique within tenant)
        builder.HasIndex(u => new { u.TenantId, u.Email })
            .IsUnique()
            .HasDatabaseName("ix_users_tenant_id_email");

        // Enum mappings
        builder.Property(u => u.Status)
            .HasConversion<string>()
            .HasMaxLength(50)
            .IsRequired()
            .HasColumnName("status");

        builder.Property(u => u.AuthProvider)
            .HasConversion<string>()
            .HasMaxLength(50)
            .IsRequired()
            .HasColumnName("auth_provider");

        // Nullable fields
        builder.Property(u => u.PasswordHash)
            .HasMaxLength(255)
            .HasColumnName("password_hash");

        builder.Property(u => u.ExternalUserId)
            .HasMaxLength(255)
            .HasColumnName("external_user_id");

        builder.Property(u => u.ExternalEmail)
            .HasMaxLength(255)
            .HasColumnName("external_email");

        builder.Property(u => u.AvatarUrl)
            .HasMaxLength(500)
            .HasColumnName("avatar_url");

        builder.Property(u => u.JobTitle)
            .HasMaxLength(100)
            .HasColumnName("job_title");

        builder.Property(u => u.PhoneNumber)
            .HasMaxLength(50)
            .HasColumnName("phone_number");

        // Timestamps
        builder.Property(u => u.CreatedAt)
            .IsRequired()
            .HasColumnName("created_at");

        builder.Property(u => u.UpdatedAt)
            .HasColumnName("updated_at");

        builder.Property(u => u.LastLoginAt)
            .HasColumnName("last_login_at");

        builder.Property(u => u.EmailVerifiedAt)
            .HasColumnName("email_verified_at");

        // Security tokens
        builder.Property(u => u.EmailVerificationToken)
            .HasMaxLength(255)
            .HasColumnName("email_verification_token");

        builder.Property(u => u.PasswordResetToken)
            .HasMaxLength(255)
            .HasColumnName("password_reset_token");

        builder.Property(u => u.PasswordResetTokenExpiresAt)
            .HasColumnName("password_reset_token_expires_at");

        // Ignore domain events
        builder.Ignore(u => u.DomainEvents);
    }
}
