<?php

namespace Planaday\Platform\WordpressConfig\Widgets\CourseDetails;

use Planaday\Api\ApiException\InvalidResponseException;
use Planaday\Config\Course\General\GeneralSettings;
use Planaday\Entities\CostDataUtility;
use Planaday\Entities\Course\CourseController;
use Planaday\Entities\Course\CourseUtility;
use Planaday\Entities\Course\Exception\CourseNotFoundException;
use Planaday\Html\HtmlParserFactory;
use Planaday\Html\Tags\Course\CourseShortcode\CourseShortcode;
use Planaday\Platform\PlatformAbstraction\LocalizationController;
use Planaday\Platform\PlatformAbstraction\UrlHandler;
use Planaday\Utility\DateAndTimeUtility;
use Planaday\Utility\Debug\Log\Logging;
use Planaday\Utility\DependencyInjection\Container;
use Planaday\Utility\DependencyInjection\InjectionImpossibleException;
use Planaday\Utility\GeneralTermEnum;
use Planaday\Utility\PluginData;
use WP_Widget;

class CourseDetails extends WP_Widget {
	use Logging;

	public function __construct(
		protected PluginData $pluginData,
		LocalizationController $localizationController,
		protected Container $registry
	) {
		parent::__construct(
			 $pluginData->getFullPrefix() . '-course-details-widget',
			$pluginData->getFullPrefix(). ' ' . $localizationController->translate('cursus details'),
			array(
				'customize_selective_refresh' => true,
			)
		);
	}

	public function form( $instance ):void {
		try {
			$parser = $this->registry->getInstance(HtmlParserFactory::class)->getParser();
		} catch (InjectionImpossibleException $e) {
			echo "<div> Iets is niet goed gegaan, probeer het later opnieuw: {$e->getMessage()} </div>";
			return;
		}

		$parser->setBeingParsedName(self::class);
		$parser->setData('titleValue', $instance[CourseDetailsSettingsEnum::TITLE] ?? 'Cursus details');

		$parser->setData('titleName', $this->get_field_name(CourseDetailsSettingsEnum::TITLE));
		$parser->setData('titleToggleName', $this->get_field_name(CourseDetailsSettingsEnum::SHOW_TITLE));
		$parser->setData('labelToggleName', $this->get_field_name(CourseDetailsSettingsEnum::SHOW_LABELS));
		$parser->setData('availableToggleName', $this->get_field_name(CourseDetailsSettingsEnum::SHOW_AVAILABLE));
		$parser->setData('priceToggleName', $this->get_field_name(CourseDetailsSettingsEnum::SHOW_PRICE));
		$parser->setData('dayPartCountToggleName', $this->get_field_name(CourseDetailsSettingsEnum::SHOW_DAY_PART_COUNT));
		$parser->setData('locationToggleName', $this->get_field_name(CourseDetailsSettingsEnum::SHOW_LOCATION));
		$parser->setData('startDateToggleName', $this->get_field_name(CourseDetailsSettingsEnum::SHOW_START_DATE));

		$parser->setData('titleId', $this->get_field_id(CourseDetailsSettingsEnum::TITLE));
		$parser->setData('titleToggleId', $this->get_field_id(CourseDetailsSettingsEnum::SHOW_TITLE));
		$parser->setData('labelToggleId', $this->get_field_id(CourseDetailsSettingsEnum::SHOW_LABELS));
		$parser->setData('availableToggleId', $this->get_field_id(CourseDetailsSettingsEnum::SHOW_AVAILABLE));
		$parser->setData('priceToggleId', $this->get_field_id(CourseDetailsSettingsEnum::SHOW_PRICE));
		$parser->setData('dayPartCountToggleId', $this->get_field_id(CourseDetailsSettingsEnum::SHOW_DAY_PART_COUNT));
		$parser->setData('locationToggleId', $this->get_field_id(CourseDetailsSettingsEnum::SHOW_LOCATION));
		$parser->setData('startDateToggleId', $this->get_field_id(CourseDetailsSettingsEnum::SHOW_START_DATE));

		$parser->setData('titleToggleChecked', $instance[CourseDetailsSettingsEnum::SHOW_TITLE] == '1' ? "data-checked" : "");
		$parser->setData('labelToggleChecked', $instance[CourseDetailsSettingsEnum::SHOW_LABELS] == '1' ? "data-checked" : "");
		$parser->setData('availableToggleChecked', $instance[CourseDetailsSettingsEnum::SHOW_AVAILABLE] == '1' ? "data-checked" : "");
		$parser->setData('priceToggleChecked', $instance[CourseDetailsSettingsEnum::SHOW_PRICE] == '1' ? "data-checked" : "");
		$parser->setData('dayPartCountToggleChecked', $instance[CourseDetailsSettingsEnum::SHOW_DAY_PART_COUNT] == '1' ? "data-checked" : "");
		$parser->setData('locationToggleChecked', $instance[CourseDetailsSettingsEnum::SHOW_LOCATION] == '1' ? "data-checked" : "");
		$parser->setData('startDateToggleChecked', $instance[CourseDetailsSettingsEnum::SHOW_START_DATE] == '1' ? "data-checked" : "");

		echo "<!--  " . ($instance[CourseDetailsSettingsEnum::SHOW_TITLE] == '1' ? "data-checked" : "") . "  -->";
		echo $parser->parse(file_get_contents(__DIR__ . '/CourseDetailsForm.html'));
	}

