// EN: Entity configuration for MerchantStaff aggregate.
// VI: Cấu hình entity cho MerchantStaff aggregate.

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MerchantService.Domain.AggregatesModel.MerchantStaffAggregate;

namespace MerchantService.Infrastructure.EntityConfigurations;

/// <summary>
/// EN: EF Core configuration for MerchantStaff entity.
/// VI: Cấu hình EF Core cho MerchantStaff entity.
/// </summary>
public class MerchantStaffEntityTypeConfiguration : IEntityTypeConfiguration<MerchantStaff>
{
    public void Configure(EntityTypeBuilder<MerchantStaff> builder)
    {
        builder.ToTable("merchant_staff");

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

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

        builder.Property<Guid>("_userId")
            .HasColumnName("user_id");

        builder.Property<Guid>("_merchantId")
            .HasColumnName("merchant_id")
            .IsRequired();

        builder.Property<string?>("_employeeCode")
            .HasColumnName("employee_code")
            .HasMaxLength(20);

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

        builder.Property(s => s.StatusId)
            .HasColumnName("status_id")
            .IsRequired();

        builder.Property<StaffPermissions>("_permissions")
            .HasColumnName("permissions")
            .HasConversion<int>();

        builder.Property<string?>("_phone")
            .HasColumnName("phone")
            .HasMaxLength(20);

        builder.Property<string?>("_email")
            .HasColumnName("email")
            .HasMaxLength(100);

        builder.Property<string?>("_pinCodeHash")
            .HasColumnName("pin_code_hash")
            .HasMaxLength(100);

        builder.Property<DateTime>("_joinedAt")
            .HasColumnName("joined_at");

        builder.Property<DateTime?>("_terminatedAt")
            .HasColumnName("terminated_at");

        builder.Property<DateTime>("_createdAt")
            .HasColumnName("created_at")
            .IsRequired();

        builder.Property<DateTime?>("_updatedAt")
            .HasColumnName("updated_at");

        // EN: Configure navigation to device tokens
        // VI: Cấu hình navigation đến device tokens
        builder.HasMany(s => s.DeviceTokens)
            .WithOne()
            .HasForeignKey(d => d.StaffId)
            .OnDelete(DeleteBehavior.Cascade);

        // EN: Configure navigation to shop assignments
        // VI: Cấu hình navigation đến shop assignments
        builder.HasMany(s => s.ShopAssignments)
            .WithOne()
            .HasForeignKey(a => a.StaffId)
            .OnDelete(DeleteBehavior.Cascade);

        // EN: Indexes
        // VI: Indexes
        builder.HasIndex("_userId").HasDatabaseName("ix_merchant_staff_user_id");
        builder.HasIndex("_merchantId").HasDatabaseName("ix_merchant_staff_merchant_id");
        builder.HasIndex("_email").HasDatabaseName("ix_merchant_staff_email");

        // EN: Ignore calculated properties
        // VI: Bỏ qua các properties được tính toán
        builder.Ignore(s => s.Role);
        builder.Ignore(s => s.Status);
        builder.Ignore(s => s.Permissions);
        builder.Ignore(s => s.UserId);
        builder.Ignore(s => s.MerchantId);
        builder.Ignore(s => s.EmployeeCode);
        builder.Ignore(s => s.Phone);
        builder.Ignore(s => s.Email);
        builder.Ignore(s => s.PinCodeHash);
        builder.Ignore(s => s.JoinedAt);
        builder.Ignore(s => s.TerminatedAt);
        builder.Ignore(s => s.CreatedAt);
        builder.Ignore(s => s.UpdatedAt);
    }
}

