using System;
using System.ComponentModel.DataAnnotations;
using SmartStack.Domain.Common;
using SmartStack.Domain.Common.Interfaces;

namespace {{namespace}};

/// <summary>
/// {{name}} entity{{#if baseEntity}} extending {{baseEntity}}{{/if}}
/// </summary>
{{#if isSystemEntity}}
public class {{name}} : SystemEntity
{{else}}
public class {{name}} : BaseEntity
{{/if}}
{
{{#if baseEntity}}
    /// <summary>
    /// Foreign key to {{baseEntity}}
    /// </summary>
    public Guid {{baseEntity}}Id { get; private set; }

    /// <summary>
    /// Navigation property to {{baseEntity}}
    /// </summary>
    public virtual {{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 isSystemEntity}}
    public static {{name}} Create(
        string code,
        string? createdBy = null)
    {
        return new {{name}}
        {
            Id = Guid.NewGuid(),
            Code = code.ToLowerInvariant(),
            CreatedAt = DateTime.UtcNow,
            CreatedBy = createdBy
        };
    }
{{else}}
    public static {{name}} Create(
        Guid tenantId,
        string code,
        string? createdBy = null)
    {
        return new {{name}}
        {
            Id = Guid.NewGuid(),
            TenantId = tenantId,
            Code = code.ToLowerInvariant(),
            CreatedAt = DateTime.UtcNow,
            CreatedBy = createdBy
        };
    }
{{/if}}

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

    /// <summary>
    /// Soft delete the entity
    /// </summary>
    public void SoftDelete(string? deletedBy = null)
    {
        IsDeleted = true;
        DeletedAt = DateTime.UtcNow;
        DeletedBy = deletedBy;
    }

    /// <summary>
    /// Restore a soft-deleted entity
    /// </summary>
    public void Restore(string? restoredBy = null)
    {
        IsDeleted = false;
        DeletedAt = null;
        DeletedBy = null;
        UpdatedAt = DateTime.UtcNow;
        UpdatedBy = restoredBy;
    }
}

// ============================================================================
// Base Entity Classes (SmartStack.Domain.Common)
// ============================================================================
/*
/// <summary>
/// Base entity for tenant-scoped entities (default)
/// </summary>
public abstract class BaseEntity : ITenantEntity, IHasCode, ISoftDeletable, IVersioned
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public Guid TenantId { get; set; }

    private string _code = string.Empty;
    public string Code
    {
        get => _code;
        set => _code = value?.ToLowerInvariant() ?? string.Empty;
    }

    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public DateTime? UpdatedAt { get; set; }
    public string? CreatedBy { get; set; }
    public string? UpdatedBy { get; set; }

    public bool IsDeleted { get; set; }
    public DateTime? DeletedAt { get; set; }
    public string? DeletedBy { get; set; }

    public byte[] RowVersion { get; set; } = Array.Empty<byte>();
}

/// <summary>
/// Base entity for system-wide entities (no tenant isolation)
/// </summary>
public abstract class SystemEntity : ISystemEntity, IHasCode, ISoftDeletable, IVersioned
{
    public Guid Id { get; set; } = Guid.NewGuid();

    private string _code = string.Empty;
    public string Code
    {
        get => _code;
        set => _code = value?.ToLowerInvariant() ?? string.Empty;
    }

    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public DateTime? UpdatedAt { get; set; }
    public string? CreatedBy { get; set; }
    public string? UpdatedBy { get; set; }

    public bool IsDeleted { get; set; }
    public DateTime? DeletedAt { get; set; }
    public string? DeletedBy { get; set; }

    public byte[] RowVersion { get; set; } = Array.Empty<byte>();
}
*/

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

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

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

        // Primary key
        builder.HasKey(e => e.Id);

{{#unless isSystemEntity}}
        // Multi-tenant
        builder.Property(e => e.TenantId).IsRequired();
        builder.HasIndex(e => e.TenantId);

        // Code: lowercase, unique per tenant (filtered for soft delete)
        builder.Property(e => e.Code).HasMaxLength(100).IsRequired();
        builder.HasIndex(e => new { e.TenantId, e.Code })
            .IsUnique()
            .HasFilter("[IsDeleted] = 0")
            .HasDatabaseName("IX_{{tablePrefix}}{{name}}s_Tenant_Code_Unique");
{{else}}
        // Code: lowercase, unique (filtered for soft delete)
        builder.Property(e => e.Code).HasMaxLength(100).IsRequired();
        builder.HasIndex(e => e.Code)
            .IsUnique()
            .HasFilter("[IsDeleted] = 0")
            .HasDatabaseName("IX_{{tablePrefix}}{{name}}s_Code_Unique");
{{/unless}}

        // Concurrency token
        builder.Property(e => e.RowVersion).IsRowVersion();

        // Audit fields
        builder.Property(e => e.CreatedBy).HasMaxLength(256);
        builder.Property(e => e.UpdatedBy).HasMaxLength(256);
        builder.Property(e => e.DeletedBy).HasMaxLength(256);

{{#if baseEntity}}
        // Relationship to {{baseEntity}} (1:1)
        builder.HasOne(e => e.{{baseEntity}})
               .WithOne()
               .HasForeignKey<{{name}}>(e => e.{{baseEntity}}Id)
               .OnDelete(DeleteBehavior.Cascade);

        // Index on foreign key
        builder.HasIndex(e => e.{{baseEntity}}Id)
               .IsUnique();
{{/if}}

        // TODO: Add additional configuration
    }
}

// ============================================================================
// DbContext Update (add to ApplicationDbContext.cs)
// ============================================================================
// public DbSet<{{name}}> {{name}}s => Set<{{name}}>();

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