<?php

namespace App\Modules\DefinedService\TypeDefinedService\Application\Insert;

use App\Http\History\HistoryTables;
use App\Modules\DefinedService\TypeDefinedService\Domain\IdTypeDefinedService;
use App\Modules\DefinedService\TypeDefinedService\Domain\TypeDefinedService;
use App\Modules\DefinedService\TypeDefinedService\Domain\TypeDefinedServiceCode;
use App\Modules\DefinedService\TypeDefinedService\Domain\TypeDefinedServiceDate;
use App\Modules\DefinedService\TypeDefinedService\Domain\TypeDefinedServiceDateUpdate;
use App\Modules\DefinedService\TypeDefinedService\Domain\TypeDefinedServiceName;
use App\Modules\DefinedService\TypeDefinedService\Domain\TypeDefinedServiceRepository;
use App\Modules\DefinedService\TypeDefinedService\Domain\TypeDefinedServiceStatus;
use App\Modules\DefinedService\TypeDefinedService\Domain\TypeDefinedServiceVersion;
use App\Modules\History\Application\Insert\InsertHistoryQuery;
use App\Modules\History\Domain\HistoryOperation;
use App\Modules\Shared\Domain\Bus\Event\EventBus;
use App\Modules\Shared\Domain\Bus\Query\QueryBus;
use App\Modules\Shared\Domain\Transaction;
use App\Modules\TypeProvider\Application\Index\IndexTypeProviderQuery;
use App\Modules\TypeProvider\Domain\IdTypeProvider;

final class TypeDefinedServiceInserter
{
    public function __construct(
        private TypeDefinedServiceRepository $repository,
        private EventBus $eventBus,
        private QueryBus $queryBus,
        private Transaction $transaction
    ) {}

    public function __invoke(
        IdTypeDefinedService $id,
        TypeDefinedServiceDate $date,
        TypeDefinedServiceDateUpdate $dateUpdate,
        TypeDefinedServiceName $name,
        TypeDefinedServiceCode $code,
        TypeDefinedServiceVersion $version,
        TypeDefinedServiceStatus $status,
        IdTypeProvider $idTypeProvider,
        int $idAdmin
    ) {
        $this->transaction->begin();
        $this->queryBus->ask(new IndexTypeProviderQuery($idTypeProvider->value()));
        $model = TypeDefinedService::create($id, $date, $dateUpdate, $name, $code, $version, $status, $idTypeProvider);
        $id = $this->repository->insert($model);
        $model->setId($id);
        // $model->addCreatedDomainEvent($idAdmin);
        // $this->eventBus->publishAll(...$model->pullDomainEvents());
        $this->queryBus->ask(new InsertHistoryQuery(
            json_encode([]),
            json_encode([$model->toArray()]),
            HistoryOperation::INSERT,
            $id->value(),
            $id->value(),
            HistoryTables::TYPE_DEFINED_SERVICE,
            $idAdmin,
        ));
        $this->transaction->commit();
        return $id->value();
    }
}