	public function update( $new_instance, $old_instance ): array {
		return $new_instance;
	}

	public function widget( $args, $instance ): void {
		try {
			$urlHandler = $this->registry->getInstance(UrlHandler::class);
		} catch (InjectionImpossibleException $e){
			$this->logError('Failed to load required components for Course Details Widget: ' . $e->getMessage());
			return;
		}

		$detailPage = $urlHandler->currentPageHasShortCode($this->pluginData->getShortPrefix() . '-' . CourseShortcode::TAG);
		$courseId = $urlHandler->getUrlQueryField($this->pluginData->getShortPrefix() . GeneralTermEnum::COURSE_ID_URL_QUERY);

		if ( !$detailPage ) return;

		if ($courseId === null) {
			$this->logWarning('Course ID not found in URL');
			return;
		}

		try {
			$generalCourseSettings = $this->registry->getInstance(GeneralSettings::class);
			$courseController = $this->registry->getInstance(CourseController::class);
			$costUtility = $this->registry->getInstance(CostDataUtility::class);
			$courseUtility = $this->registry->getInstance(CourseUtility::class);
			$dateUtility = $this->registry->getInstance(DateAndTimeUtility::class);
			$parser = $this->registry->getInstance(HtmlParserFactory::class)->getParser();
		} catch (InjectionImpossibleException $e){
			$this->logError('Failed to load required components for Course Details Widget: ' . $e->getMessage());
			return;
		}

		try {
			$course = $courseController->getCourse($courseId, true);
		} catch(CourseNotFoundException){
			$this->logWarning("course not found with Id: $courseId");
			return;
		} catch(InvalidResponseException $e){
			$this->logError('Failed to get course data from API: ' . $e->getMessage());
			return;
		}
		$parser->setBeingParsedName(self::class);

		$firstDayPart = $course->getEarliestDayPart($generalCourseSettings->isELearningCountsAsStart());
		if ($firstDayPart) $parser->setData('startDate', $dateUtility->getReadableDate($firstDayPart->getStartTime()));
		else $parser->setData('startDate', '-');
		$location = $firstDayPart?->getLocations()[0] ?? null;
		if ($location) $parser->setData('location', $location->getCity());
		else $parser->setData('location', '-');

		$includeOptionsAvailability = $generalCourseSettings->isIncludeOptionInCount();

		$parser->setData('name', $course->getName());
		$parser->setData('dayPartCount', $courseUtility->getDayPartCount($course, true));
		$parser->setData('dayPartText', $generalCourseSettings->getDayPartText());
		$parser->setData('available', $course->getUsersData()->getAvailableSpots($includeOptionsAvailability));
		$parser->setData('labels', implode(', ', $course->getLabels()));
		$parser->setData('price', $costUtility->getPriceString($course->getCostsData(), false, true));
		$parser->setData(
			'titleText',
			empty($instance[CourseDetailsSettingsEnum::TITLE]) ?
				'Cursus details' :
				$instance[CourseDetailsSettingsEnum::TITLE]
		);
		$parser->setUnsafeData('beforeTitle', $args['before_title']);
		$parser->setUnsafeData('afterTitle', $args['after_title']);

		$parser->setCondition('showDayPartCount', $instance[CourseDetailsSettingsEnum::SHOW_DAY_PART_COUNT] == '1');
		$parser->setCondition('showLabels',  $instance[CourseDetailsSettingsEnum::SHOW_LABELS] == '1');
		$parser->setCondition('showLocation', $instance[CourseDetailsSettingsEnum::SHOW_LOCATION] == '1');
		$parser->setCondition('showAvailable', $instance[CourseDetailsSettingsEnum::SHOW_AVAILABLE] == '1');
		$parser->setCondition('showPrice', $instance[CourseDetailsSettingsEnum::SHOW_PRICE] == '1');
		$parser->setCondition('showStartDate', $instance[CourseDetailsSettingsEnum::SHOW_START_DATE] == '1');
		$parser->setCondition('showTitle', $instance[CourseDetailsSettingsEnum::SHOW_TITLE] == '1');

		echo $args['before_widget'];
		echo $parser->parse(file_get_contents(__DIR__ . '/CourseDetailsWidget.html'));
		echo $args['after_widget'];
	}
}