// ============================================================
// SERVICE TEMPLATE
// Generated by MORPH Framework
// ============================================================

using Microsoft.Extensions.Logging;

namespace MyProject.Application.Features.{Feature}.Services;

/// <summary>
/// Service for managing {Feature} operations.
/// </summary>
public class {Feature}Service(
    I{Feature}Repository repository,
    ILogger<{Feature}Service> logger) : I{Feature}Service
{
    /// <inheritdoc />
    public async Task<{Feature}Dto?> GetByIdAsync(int id, CancellationToken cancellationToken = default)
    {
        logger.LogDebug("Getting {Feature} with ID {Id}", id);

        var entity = await repository.GetByIdAsync(id, cancellationToken);
        if (entity is null)
        {
            logger.LogWarning("{Feature} with ID {Id} not found", id);
            return null;
        }

        return MapToDto(entity);
    }

    /// <inheritdoc />
    public async Task<List<{Feature}Dto>> GetAllAsync(CancellationToken cancellationToken = default)
    {
        logger.LogDebug("Getting all {Feature}s");

        var entities = await repository.GetAllAsync(cancellationToken);
        return entities.Select(MapToDto).ToList();
    }

    /// <inheritdoc />
    public async Task<{Feature}Dto> CreateAsync(
        Create{Feature}Request request,
        CancellationToken cancellationToken = default)
    {
        logger.LogInformation("Creating new {Feature}: {Name}", request.Name);

        // Validate
        await ValidateCreateAsync(request, cancellationToken);

        // Create entity
        var entity = Domain.Entities.{Feature}.Create(request.Name);

        // Save
        await repository.AddAsync(entity, cancellationToken);
        await repository.SaveChangesAsync(cancellationToken);

        logger.LogInformation("Created {Feature} with ID {Id}", entity.Id);

        return MapToDto(entity);
    }

    /// <inheritdoc />
    public async Task UpdateAsync(
        int id,
        Update{Feature}Request request,
        CancellationToken cancellationToken = default)
    {
        logger.LogInformation("Updating {Feature} {Id}", id);

        var entity = await repository.GetByIdAsync(id, cancellationToken)
            ?? throw new {Feature}NotFoundException(id);

        // Validate
        await ValidateUpdateAsync(entity, request, cancellationToken);

        // Update entity
        entity.UpdateName(request.Name);

        // Save
        repository.Update(entity);
        await repository.SaveChangesAsync(cancellationToken);

        logger.LogInformation("Updated {Feature} {Id}", id);
    }

    /// <inheritdoc />
    public async Task DeleteAsync(int id, CancellationToken cancellationToken = default)
    {
        logger.LogInformation("Deleting {Feature} {Id}", id);

        var entity = await repository.GetByIdAsync(id, cancellationToken)
            ?? throw new {Feature}NotFoundException(id);

        // Soft delete or remove
        repository.Remove(entity);
        await repository.SaveChangesAsync(cancellationToken);

        logger.LogInformation("Deleted {Feature} {Id}", id);
    }

    #region Private Methods

    private static {Feature}Dto MapToDto(Domain.Entities.{Feature} entity)
    {
        return new {Feature}Dto(
            entity.Id,
            entity.Name,
            entity.Status,
            entity.CreatedAt,
            entity.UpdatedAt
        );
    }

    private async Task ValidateCreateAsync(
        Create{Feature}Request request,
        CancellationToken cancellationToken)
    {
        // Add validation logic here
        // Example: Check for duplicates
        // var existing = await repository.FindByNameAsync(request.Name, cancellationToken);
        // if (existing is not null)
        //     throw new ValidationException("Name already exists");

        await Task.CompletedTask;
    }

    private async Task ValidateUpdateAsync(
        Domain.Entities.{Feature} entity,
        Update{Feature}Request request,
        CancellationToken cancellationToken)
    {
        // Add validation logic here

        await Task.CompletedTask;
    }

    #endregion
}
