<?php

namespace Planaday\Html\NodeTags\DayPart\ListItem;

use Planaday\Api\ApiException\InvalidResponseException;
use Planaday\Api\Mock\MockDayPartApi;
use Planaday\Config\Course\General\GeneralSettings;
use Planaday\Entities\DayPart\DTO\DayPart;
use Planaday\Entities\DayPart\Exception\DayPartNotFoundException;
use Planaday\Entities\Location\Exception\LocationNotFoundException;
use Planaday\Entities\Location\LocationController;
use Planaday\Html\Nodes\NodeData;
use Planaday\Html\NodeTags\Tag;
use Planaday\Html\NodeTags\TemplateOnlyTag;
use Planaday\Html\Parsers\NodeParsers\TagMarkers\TestDataTag;
use Planaday\Utility\DependencyInjection\Attributes\Transient;

#[Transient]
class ListItem implements Tag, TestDataTag{
	use TemplateOnlyTag;

	public function __construct(
		protected LocationController $locationController,
		protected MockDayPartApi $mockDayPartApi,
		protected DayPartListItemSettings $listItemSettings,
		protected GeneralSettings $generalSettings
	) {
		$this->config = [
			"showLabels"         => $this->listItemSettings->isShowLabels( ... ),
			"showLocation"       => $this->listItemSettings->isShowLocation( ... ),
			"showELearning"      => $this->generalSettings->isIncludeELearningDayParts( ... ),
			"showIcons"          => $this->listItemSettings->isShowIcons( ... ),
			"showDescription"    => $this->listItemSettings->isShowDescription( ... ),
			"showELearningLabel" => $this->listItemSettings->isShowELearningLabel( ... ),
			"locationTemplate"   => $this->listItemSettings->getLocationTemplate( ... ),
		];
	}

	public function injectTestData(): void {
		try {
			$this->attributes["day-part"] = $this->mockDayPartApi->getDayPart( 1 );
		} catch ( InvalidResponseException|DayPartNotFoundException ) {
			return;
		}
	}

	protected function prepareData( NodeData $nodeData ): void {
		$dayPart = $this->attributes["day-part"] ?? $nodeData->data["dayPart"] ?? null;
		$nodeData->data["dayPart"] = $dayPart;

		if ( ! $dayPart instanceof DayPart || $dayPart->isELearning() ) { return; }

		$locationId = $dayPart->getLocationIds()[0] ?? null;
		if ( $locationId == null || $locationId == '' || $locationId == 0 ) {return;}

		$nodeData->data["validStartDate"] = fn () => $dayPart->getStartTime()->format('Y') !== '1970';

		$nodeData->data["location"] = function () use ($locationId) {
			try {
				$location = $this->locationController->getLocation($locationId);
				$this->logDebug( "Location found: " . $location->getName() );
				return $location;
			} catch ( InvalidResponseException|LocationNotFoundException $e ) {
				$this->logWarning( "Location not found: " . $e->getMessage() );
				return null;
			}
		};

		$nodeData->data["locationTemplateData"] = function () use ($locationId) {
			try {
				$location = $this->locationController->getLocation($locationId);
				$this->logDebug( "Location found: " . $location->getName() );
				return [
					"name" => $location->getName(),
					"code" => $location->getCode(),
					"street" => $location->getStreet1(),
					"street_2" => $location->getStreet2(),
					"house_number" => $location->getHouseNumber(),
					"house_number_extension" => $location->getHouseNumberExtension(),
					"postal_code" => $location->getZipCode(),
					"city" => $location->getCity(),
					"country" => $location->getCountry(),
				];
			} catch ( InvalidResponseException|LocationNotFoundException $e ) {
				$this->logWarning( "Location not found: " . $e->getMessage() );
				return [];
			}
		};
	}

	public function getTagDir(): string {
		return __DIR__;
	}
}