modules/backend/Write-DomainLayer.ps1

param(
    [string]$ProjectName,
    [string]$OrmMode,
    [string]$OutputPath,
    [string[]]$Entities
)

. (Join-Path (Split-Path $MyInvocation.MyCommand.Path) "..\core\Utils.ps1")

$base = Join-Path $OutputPath "src\$ProjectName.Domain"

function Write-File($rel, $con) { Write-CoreFile (Join-Path $base $rel) $con }
function T($template, $e = "") {
    $res = $template.Replace("{P}", $ProjectName)
    if ($e) { $res = $res.Replace("{E}", $e) }
    return $res
}

# ---- BaseEntity ----
Write-File "Common\BaseEntity.cs" (T @'
namespace {P}.Domain.Common;
 
public abstract class BaseEntity
{
    public int Id { get; set; }
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
    public bool IsDeleted { get; set; } = false;
    public DateTime? DeletedAt { get; set; }
}
'@
)

# ---- PagedQuery ----
Write-File "Common\PagedQuery.cs" (T @'
namespace {P}.Domain.Common;
 
public class PagedQuery
{
    public int Page { get; set; } = 1;
    public int Size { get; set; } = 20;
    public int Skip => (Page - 1) * Size;
}
'@
)

# ---- PagedResult<T> ----
Write-File "Common\PagedResult.cs" (T @'
namespace {P}.Domain.Common;
 
public class PagedResult<T>
{
    public IEnumerable<T> Items { get; set; } = Enumerable.Empty<T>();
    public int TotalCount { get; set; }
    public int Page { get; set; }
    public int Size { get; set; }
    public int TotalPages => (int)Math.Ceiling((double)TotalCount / Size);
    public bool HasNextPage => Page < TotalPages;
    public bool HasPreviousPage => Page > 1;
}
'@
)

# ---- IRepository<T> ----
Write-File "Interfaces\IRepository.cs" (T @'
using {P}.Domain.Common;
 
namespace {P}.Domain.Interfaces;
 
public interface IRepository<T> where T : class
{
    Task<T?> GetByIdAsync(int id);
    Task<IEnumerable<T>> GetAllAsync();
    Task<PagedResult<T>> GetPagedAsync(PagedQuery query);
    Task<int> AddAsync(T entity);
    Task UpdateAsync(T entity);
    Task DeleteAsync(int id);
}
'@
)

# ---- IUnitOfWork ----
Write-File "Interfaces\IUnitOfWork.cs" (T @'
namespace {P}.Domain.Interfaces;
 
public interface IUnitOfWork : IDisposable
{
    Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
    Task BeginTransactionAsync();
    Task CommitTransactionAsync();
    Task RollbackTransactionAsync();
}
'@
)

# ---- Dinamik Entity ve Repository Üretimi ----
foreach ($e in $Entities) {
    if ($e -eq "User") {
        Write-File "Entities\User.cs" (T @'
using {P}.Domain.Common;
 
namespace {P}.Domain.Entities;
 
public class User : BaseEntity
{
    public string Username { get; set; } = string.Empty;
    public string PasswordHash { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
    public bool IsActive { get; set; } = true;
    public string Role { get; set; } = "User";
}
'@
)

        Write-File "Interfaces\IUserRepository.cs" (T @'
using {P}.Domain.Entities;
 
namespace {P}.Domain.Interfaces;
 
public interface IUserRepository
{
    Task<User?> GetByUsernameAsync(string username);
    Task<int> AddAsync(User user);
}
'@
)
    }
    else {
        # Jenerik Entity
        $extraFields = if ($e -eq "Product") { "`n public decimal Price { get; set; }" } else { "" }
        Write-File "Entities\$e.cs" (T @"
using {P}.Domain.Common;
 
namespace {P}.Domain.Entities;
 
public class {E} : BaseEntity
{
    public string Name { get; set; } = string.Empty;$extraFields
}
"@
 $e)

        # Jenerik Repository Arayüzü
        Write-File "Interfaces\I$e`Repository.cs" (T @'
 
using {P}.Domain.Entities;
 
namespace {P}.Domain.Interfaces;
 
public interface I{E}Repository : IRepository<{E}>
{
}
'@
 $e)
    }
}