using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using IamService.Domain.AggregatesModel.GroupAggregate;

namespace IamService.Infrastructure.EntityConfigurations;

/// <summary>
/// EN: Entity configuration for Group.
/// VI: Cấu hình entity cho Group.
/// </summary>
public class GroupEntityConfiguration : IEntityTypeConfiguration<Group>
{
    public void Configure(EntityTypeBuilder<Group> builder)
    {
        builder.ToTable("groups");

        builder.HasKey(g => g.Id);

        builder.Property(g => g.Id)
            .HasColumnName("id")
            .ValueGeneratedNever();

        builder.Property("_name")
            .HasColumnName("name")
            .HasMaxLength(200)
            .IsRequired();

        builder.Property("_description")
            .HasColumnName("description")
            .HasMaxLength(1000);

        builder.Property("_organizationId")
            .HasColumnName("organization_id")
            .IsRequired();

        builder.Property("_createdAt")
            .HasColumnName("created_at")
            .IsRequired();

        builder.Property("_updatedAt")
            .HasColumnName("updated_at");

        builder.Property("_isDeleted")
            .HasColumnName("is_deleted")
            .HasDefaultValue(false);

        // EN: Index for organization lookup
        // VI: Index để tìm kiếm theo organization
        builder.HasIndex("_organizationId")
            .HasDatabaseName("ix_groups_organization_id");

        // EN: Query filter for soft delete
        // VI: Query filter cho soft delete
        builder.HasQueryFilter(g => !g.IsDeleted);

        // EN: Configure navigation to members
        // VI: Cấu hình navigation đến members
        builder.HasMany(g => g.Members)
            .WithOne()
            .HasForeignKey("_groupId")
            .OnDelete(DeleteBehavior.Cascade);

        // EN: Configure navigation to permissions
        // VI: Cấu hình navigation đến permissions
        builder.HasMany(g => g.Permissions)
            .WithOne()
            .HasForeignKey("_groupId")
            .OnDelete(DeleteBehavior.Cascade);

        // EN: Ignore domain events
        // VI: Bỏ qua domain events
        builder.Ignore(g => g.DomainEvents);
    }
}

/// <summary>
/// EN: Entity configuration for GroupMember.
/// VI: Cấu hình entity cho GroupMember.
/// </summary>
public class GroupMemberEntityConfiguration : IEntityTypeConfiguration<GroupMember>
{
    public void Configure(EntityTypeBuilder<GroupMember> builder)
    {
        builder.ToTable("group_members");

        builder.HasKey(m => m.Id);

        builder.Property(m => m.Id)
            .HasColumnName("id")
            .ValueGeneratedNever();

        builder.Property("_userId")
            .HasColumnName("user_id")
            .IsRequired();

        builder.Property("_groupId")
            .HasColumnName("group_id")
            .IsRequired();

        builder.Property(m => m.RoleId)
            .HasColumnName("role_id")
            .IsRequired();

        builder.Property("_joinedAt")
            .HasColumnName("joined_at")
            .IsRequired();

        builder.Property("_addedByUserId")
            .HasColumnName("added_by_user_id");

        // EN: Unique index to prevent duplicate memberships
        // VI: Unique index để ngăn thành viên trùng lặp
        builder.HasIndex("_groupId", "_userId")
            .IsUnique()
            .HasDatabaseName("ix_group_members_group_user");

        // EN: Index for user lookup
        // VI: Index để tìm kiếm theo user
        builder.HasIndex("_userId")
            .HasDatabaseName("ix_group_members_user_id");

        // EN: Ignore expression-bodied properties (use backing fields instead)
        // VI: Bỏ qua properties expression-bodied (sử dụng backing fields thay thế)
        builder.Ignore(m => m.UserId);
        builder.Ignore(m => m.GroupId);
        builder.Ignore(m => m.JoinedAt);
        builder.Ignore(m => m.AddedByUserId);
        builder.Ignore(m => m.Role);
    }
}

/// <summary>
/// EN: Entity configuration for GroupPermission.
/// VI: Cấu hình entity cho GroupPermission.
/// </summary>
public class GroupPermissionEntityConfiguration : IEntityTypeConfiguration<GroupPermission>
{
    public void Configure(EntityTypeBuilder<GroupPermission> builder)
    {
        builder.ToTable("group_permissions");

        builder.HasKey(p => p.Id);

        builder.Property(p => p.Id)
            .HasColumnName("id")
            .ValueGeneratedNever();

        builder.Property("_groupId")
            .HasColumnName("group_id")
            .IsRequired();

        builder.Property("_permission")
            .HasColumnName("permission")
            .HasMaxLength(100)
            .IsRequired();

        builder.Property("_resource")
            .HasColumnName("resource")
            .HasMaxLength(500);

        builder.Property("_grantedAt")
            .HasColumnName("granted_at")
            .IsRequired();

        builder.Property("_grantedByUserId")
            .HasColumnName("granted_by_user_id");

        // EN: Index for permission lookup
        // VI: Index để tìm kiếm permission
        builder.HasIndex("_groupId", "_permission", "_resource")
            .IsUnique()
            .HasDatabaseName("ix_group_permissions_unique");

        // EN: Ignore expression-bodied properties (use backing fields instead)
        // VI: Bỏ qua properties expression-bodied (sử dụng backing fields thay thế)
        builder.Ignore(p => p.GroupId);
        builder.Ignore(p => p.Permission);
        builder.Ignore(p => p.Resource);
        builder.Ignore(p => p.GrantedAt);
        builder.Ignore(p => p.GrantedByUserId);
    }
}

/// <summary>
/// EN: Entity configuration for GroupRole.
/// VI: Cấu hình entity cho GroupRole.
/// </summary>
public class GroupRoleEntityConfiguration : IEntityTypeConfiguration<GroupRole>
{
    public void Configure(EntityTypeBuilder<GroupRole> builder)
    {
        builder.ToTable("group_roles");

        builder.HasKey(r => r.Id);

        builder.Property(r => r.Id)
            .HasColumnName("id")
            .ValueGeneratedNever();

        builder.Property(r => r.Name)
            .HasColumnName("name")
            .HasMaxLength(50)
            .IsRequired();

        // EN: Seed data
        // VI: Seed data
        builder.HasData(
            GroupRole.Member,
            GroupRole.Admin,
            GroupRole.Owner
        );
    }
}
