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

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

namespace MerchantService.Infrastructure.EntityConfigurations;

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

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

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

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

        builder.Property<string>("_businessName")
            .HasColumnName("business_name")
            .HasMaxLength(200)
            .IsRequired();

        builder.Property(m => m.TypeId)
            .HasColumnName("type_id")
            .IsRequired();

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

        builder.Property(m => m.VerificationStatusId)
            .HasColumnName("verification_status_id")
            .IsRequired();

        // EN: Configure owned entity for BusinessInfo
        // VI: Cấu hình owned entity cho BusinessInfo
        builder.OwnsOne<BusinessInfo>("_businessInfo", bi =>
        {
            bi.Property(b => b.TaxId)
                .HasColumnName("tax_id")
                .HasMaxLength(20);

            bi.Property(b => b.BusinessLicenseNumber)
                .HasColumnName("business_license_number")
                .HasMaxLength(50);

            bi.Property(b => b.CompanyRegistrationNumber)
                .HasColumnName("company_registration_number")
                .HasMaxLength(50);

            bi.Property(b => b.EstablishedDate)
                .HasColumnName("established_date");
        });

        // EN: Configure owned entity for SettlementConfig
        // VI: Cấu hình owned entity cho SettlementConfig
        builder.OwnsOne<SettlementConfig>("_settlementConfig", sc =>
        {
            sc.Property(s => s.CommissionRate)
                .HasColumnName("commission_rate")
                .HasPrecision(5, 2);

            sc.Property(s => s.SettlementCycleId)
                .HasColumnName("settlement_cycle_id");

            sc.Property(s => s.AutoSettlement)
                .HasColumnName("auto_settlement");

            sc.OwnsOne(s => s.BankAccount, ba =>
            {
                ba.Property(b => b.BankCode)
                    .HasColumnName("bank_code")
                    .HasMaxLength(10);

                ba.Property(b => b.BankName)
                    .HasColumnName("bank_name")
                    .HasMaxLength(100);

                ba.Property(b => b.AccountNumber)
                    .HasColumnName("bank_account_number")
                    .HasMaxLength(30);

                ba.Property(b => b.AccountHolderName)
                    .HasColumnName("bank_account_holder_name")
                    .HasMaxLength(100);
            });
        });

        builder.Property(m => m.VerifiedAt)
            .HasColumnName("verified_at");

        builder.Property(m => m.VerifiedBy)
            .HasColumnName("verified_by");

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

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

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

        // EN: Subscription plan ID (0=Starter, 1=Growth, 2=Pro, 3=Enterprise)
        // VI: ID gói đăng ký (0=Starter, 1=Growth, 2=Pro, 3=Enterprise)
        builder.Property<int>("_subscriptionPlanId")
            .HasColumnName("subscription_plan_id")
            .HasDefaultValue(0)
            .IsRequired();

        // EN: Indexes
        // VI: Indexes
        builder.HasIndex("_userId").HasDatabaseName("ix_merchants_user_id");
        builder.HasIndex(m => m.StatusId).HasDatabaseName("ix_merchants_status");

        // EN: Ignore expression-bodied properties (EF Core can't map them)
        // EN: Repository queries use EF.Property<T>() to access backing fields directly.
        // VI: Ignore expression-bodied properties (EF Core không thể map chúng)
        // VI: Repository queries sử dụng EF.Property<T>() để truy cập backing fields trực tiếp.
        builder.Ignore(m => m.Type);
        builder.Ignore(m => m.Status);
        builder.Ignore(m => m.VerificationStatus);
        builder.Ignore(m => m.BusinessInfo);
        builder.Ignore(m => m.SettlementConfig);
        builder.Ignore(m => m.BusinessName);
        builder.Ignore(m => m.UserId);
        builder.Ignore(m => m.CreatedAt);
        builder.Ignore(m => m.UpdatedAt);
        builder.Ignore(m => m.IsDeleted);
        builder.Ignore(m => m.SubscriptionPlanId);
    }
}

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

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

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

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

        // EN: Seed data
        // VI: Dữ liệu khởi tạo
        builder.HasData(
            MerchantType.Individual,
            MerchantType.Company
        );
    }
}

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

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

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

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

        // EN: Seed data
        // VI: Dữ liệu khởi tạo
        builder.HasData(
            MerchantStatus.PendingApproval,
            MerchantStatus.Active,
            MerchantStatus.Suspended,
            MerchantStatus.Banned
        );
    }
}

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

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

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

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

        // EN: Seed data
        // VI: Dữ liệu khởi tạo
        builder.HasData(
            VerificationStatus.Unverified,
            VerificationStatus.Pending,
            VerificationStatus.Verified,
            VerificationStatus.Rejected
        );
    }
}

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

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

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

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

        // EN: Seed data
        // VI: Dữ liệu khởi tạo
        builder.HasData(
            SettlementCycle.Daily,
            SettlementCycle.Weekly,
            SettlementCycle.Monthly
        );
    }
}
