<?php

namespace App\Modules\CategoryProvider\Application\Update;

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\Versioner\Application\Check\VersionChecker;

final class CategoryProviderUpdater
{
    public function __construct(
        private CategoryProviderRepository $repository,
        private VersionChecker $versionChecker,
        private CategoryProviderLevelRepository $levelRepository,
        private QueryBus $queryBus,
        private Transaction $transaction,
    ) {}

    public function __invoke(
        CategoryProvider $model,
        CategoryProviderLevel $oldLevel,
        $idAdmin
    ) {
        $this->transaction->begin();
        $model->updateVersion();

        if ($oldLevel->lt($model->level())) {
            $this->levelRepository->shiftDown($model->idTypeProvider(), $oldLevel, $model->level());
        } else if ($oldLevel->gt($model->level())) {
            $this->levelRepository->shiftUp($model->idTypeProvider(), $oldLevel, $model->level());
        }

        $update = $this->repository->updatePartial($model);
        $this->queryBus->ask(new InsertHistoryQuery(
            json_encode([]),
            json_encode([$model->toArray()]),
            HistoryOperation::UPDATE,
            $model->id()->value(),
            $model->id()->value(),
            HistoryTables::CATEGORY_PROVIDER,
            $idAdmin,
        ));
        $this->transaction->commit();
        return $update;
    }
}
