<?php

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

use App\Http\History\HistoryTables;
use App\Modules\DefinedService\CategoryDefinedService\Application\Find\FindCategoryDefinedServiceQuery;
use App\Modules\DefinedService\CategoryDefinedService\Application\Index\IndexCategoryDefinedServiceQuery;
use App\Modules\DefinedService\CategoryDefinedService\Domain\IdCategoryDefinedService;
use App\Modules\DefinedService\DefinedService\Domain\IdDefinedService;
use App\Modules\DefinedService\DefinedService\Domain\DefinedService;
use App\Modules\DefinedService\DefinedService\Domain\DefinedServiceDate;
use App\Modules\DefinedService\DefinedService\Domain\DefinedServiceDateUpdate;
use App\Modules\DefinedService\DefinedService\Domain\DefinedServiceName;
use App\Modules\DefinedService\DefinedService\Domain\DefinedServiceRepository;
use App\Modules\DefinedService\DefinedService\Domain\DefinedServiceStatus;
use App\Modules\DefinedService\DefinedService\Domain\DefinedServiceVersion;
use App\Modules\DefinedService\Route\Application\Find\FindRouteQuery;
use App\Modules\DefinedService\Route\Application\Index\IndexRouteQuery;
use App\Modules\DefinedService\Route\Domain\IdRoute;
use App\Modules\DefinedService\TypeDefinedService\Application\Find\FindTypeDefinedServiceQuery;
use App\Modules\DefinedService\TypeDefinedService\Application\Index\IndexTypeDefinedServiceQuery;
use App\Modules\DefinedService\TypeDefinedService\Domain\IdTypeDefinedService;
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\Tour\Application\Find\FindTourQuery;
use App\Modules\Tour\Domain\IdTour;
use App\Modules\TypeProvider\Application\Index\IndexTypeProviderQuery;
use App\Modules\TypeProvider\Domain\IdTypeProvider;

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

    public function __invoke(
        IdDefinedService $id,
        DefinedServiceDate $date,
        DefinedServiceDateUpdate $dateUpdate,
        DefinedServiceName $name,
        DefinedServiceVersion $version,
        DefinedServiceStatus $Status,
        IdTypeProvider $idTypeProvider,
        IdCategoryDefinedService $idCategoryDefinedService,
        IdTypeDefinedService $idTypeDefinedService,
        IdRoute $idRoute,
        IdTour $idTour,
        int $idAdmin
    ) {
        $this->queryBus->ask(new IndexTypeProviderQuery($idTypeProvider->value()));
        $this->transaction->begin();
        $this->queryBus->ask(new FindTourQuery($idTour->value(), true, true));
        $this->queryBus->ask(new FindCategoryDefinedServiceQuery($idCategoryDefinedService->value(), true, true));
        $this->queryBus->ask(new FindTypeDefinedServiceQuery($idTypeDefinedService->value(), true, true));
        $this->queryBus->ask(new FindRouteQuery($idRoute->value(), true, true));

        $model = DefinedService::create(
            $id,
            $date,
            $dateUpdate,
            $name,
            $version,
            $Status,
            $idTypeProvider,
            $idCategoryDefinedService,
            $idTypeDefinedService,
            $idRoute,
            $idTour,
        );
        $id = $this->repository->insert($model);
        $model->setId($id);
        $this->queryBus->ask(new InsertHistoryQuery(
            json_encode([]),
            json_encode([$model->toArray()]),
            HistoryOperation::INSERT,
            $id->value(),
            $id->value(),
            HistoryTables::DEFINED_SERVICE,
            $idAdmin,
        ));
        $this->transaction->commit();
        return $id->value();
    }
}
