using Fengling.Platform.Domain.AggregatesModel.GatewayAggregate;

using Fengling.Platform.Domain.AggregatesModel.RoleAggregate;
using Fengling.Platform.Domain.AggregatesModel.TenantAggregate;
using Fengling.Platform.Domain.AggregatesModel.UserAggregate;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;


namespace Fengling.Platform.Infrastructure;


public class PlatformDbContext(DbContextOptions options)
    : IdentityDbContext<ApplicationUser, ApplicationRole, long>(options)
{
    public DbSet<Tenant> Tenants => Set<Tenant>();
    public DbSet<AccessLog> AccessLogs => Set<AccessLog>();
    public DbSet<AuditLog> AuditLogs => Set<AuditLog>();
    
    // Gateway 实体
    public DbSet<GwTenant> GwTenants => Set<GwTenant>();
    public DbSet<GwTenantRoute> GwTenantRoutes => Set<GwTenantRoute>();
    public DbSet<GwServiceInstance> GwServiceInstances => Set<GwServiceInstance>();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        if (modelBuilder is null)
        {
            throw new ArgumentNullException(nameof(modelBuilder));
        }

        modelBuilder.Entity<ApplicationUser>(entity =>
        {
            entity.Property(e => e.PhoneNumber).HasMaxLength(20);
            entity.HasIndex(e => e.PhoneNumber).IsUnique();

            entity.OwnsOne(e => e.TenantInfo, navigationBuilder =>
            {
                navigationBuilder.Property(t => t.TenantCode).HasColumnName("TenantCode");
                navigationBuilder.Property(t => t.TenantId).HasColumnName("TenantId");
                navigationBuilder.Property(t => t.TenantName).HasColumnName("TenantName");
                navigationBuilder.WithOwner();
            });
        });

        modelBuilder.Entity<ApplicationRole>(entity =>
        {
            entity.Property(e => e.Description).HasMaxLength(200);
        });

        modelBuilder.Entity<AccessLog>(entity =>
        {
            entity.HasKey(e => e.Id);
            entity.HasIndex(e => e.CreatedAt);
            entity.HasIndex(e => e.UserName);
            entity.HasIndex(e => e.TenantId);
            entity.HasIndex(e => e.Action);
            entity.HasIndex(e => e.Status);
            entity.Property(e => e.UserName).HasMaxLength(50);
            entity.Property(e => e.TenantId).HasMaxLength(50);
            entity.Property(e => e.Action).HasMaxLength(20);
            entity.Property(e => e.Resource).HasMaxLength(200);
            entity.Property(e => e.Method).HasMaxLength(10);
            entity.Property(e => e.IpAddress).HasMaxLength(50);
            entity.Property(e => e.UserAgent).HasMaxLength(500);
            entity.Property(e => e.Status).HasMaxLength(20);
        });

        modelBuilder.Entity<AuditLog>(entity =>
        {
            entity.HasKey(e => e.Id);
            entity.HasIndex(e => e.CreatedAt);
            entity.HasIndex(e => e.Operator);
            entity.HasIndex(e => e.TenantId);
            entity.HasIndex(e => e.Operation);
            entity.HasIndex(e => e.Action);
            entity.Property(e => e.Operator).HasMaxLength(50);
            entity.Property(e => e.TenantId).HasMaxLength(50);
            entity.Property(e => e.Operation).HasMaxLength(20);
            entity.Property(e => e.Action).HasMaxLength(20);
            entity.Property(e => e.TargetType).HasMaxLength(50);
            entity.Property(e => e.TargetName).HasMaxLength(100);
            entity.Property(e => e.IpAddress).HasMaxLength(50);
            entity.Property(e => e.Description).HasMaxLength(500);
            entity.Property(e => e.Status).HasMaxLength(20);
        });

        // Gateway 实体配置
        modelBuilder.Entity<GwTenant>(entity =>
        {
            entity.HasKey(e => e.Id);
            entity.Property(e => e.TenantCode).HasMaxLength(50).IsRequired();
            entity.Property(e => e.TenantName).HasMaxLength(100).IsRequired();
            entity.HasIndex(e => e.TenantCode).IsUnique();
        });

        modelBuilder.Entity<GwTenantRoute>(entity =>
        {
            entity.HasKey(e => e.Id);
            entity.Property(e => e.TenantCode).HasMaxLength(50);
            entity.Property(e => e.ServiceName).HasMaxLength(100).IsRequired();
            entity.Property(e => e.ClusterId).HasMaxLength(100).IsRequired();
            entity.Property(e => e.PathPattern).HasMaxLength(200).IsRequired();
            entity.HasIndex(e => e.TenantCode);
            entity.HasIndex(e => e.ServiceName);
            entity.HasIndex(e => e.ClusterId);
            entity.HasIndex(e => new { e.ServiceName, e.IsGlobal, e.Status });
        });

        modelBuilder.Entity<GwServiceInstance>(entity =>
        {
            entity.HasKey(e => e.Id);
            entity.Property(e => e.ClusterId).HasMaxLength(100).IsRequired();
            entity.Property(e => e.DestinationId).HasMaxLength(100).IsRequired();
            entity.Property(e => e.Address).HasMaxLength(200).IsRequired();
            entity.HasIndex(e => new { e.ClusterId, e.DestinationId }).IsUnique();
            entity.HasIndex(e => e.Health);
        });

        modelBuilder.ApplyConfigurationsFromAssembly(typeof(PlatformDbContext).Assembly);
        base.OnModelCreating(modelBuilder);
    }
}
