<?php

namespace App\Modules\BookingEquipment\Application\UpdatePartial;

use App\Modules\BookingEquipment\Application\Index\BookingEquipmentIndexer;
use App\Modules\BookingEquipment\Domain\BookingEquipment;
use App\Modules\BookingEquipment\Domain\BookingEquipmentIncluded;
use App\Modules\BookingEquipment\Domain\BookingEquipmentMode;
use App\Modules\BookingEquipment\Domain\BookingEquipmentShow;
use App\Modules\BookingEquipment\Domain\IdBookingEquipment;
use App\Modules\Shared\Domain\Aggregate\AggregateRoot;
use App\Modules\Shared\Domain\Bus\Query\QueryHandler;

final class UpdatePartialBookingEquipmentQueryHandler implements QueryHandler
{
    public function __construct(
        private BookingEquipmentIndexer $indexer,
        private BookingEquipmentPartialUpdater $updater
    ) {}

    private function conditionalSet($condition, AggregateRoot &$aggregateRoot, $setter, $object)
    {
        if (isset($condition)) {
            $aggregateRoot->$setter(new $object($condition));
        }
    }

    public function __invoke(UpdatePartialBookingEquipmentQuery $query): UpdatePartialBookingEquipmentResponse
    {
        /** @var BookingEquipment $index */
        $index = $this->indexer->__invoke(new IdBookingEquipment($query->id));

        $set = [
            [$query->show, $index, 'setShow', BookingEquipmentShow::class],
            [$query->included, $index, 'setIncluded', BookingEquipmentIncluded::class],
            [$query->mode, $index, 'setMode', BookingEquipmentMode::class],
        ];

        foreach ($set as $value) {
            $this->conditionalSet($value[0], $value[1], $value[2], $value[3]);
        }

        return new UpdatePartialBookingEquipmentResponse(
            $this->updater->__invoke($index)
        );
    }
}
