<?php

namespace App\Modules\BookingTour\Application\Update;

use App\Modules\Booking\Domain\IdBooking;
use App\Modules\BookingTour\Application\BookingTourResponse;
use App\Modules\BookingTour\Domain\IdBookingTour;
use App\Modules\BookingTour\Application\Index\BookingTourIndexer;
use App\Modules\BookingTour\Application\Index\IndexBookingTourResponse;
use App\Modules\BookingTour\Domain\BookingTour;
use App\Modules\BookingTour\Domain\BookingTourDate;
use App\Modules\BookingTour\Domain\BookingTourDateBriefing;
use App\Modules\BookingTour\Domain\BookingTourDateStart;
use App\Modules\BookingTour\Domain\BookingTourFeeType;
use App\Modules\BookingTour\Domain\BookingTourFull;
use App\Modules\BookingTour\Domain\BookingTourGroup;
use App\Modules\BookingTour\Domain\BookingTourMinimumFull;
use App\Modules\BookingTour\Domain\BookingTourModel;
use App\Modules\BookingTour\Domain\BookingTourName;
use App\Modules\BookingTour\Domain\BookingTourNoPax;
use App\Modules\BookingTour\Domain\BookingTourPickUp;
use App\Modules\BookingTour\Domain\BookingTourPlaceBriefing;
use App\Modules\BookingTour\Domain\BookingTourStatus;
use App\Modules\BookingTour\Domain\BookingTourTourDuration;
use App\Modules\BookingTour\Domain\BookingTourTourName;
use App\Modules\BookingTour\Domain\BookingTourType;
use App\Modules\BookingTour\Domain\BookingTourUseBookingPlaceBriefing;
use App\Modules\LodgingPlace\Domain\IdLodgingPlace;
use App\Modules\Package\Domain\IdPackage;
use App\Modules\Shared\Domain\Aggregate\AggregateRoot;
use App\Modules\Shared\Domain\Bus\Query\QueryHandler;
use App\Modules\Tour\Domain\IdTour;

final class UpdateBookingTourQueryHandler implements QueryHandler
{
    public function __construct(
        private BookingTourUpdater $updater,
        private BookingTourIndexer $indexer,
    ) {}

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

    public function __invoke(UpdateBookingTourQuery $query): UpdateBookingTourQueryResponse
    {
        /** @var BookingTour $model */
        $model = $this->indexer->__invoke(new IdBookingTour($query->id));
        // /** @var BookingTourResponse $response */
        // $response = $this->indexer->__invoke(new IdBookingTour($query->id));
        // $model = BookingTourUpdateDTO::validateData($response);
        // $model = new BookingTourModel();
        // $model->fill($response);
        // $model = new BookingTourModel([
        //     // ...
        // ]); 
        $responseData = $model;
        $model = new BookingTourModel(
            new IdBookingTour($responseData->id()->value()),
            new BookingTourDate($responseData->date()->value()),
            new BookingTourDateStart($responseData->dateStart()->value()),
            new BookingTourPickUp($responseData->pickUp()->value()),
            new BookingTourType($responseData->type()->value()),
            new BookingTourNoPax($responseData->noPax()->value()),
            new BookingTourName($responseData->name()->value()),
            new BookingTourTourName($responseData->tourName()->value()),
            new BookingTourFeeType($responseData->feeType()->value()),
            new BookingTourFull($responseData->full()->value()),
            new BookingTourMinimumFull($responseData->minimumFull()->value()),
            new BookingTourGroup($responseData->group()->value()),
            new BookingTourTourDuration($responseData->tourDuration()->value()),
            new BookingTourDateBriefing($responseData->dateBriefing()->value()),
            new BookingTourPlaceBriefing($responseData->placeBriefing()->value()),
            new BookingTourUseBookingPlaceBriefing($responseData->useBookingPlaceBriefing()->value()),
            new BookingTourStatus($responseData->status()->value()),
            new IdBooking($responseData->idBooking()->value()),
            new IdPackage($responseData->idPackage()->value()),
            new IdTour($responseData->idTour()->value()),
            new IdLodgingPlace($responseData->idLodgingPlacePickUp()->value()),
            new IdLodgingPlace($responseData->idLodgingPlaceDropOff()->value()),
        );
        // dd($model);

        // ---------aquí todos los campos que se van a llenar con el response
        // --------------------------------------------------------------------------
        // $model = new FactTypeDocument(
        //     new IdFactTypeDocument($query->getId()),
        //     new FactTypeDocumentName($query->getName()),
        //     new FactTypeDocumentAbrv($query->getAbrv()),
        //     new FactTypeDocumentStatus($query->getStatus()),
        // );
        $set = [
            [$query->idLodgingPlacePickUp, $model, 'setIdLodgingPlacePickUp', IdLodgingPlace::class],
            [$query->idLodgingPlaceDropOff, $model, 'setIdLodgingPlaceDropOff', IdLodgingPlace::class],
            // [$query->idAdmin, $model, 'setIdAdmin', IdAdmin::class],
        ];
        foreach ($set as $value) {
            $this->conditionalSet($value[0], $value[1], $value[2], $value[3]);
        }

        return $this->updater->__invoke(
            $model,
        );
    }
}
