// 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(s => s.UserId)
            .HasField("_userId")
            .HasColumnName("user_id");

        builder.Property(s => s.MerchantId)
            .HasField("_merchantId")
            .HasColumnName("merchant_id")
            .IsRequired();

        builder.Property(s => s.EmployeeCode)
            .HasField("_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(s => s.Permissions)
            .HasField("_permissions")
            .HasColumnName("permissions")
            .HasConversion<int>();

        builder.Property(s => s.Phone)
            .HasField("_phone")
            .HasColumnName("phone")
            .HasMaxLength(20);

        builder.Property(s => s.Email)
            .HasField("_email")
            .HasColumnName("email")
            .HasMaxLength(100);

        builder.Property(s => s.PinCodeHash)
            .HasField("_pinCodeHash")
            .HasColumnName("pin_code_hash")
            .HasMaxLength(100);

        builder.Property(s => s.JoinedAt)
            .HasField("_joinedAt")
            .HasColumnName("joined_at");

        builder.Property(s => s.TerminatedAt)
            .HasField("_terminatedAt")
            .HasColumnName("terminated_at");

        builder.Property(s => s.CreatedAt)
            .HasField("_createdAt")
            .HasColumnName("created_at")
            .IsRequired();

        builder.Property(s => s.UpdatedAt)
            .HasField("_updatedAt")
            .HasColumnName("updated_at");

        builder.Property(s => s.FirstName)
            .HasField("_firstName")
            .HasColumnName("first_name")
            .HasMaxLength(100);

        builder.Property(s => s.LastName)
            .HasField("_lastName")
            .HasColumnName("last_name")
            .HasMaxLength(100);

        builder.Property(s => s.Address)
            .HasField("_address")
            .HasColumnName("address")
            .HasMaxLength(500);

        builder.Property(s => s.ProfilePhotoUrl)
            .HasField("_profilePhotoUrl")
            .HasColumnName("profile_photo_url")
            .HasMaxLength(500);

        builder.Property(s => s.DocumentFrontUrl)
            .HasField("_documentFrontUrl")
            .HasColumnName("document_front_url")
            .HasMaxLength(500);

        builder.Property(s => s.DocumentBackUrl)
            .HasField("_documentBackUrl")
            .HasColumnName("document_back_url")
            .HasMaxLength(500);

        // 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(s => s.UserId).HasDatabaseName("ix_merchant_staff_user_id");
        builder.HasIndex(s => s.MerchantId).HasDatabaseName("ix_merchant_staff_merchant_id");
        builder.HasIndex(s => s.Email).HasDatabaseName("ix_merchant_staff_email");

        // EN: Ignore Enumeration navigation properties (resolved in-memory).
        // VI: Ignore Enumeration navigation properties (resolve trong bộ nhớ).
        builder.Ignore(s => s.Role);
        builder.Ignore(s => s.Status);
    }
}

/// <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(d => d.DeviceId)
            .HasField("_deviceId")
            .HasColumnName("device_id")
            .HasMaxLength(100)
            .IsRequired();

        builder.Property(d => d.DeviceName)
            .HasField("_deviceName")
            .HasColumnName("device_name")
            .HasMaxLength(100);

        builder.Property(d => d.FcmToken)
            .HasField("_fcmToken")
            .HasColumnName("fcm_token")
            .HasMaxLength(500);

        builder.Property(d => d.Platform)
            .HasField("_platform")
            .HasColumnName("platform")
            .HasMaxLength(20)
            .IsRequired();

        builder.Property(d => d.LastUsedAt)
            .HasField("_lastUsedAt")
            .HasColumnName("last_used_at");

        builder.Property(d => d.CreatedAt)
            .HasField("_createdAt")
            .HasColumnName("created_at")
            .IsRequired();

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

/// <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(m => m.ShopId)
            .HasField("_shopId")
            .HasColumnName("shop_id")
            .IsRequired();

        builder.Property(m => m.BranchId)
            .HasField("_branchId")
            .HasColumnName("branch_id");

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

        builder.Property(m => m.CustomPermissions)
            .HasField("_customPermissions")
            .HasColumnName("custom_permissions")
            .HasConversion<int?>();

        builder.Property(m => m.IsPrimary)
            .HasField("_isPrimary")
            .HasColumnName("is_primary")
            .HasDefaultValue(false);

        builder.Property(m => m.AssignedAt)
            .HasField("_assignedAt")
            .HasColumnName("assigned_at")
            .IsRequired();

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

        // EN: Ignore Enumeration navigation property (resolved in-memory).
        // VI: Ignore Enumeration navigation property (resolve trong bộ nhớ).
        builder.Ignore(m => m.Role);
    }
}

/// <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
        );
    }
}
