<?php

namespace App\Modules\Room\Application\ListAll;

use App\Http\Controllers\Owner\Room\RoomListOrderBy;
use App\Http\Controllers\Owner\Room\RoomListOrderType;
use App\Modules\DefinedService\Location\Domain\IdLocation;
use App\Modules\Room\Domain\ListAllRoom;
use App\Modules\Room\Domain\MainProviderFromBookingTourPassenger;
use App\Modules\Room\Domain\RoomRepository;
use App\Modules\Shared\Domain\DataUtils;
use App\Modules\Shared\Domain\DateEnd;
use App\Modules\Shared\Domain\DateStart;
use App\Providers\StorageProvider;

final class RoomAllLister
{
    public function __construct(
        private RoomRepository $repository,
        private StorageProvider $storageProvider,
    ) {}

    public function __invoke(
        string $dateStart,
        string $dateEnd,
        string $orderBy,
        string $orderType,
        array $statuses,
        array $idExtras,
        array $idProviders,
        array $locks,
        array $idCategories,
        array $idTours,
        array $idTypeRooms,
        array $UpgradeStatuses,
        bool $allStatuses,
        bool $allExtras,
        bool $allProviders,
        bool $allLocks,
        bool $allTours,
        bool $allTypeRooms,
        bool $allUpgradeStatuses,
        int $idLocation,
        ?string $search,
        ?int $page,
        ?int $limit,
        ?int $idRoom = null,
    ) {
        $criteria = new ListAllRoom(
            new DateStart($dateStart),
            new DateEnd($dateEnd),
            new RoomListOrderBy($orderBy),
            new RoomListOrderType($orderType),
            $statuses,
            $idExtras,
            $idProviders,
            $locks,
            $idCategories,
            $idTours,
            $idTypeRooms,
            $UpgradeStatuses,
            $allStatuses,
            $allExtras,
            $allProviders,
            $allLocks,
            $allTours,
            $allTypeRooms,
            $allUpgradeStatuses,
            new IdLocation($idLocation),
            $search,
            $page,
            $limit,
            $idRoom,
        );

        $listAllRoom = $this->repository->search($criteria);

        $listAllRoom = array_map([$this, 'richElement'], $listAllRoom);
        $paxList = array_reduce($listAllRoom, function ($carry, $item) {
            return array_merge($carry, $item->PassengerList);
        }, []);

        $idPaxs = array_reduce($paxList, function ($carry, $item) {
            return array_merge($carry, [$item['Id_BookingTourPassenger']]);
        }, []);

        $providers = $this->repository->search(new MainProviderFromBookingTourPassenger($idPaxs));

        foreach ($listAllRoom as $i => $room) {
            foreach ($listAllRoom[$i]->PassengerList as $j => $passenger) {
                $listAllRoom[$i]->PassengerList[$j]['Provider'] = $this->findAll($providers, $passenger['Id_BookingTourPassenger']);
            }
        }

        return $listAllRoom;
    }

    public function findAll(array $providers, int $idBookingTourPassenger)
    {
        $found = [];
        foreach ($providers as $provider) {
            if ($provider->Id === $idBookingTourPassenger) {
                $found[] = $provider;
            }
        }
        return $found;
    }

    public function richElement($element)
    {
        $element->PassengerList = DataUtils::decodeMysqlJson($element, 'PassengerList');
        $length = count($element->PassengerList);
        for ($key = 0; $key < $length; $key++) {
            $element->PassengerList[$key]['UserCountry_Img'] = $this->storageProvider->publicCountryPath($element->PassengerList[$key]['UserCountry_Img']);
        }
        return $element;
    }
}
