<?php

namespace App\Modules\CategoryProvider\Application\Insert;

use App\Http\History\HistoryTables;
use App\Modules\CategoryProvider\Domain\CategoryProvider;
use App\Modules\CategoryProvider\Domain\CategoryProviderLevel;
use App\Modules\CategoryProvider\Domain\CategoryProviderLevelRepository;
use App\Modules\CategoryProvider\Domain\CategoryProviderRepository;
use App\Modules\CategoryProvider\Domain\NextCategoryProviderLevel;
use App\Modules\History\Application\Insert\InsertHistoryQuery;
use App\Modules\History\Domain\HistoryOperation;
use App\Modules\Shared\Domain\Bus\Query\QueryBus;
use App\Modules\Shared\Domain\Transaction;
use App\Modules\TypeProvider\Application\Find\FindTypeProviderQuery;

final class CategoryProviderInserter
{
    public function __construct(
        private CategoryProviderRepository $repository,
        private CategoryProviderLevelRepository $repositoryLevel,
        private QueryBus $queryBus,
        private Transaction $transaction
    ) {}

    public function __invoke(
        CategoryProvider $model,
        int $idAdmin
    ) {
        $this->transaction->begin();
        $this->queryBus->ask(new FindTypeProviderQuery($model->idTypeProvider()->value(), true, true));

        $nextLevel = $this->repository->find(new NextCategoryProviderLevel($model->idTypeProvider()));
        $model->setLevel(new CategoryProviderLevel(min($model->level()->value(), $nextLevel->value())));
        $this->repositoryLevel->makeSpace($model->idTypeProvider(), $model->level());
        $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::CATEGORY_PROVIDER,
            $idAdmin,
        ));
        $this->transaction->commit();
        return $id->value();
    }
}
