using CMSMicroservice.Domain.Entities;
using CMSMicroservice.Domain.Entities.DiscountShop;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace CMSMicroservice.Infrastructure.Persistence.Configurations;

/// <summary>
/// تنظیمات Entity Framework برای موجودی کالا
/// </summary>
public class InventoryItemConfiguration : IEntityTypeConfiguration<InventoryItem>
{
    public void Configure(EntityTypeBuilder<InventoryItem> builder)
    {
        // ========== تنظیمات پایه ==========
        builder.HasQueryFilter(i => !i.IsDeleted);
        builder.Ignore(entity => entity.DomainEvents);
        builder.HasKey(entity => entity.Id);
        builder.Property(entity => entity.Id).UseIdentityColumn();
        
        // ========== فیلدهای اصلی ==========
        builder.Property(e => e.ProductType)
            .IsRequired()
            .HasConversion<int>();
        
        builder.Property(e => e.Quantity)
            .IsRequired()
            .HasDefaultValue(0);
        
        builder.Property(e => e.ReservedQuantity)
            .IsRequired()
            .HasDefaultValue(0);
        
        // ========== تنظیمات انبار ==========
        builder.Property(e => e.LowStockThreshold)
            .IsRequired()
            .HasDefaultValue(10);
        
        builder.Property(e => e.ReorderPoint)
            .IsRequired()
            .HasDefaultValue(5);
        
        builder.Property(e => e.MaxStockLevel)
            .IsRequired()
            .HasDefaultValue(1000);
        
        // ========== تاریخ‌ها ==========
        builder.Property(e => e.LastRestockedAt)
            .IsRequired(false);
        
        builder.Property(e => e.LastSoldAt)
            .IsRequired(false);
        
        // ========== انبار ==========
        builder.Property(e => e.WarehouseId)
            .IsRequired()
            .HasDefaultValue(1);
        
        // ========== روابط ==========
        
        // رابطه با Product (اختیاری)
        builder.HasOne(e => e.Product)
            .WithMany()
            .HasForeignKey(e => e.ProductId)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.Cascade);
        
        // رابطه با DiscountProduct (اختیاری)
        builder.HasOne(e => e.DiscountProduct)
            .WithMany()
            .HasForeignKey(e => e.DiscountProductId)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.Cascade);
        
        // رابطه با Warehouse
        builder.HasOne(e => e.Warehouse)
            .WithMany(w => w.InventoryItems)
            .HasForeignKey(e => e.WarehouseId)
            .IsRequired()
            .OnDelete(DeleteBehavior.Restrict);
        
        // ========== Index ها ==========
        
        // Index روی ProductId برای جستجوی سریع محصولات معمولی
        builder.HasIndex(e => e.ProductId)
            .HasDatabaseName("IX_InventoryItems_ProductId");
        
        // Index روی DiscountProductId برای جستجوی سریع محصولات تخفیفی
        builder.HasIndex(e => e.DiscountProductId)
            .HasDatabaseName("IX_InventoryItems_DiscountProductId");
        
        // Index ترکیبی روی ProductType و Quantity برای گزارش‌گیری
        builder.HasIndex(e => new { e.ProductType, e.Quantity })
            .HasDatabaseName("IX_InventoryItems_ProductType_Quantity");
        
        // Index ساده روی WarehouseId برای انبار
        builder.HasIndex(e => e.WarehouseId)
            .HasDatabaseName("IX_InventoryItems_WarehouseId");
        
        // ========== محدودیت‌ها ==========
        
        // محدودیت: یا ProductId یا DiscountProductId باید پر باشد (نه هر دو، نه هیچ‌کدام)
        builder.HasCheckConstraint("CK_InventoryItem_ProductReference", 
            "(ProductId IS NOT NULL AND DiscountProductId IS NULL) OR (ProductId IS NULL AND DiscountProductId IS NOT NULL)");
        
        // محدودیت: ProductType باید با نوع محصول مطابقت داشته باشد
        builder.HasCheckConstraint("CK_InventoryItem_ProductType_Match",
            "(ProductType = 1 AND ProductId IS NOT NULL) OR (ProductType = 2 AND DiscountProductId IS NOT NULL)");
        
        // محدودیت: موجودی نمی‌تواند منفی باشد
        builder.HasCheckConstraint("CK_InventoryItem_Quantity_NonNegative", 
            "Quantity >= 0");
        
        // محدودیت: موجودی رزرو شده نمی‌تواند منفی باشد
        builder.HasCheckConstraint("CK_InventoryItem_ReservedQuantity_NonNegative", 
            "ReservedQuantity >= 0");
        
        // محدودیت: موجودی رزرو شده نمی‌تواند بیشتر از موجودی کل باشد
        builder.HasCheckConstraint("CK_InventoryItem_ReservedQuantity_LessOrEqualQuantity", 
            "ReservedQuantity <= Quantity");
    }
}