<?php

namespace Planaday\Api\Mock;

use ArrayAccess;
use Countable;
use Planaday\Entities\Location\DTO\Location;
use Planaday\Entities\Location\Exception\LocationNotFoundException;
use Planaday\Entities\Location\LocationApi;
use Planaday\Utility\DataGrouping\Collection;
use Planaday\Utility\Debug\Log\Logging;
use Traversable;

class MockLocationApi implements LocationApi {
	use Logging;
	public LocationApi|null $locationApiMock = null;
	/** @var Collection<Location> */
	public Collection $locations;

	public function __construct() {
		$this->logInfo("MockLocationApi constructed");

		$this->locations = new Collection();
		$locations = range(1, 9);
		foreach ($locations as $locationId) {
			$this->locations->append($this->getTestLocation('l' . $locationId));
		}

		$this->logInfo("Locations added, count: " . count($this->locations));
	}

	/**
	 * @inheritDoc
	 */
	public function getLocation( string $locationId ): Location {
		if ( $this->locationApiMock !== null ) return $this->locationApiMock->getLocation( $locationId );

		$this->logInfo("MockLocationApi getting location $locationId");
		$locationId = str_replace(['l', 'c'], ['',''], $locationId);
		if (isset($this->locations[$locationId - 1])) {
			return $this->locations[$locationId - 1];
		}

		throw new LocationNotFoundException("Location with ID $locationId not found");
	}

	public function getTestLocation(string $locationId): Location {
		return (new Location($locationId))
			->setName("Test Locatie $locationId")
			->setCode("Test$locationId")
			->setStreet1("Test Straat $locationId")
			->setHouseNumber("$locationId")
			->setZipcode("1234AB")
			->setCity("Test Stad $locationId")
			->setCountry("Test Land $locationId")
			->setLat("1234567890")
			->setLng("1234567890")
			->setPhoneNumber("+31 123456789")
			->setEmail("test@test.nl")
			->setWebsite("test.nl")
			->setDescription("Dit is een test locatie (id: $locationId), deze wordt weergeven omdat er nog geen koppeling is gemaakt met planaday.")
			->setCapacity(10);
	}

	public function getLocations( Countable&Traversable&ArrayAccess $locationIds ): ArrayAccess&Traversable&Countable {
		if ( $this->locationApiMock !== null ) return $this->locationApiMock->getLocations( $locationIds );

		$locations = [];

		$this->logInfo("MockLocationApi getting locations " . implode(", ", [...$locationIds]));
		foreach ($locationIds as $locationId) {
			$locations[] = $this->getLocation($locationId);
		}
		$this->logInfo("MockLocationApi returning " . count($locations) . " locations");

		return Collection::fromArray($locations);
	}
}