/// <summary>
/// EN: EF Core configuration for DeviceToken entity.
/// VI: Cấu hình EF Core cho DeviceToken entity.
/// </summary>
public class DeviceTokenEntityTypeConfiguration : IEntityTypeConfiguration<DeviceToken>
{
    public void Configure(EntityTypeBuilder<DeviceToken> builder)
    {
        builder.ToTable("device_tokens");

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

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

        builder.Property(d => d.StaffId)
            .HasColumnName("staff_id")
            .IsRequired();

        builder.Property<string>("_deviceId")
            .HasColumnName("device_id")
            .HasMaxLength(100)
            .IsRequired();

        builder.Property<string?>("_deviceName")
            .HasColumnName("device_name")
            .HasMaxLength(100);

        builder.Property<string?>("_fcmToken")
            .HasColumnName("fcm_token")
            .HasMaxLength(500);

        builder.Property<string>("_platform")
            .HasColumnName("platform")
            .HasMaxLength(20)
            .IsRequired();

        builder.Property<DateTime?>("_lastUsedAt")
            .HasColumnName("last_used_at");

        builder.Property<DateTime>("_createdAt")
            .HasColumnName("created_at")
            .IsRequired();

        // EN: Indexes
        // VI: Indexes
        builder.HasIndex(d => d.StaffId).HasDatabaseName("ix_device_tokens_staff_id");
        builder.HasIndex("_deviceId").HasDatabaseName("ix_device_tokens_device_id");

        // EN: Ignore navigation properties
        // VI: Bỏ qua navigation properties
        builder.Ignore(d => d.DeviceId);
        builder.Ignore(d => d.DeviceName);
        builder.Ignore(d => d.FcmToken);
        builder.Ignore(d => d.Platform);
        builder.Ignore(d => d.LastUsedAt);
        builder.Ignore(d => d.CreatedAt);
    }
}

/// <summary>
/// EN: EF Core configuration for ShopMember entity.
/// VI: Cấu hình EF Core cho ShopMember entity.
/// </summary>
public class ShopMemberEntityTypeConfiguration : IEntityTypeConfiguration<ShopMember>
{
    public void Configure(EntityTypeBuilder<ShopMember> builder)
    {
        builder.ToTable("shop_members");

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

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

        builder.Property(m => m.StaffId)
            .HasColumnName("staff_id")
            .IsRequired();

        builder.Property<Guid>("_shopId")
            .HasColumnName("shop_id")
            .IsRequired();

        builder.Property<Guid?>("_branchId")
            .HasColumnName("branch_id");

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

        builder.Property<StaffPermissions?>("_customPermissions")
            .HasColumnName("custom_permissions")
            .HasConversion<int?>();

        builder.Property<bool>("_isPrimary")
            .HasColumnName("is_primary")
            .HasDefaultValue(false);

        builder.Property<DateTime>("_assignedAt")
            .HasColumnName("assigned_at")
            .IsRequired();

        // EN: Indexes
        // VI: Indexes
        builder.HasIndex(m => m.StaffId).HasDatabaseName("ix_shop_members_staff_id");
        builder.HasIndex("_shopId").HasDatabaseName("ix_shop_members_shop_id");

        // EN: Ignore navigation properties
        // VI: Bỏ qua navigation properties
        builder.Ignore(m => m.Role);
        builder.Ignore(m => m.CustomPermissions);
        builder.Ignore(m => m.ShopId);
        builder.Ignore(m => m.BranchId);
        builder.Ignore(m => m.IsPrimary);
        builder.Ignore(m => m.AssignedAt);
    }
}

/// <summary>
/// EN: EF Core configuration for StaffRole enumeration.
/// VI: Cấu hình EF Core cho StaffRole enumeration.
/// </summary>
public class StaffRoleEntityTypeConfiguration : IEntityTypeConfiguration<StaffRole>
{
    public void Configure(EntityTypeBuilder<StaffRole> builder)
    {
        builder.ToTable("staff_roles");

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

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

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

        builder.HasData(
            StaffRole.Cashier,
            StaffRole.Waiter,
            StaffRole.Manager,
            StaffRole.Admin
        );
    }
}

/// <summary>
/// EN: EF Core configuration for StaffStatus enumeration.
/// VI: Cấu hình EF Core cho StaffStatus enumeration.
/// </summary>
public class StaffStatusEntityTypeConfiguration : IEntityTypeConfiguration<StaffStatus>
{
    public void Configure(EntityTypeBuilder<StaffStatus> builder)
    {
        builder.ToTable("staff_statuses");

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

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

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

        builder.HasData(
            StaffStatus.Invited,
            StaffStatus.Active,
            StaffStatus.Inactive,
            StaffStatus.Terminated
        );
    }
}

/// <summary>
/// EN: EF Core configuration for ShopRole enumeration.
/// VI: Cấu hình EF Core cho ShopRole enumeration.
/// </summary>
public class ShopRoleEntityTypeConfiguration : IEntityTypeConfiguration<ShopRole>
{
    public void Configure(EntityTypeBuilder<ShopRole> builder)
    {
        builder.ToTable("shop_roles");

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

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

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

        builder.HasData(
            ShopRole.Cashier,
            ShopRole.Waiter,
            ShopRole.Manager,
            ShopRole.Owner
        );
    }
}
