using System;
using SmartStack.Domain.Common;

namespace {{namespace}};

/// <summary>
/// {{name}} entity{{#if baseEntity}} extending {{baseEntity}}{{/if}}
{{#if isStrict}}
/// Tenant-scoped: data is isolated per tenant (ITenantEntity)
{{else if isOptional}}
/// Cross-tenant: data can be shared across tenants or tenant-specific (IOptionalTenantEntity)
{{else if isScoped}}
/// Scoped: data visibility controlled by EntityScope (IScopedTenantEntity)
{{else}}
/// Platform-level entity: no tenant isolation
{{/if}}
/// </summary>
{{#if isStrict}}
public class {{name}} : BaseEntity, ITenantEntity, IAuditableEntity
{{else if isOptional}}
public class {{name}} : BaseEntity, IOptionalTenantEntity, IAuditableEntity
{{else if isScoped}}
public class {{name}} : BaseEntity, IScopedTenantEntity, IAuditableEntity
{{else}}
public class {{name}} : BaseEntity, IAuditableEntity
{{/if}}
{
{{#if hasTenantId}}
    // === MULTI-TENANT ===

{{#if isNullableTenant}}
    /// <summary>
    /// Tenant identifier — null means shared across all tenants
    /// </summary>
    public Guid? TenantId { get; private set; }
{{else}}
    /// <summary>
    /// Tenant identifier for multi-tenant isolation (required)
    /// </summary>
    public Guid TenantId { get; private set; }
{{/if}}

{{/if}}
{{#if hasScope}}
    /// <summary>
    /// Visibility scope: Tenant (tenant-specific), Shared (all tenants), Platform (admin only)
    /// </summary>
    public EntityScope Scope { get; private set; }

{{/if}}
    // === AUDIT ===

    /// <summary>User who created this entity</summary>
    public string? CreatedBy { get; set; }

    /// <summary>User who last updated this entity</summary>
    public string? UpdatedBy { get; set; }

{{#if baseEntity}}
    // === RELATIONSHIPS ===

    /// <summary>
    /// Foreign key to {{baseEntity}}
    /// </summary>
    public Guid {{baseEntity}}Id { get; private set; }

    /// <summary>
    /// Navigation property to {{baseEntity}}
    /// </summary>
    public {{baseEntity}}? {{baseEntity}} { get; private set; }

{{/if}}
    // === BUSINESS PROPERTIES ===
    // TODO: Add {{name}} specific properties here

    /// <summary>
    /// Private constructor for EF Core
    /// </summary>
    private {{name}}() { }

    /// <summary>
    /// Factory method to create a new {{name}}
    /// </summary>
{{#if isStrict}}
    /// <param name="tenantId">Required tenant identifier</param>
    public static {{name}} Create(
        Guid tenantId,
        string? createdBy = null)
    {
        if (tenantId == Guid.Empty)
            throw new ArgumentException("TenantId is required", nameof(tenantId));

        return new {{name}}
        {
            Id = Guid.NewGuid(),
            TenantId = tenantId,
            CreatedAt = DateTime.UtcNow,
            CreatedBy = createdBy
        };
    }
{{else if isOptional}}
    /// <param name="tenantId">Tenant identifier — null for shared (cross-tenant) data</param>
    public static {{name}} Create(
        Guid? tenantId = null,
        string? createdBy = null)
    {
        return new {{name}}
        {
            Id = Guid.NewGuid(),
            TenantId = tenantId,
            CreatedAt = DateTime.UtcNow,
            CreatedBy = createdBy
        };
    }
{{else if isScoped}}
    /// <param name="tenantId">Tenant identifier — null for shared/platform data</param>
    /// <param name="scope">Visibility scope (default: Tenant)</param>
    public static {{name}} Create(
        Guid? tenantId = null,
        EntityScope scope = EntityScope.Tenant,
        string? createdBy = null)
    {
        if (scope == EntityScope.Tenant && tenantId == null)
            throw new ArgumentException("TenantId is required when scope is Tenant", nameof(tenantId));

        return new {{name}}
        {
            Id = Guid.NewGuid(),
            TenantId = tenantId,
            Scope = scope,
            CreatedAt = DateTime.UtcNow,
            CreatedBy = createdBy
        };
    }
{{else}}
    public static {{name}} Create(
        string? createdBy = null)
    {
        return new {{name}}
        {
            Id = Guid.NewGuid(),
            CreatedAt = DateTime.UtcNow,
            CreatedBy = createdBy
        };
    }
{{/if}}

    /// <summary>
    /// Update the entity
    /// </summary>
    public void Update(string? updatedBy = null)
    {
        UpdatedAt = DateTime.UtcNow;
        UpdatedBy = updatedBy;
    }
}

// ============================================================================
// Base Entity Classes (SmartStack.Domain.Common) — Reference Only
// ============================================================================
/*
BaseEntity:   Id (Guid), CreatedAt (DateTime), UpdatedAt (DateTime?)
ITenantEntity:        TenantId (Guid)           — strict tenant isolation
IOptionalTenantEntity: TenantId (Guid?)          — cross-tenant shared data (null = shared)
IScopedTenantEntity:  TenantId (Guid?) + Scope  — with EntityScope (Tenant/Shared/Platform)
IAuditableEntity:     CreatedBy (string?), UpdatedBy (string?)
*/

// ============================================================================
// EF Core Configuration
// ============================================================================
namespace {{infrastructureNamespace}}.Persistence.Configurations{{#if configNamespaceSuffix}}.{{configNamespaceSuffix}}{{/if}};

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using {{domainNamespace}};

public class {{name}}Configuration : IEntityTypeConfiguration<{{name}}>
{
    public void Configure(EntityTypeBuilder<{{name}}> builder)
    {
        builder.ToTable("{{tablePrefix}}{{name}}s", "{{schema}}");

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

{{#if isStrict}}
        // Multi-tenant (strict: TenantId required)
        builder.Property(e => e.TenantId).IsRequired();
        builder.HasIndex(e => e.TenantId)
            .HasDatabaseName("IX_{{tablePrefix}}{{name}}s_TenantId");

{{else if isOptional}}
        // Multi-tenant (optional: TenantId nullable — null = shared across tenants)
        builder.Property(e => e.TenantId).IsRequired(false);
        builder.HasIndex(e => e.TenantId)
            .HasDatabaseName("IX_{{tablePrefix}}{{name}}s_TenantId");

{{else if isScoped}}
        // Multi-tenant (scoped: TenantId nullable + EntityScope)
        builder.Property(e => e.TenantId).IsRequired(false);
        builder.HasIndex(e => e.TenantId)
            .HasDatabaseName("IX_{{tablePrefix}}{{name}}s_TenantId");

        builder.Property(e => e.Scope)
            .IsRequired()
            .HasConversion<string>()
            .HasMaxLength(20);
        builder.HasIndex(e => new { e.TenantId, e.Scope })
            .HasDatabaseName("IX_{{tablePrefix}}{{name}}s_TenantId_Scope");

{{/if}}
        // Audit fields (from IAuditableEntity)
        builder.Property(e => e.CreatedBy).HasMaxLength(256);
        builder.Property(e => e.UpdatedBy).HasMaxLength(256);

{{#if baseEntity}}
        // Relationship to {{baseEntity}}
        builder.HasOne(e => e.{{baseEntity}})
               .WithMany()
               .HasForeignKey(e => e.{{baseEntity}}Id)
               .OnDelete(DeleteBehavior.Restrict);

        builder.HasIndex(e => e.{{baseEntity}}Id)
               .HasDatabaseName("IX_{{tablePrefix}}{{name}}s_{{baseEntity}}Id");
{{/if}}

        // TODO: Add business property configurations (HasMaxLength, IsRequired, indexes)
    }
}

// ============================================================================
// DbContext Update (add to your DbContext interface + implementation)
// ============================================================================
// public DbSet<{{name}}> {{name}}s => Set<{{name}}>();

// ============================================================================
// Migration Command
// ============================================================================
// dotnet ef migrations add core_vX.X.X_XXX_Add{{name}} --context CoreDbContext
