<?php

declare(strict_types=1);

namespace Modules\{{ Module }}\Services;

use App\Foundation\Service\InteractsWithTransactions;
use Modules\{{ Module }}\Contracts\{{ Entity }}RepositoryInterface;
use Modules\{{ Module }}\Contracts\{{ Entity }}ServiceInterface;
use Modules\{{ Module }}\DTOs\{{ Entity }}Data;
use Modules\{{ Module }}\Events\{{ Entity }}Created;
use Modules\{{ Module }}\Models\{{ Entity }};

/**
 * Every business rule for {{ Module }} lives here.
 *
 * Controllers coordinate; this class decides. That is what lets the web UI, the
 * REST API, an Artisan command and a queued job all drive the same behaviour.
 */
final readonly class {{ Entity }}Service implements {{ Entity }}ServiceInterface
{
    use InteractsWithTransactions;

    public function __construct(
        private {{ Entity }}RepositoryInterface $repository,
    ) {}

    public function create({{ Entity }}Data $data): {{ Entity }}
    {
        ${{ entity }} = $this->transaction(
            fn (): {{ Entity }} => $this->repository->create($data->toArray()),
        );

        $this->dispatchAfterCommit(new {{ Entity }}Created(${{ entity }}->id, ${{ entity }}->ulid));

        return ${{ entity }};
    }

    public function update({{ Entity }} ${{ entity }}, {{ Entity }}Data $data): {{ Entity }}
    {
        return $this->transaction(
            fn (): {{ Entity }} => $this->repository->update(${{ entity }}, $data->toFilledArray()),
        );
    }

    public function delete({{ Entity }} ${{ entity }}): void
    {
        $this->transaction(function () use (${{ entity }}): void {
            $this->repository->delete(${{ entity }});
        });
    }
}
