<?php

namespace Planaday\Platform\WordpressConfig\Blocks;

use Exception;
use Planaday\Config\FeatureToggles\FeatureToggleSettings;
use Planaday\Html\FeatureService;
use Planaday\Html\NodeTags\Feature;
use Planaday\Platform\PlatformAbstraction\LocalizationController;
use Planaday\Platform\PlatformAbstraction\UrlHandler;
use Planaday\Utility\Debug\Log\Logging;
use Planaday\Utility\Debug\PluginFeatureTimer;
use Planaday\Utility\DependencyInjection\Container;
use Planaday\Utility\PluginData;
use WP_Error;
use WP_REST_Request;

class BlockHandler {
	use Logging;

	public function __construct(
		protected PluginData $pluginData,
		protected Container $registry,
		protected UrlHandler $urlHandler,
		protected LocalizationController $translator,
		protected FeatureToggleSettings $featureToggleSettings,
		protected PluginFeatureTimer $timer
	) {}

	public function registerBlocks(): void {
		$stop = $this->timer->start("registering blocks");
		add_filter('block_categories_all', [$this, 'addPlanadayCategory']);
		$assetFile = include(__DIR__ . '/build/index.asset.php');

		wp_register_script(
			$this->pluginData->getFullPrefix() . '-block-editor-script',
			plugins_url( dirname( $this->pluginData->getPluginFile() ) . '/src/Planaday/Platform/WordpressConfig/Blocks/build/index.js' ),
			$assetFile['dependencies'],
			$assetFile['version']
		);

		wp_register_style(
			$this->pluginData->getFullPrefix() . '-block-editor-style',
			plugins_url( dirname( $this->pluginData->getPluginFile() ) . '/src/Planaday/Platform/WordpressConfig/Blocks/blockStyles.css' ),
			[
				$this->pluginData->getFullPrefix() . '-form-builder-style'
			]
		);

		foreach (WordPressBlock::cases() as $block) {
			$this->registerBlock($block);
		}
		$stop();
	}

	public function addPlanadayCategory(array $block_categories): array {
		$block_categories[] = [
			'slug'  => $this->pluginData->getFullPrefix(),
			'title' => 'Planaday',
			'icon'  => null
		];

		return $block_categories;
	}

	protected function registerBlock(WordPressBlock $block):void{
		/** @var class-string<Feature> $class */
		$class = $block->getClass();
		$name = $this->pluginData->getFullPrefix() . '/' . $block->value;
		$templates = [];

		foreach ($class::getAllowedTemplates($this->featureToggleSettings) as $key => $template) {
			if (!is_string($key)){
				$templates[$template] = $template;
			} else {
				$templates[$this->translator->translate($key)] = $template;
			}
		}

		$renderURL = $this->urlHandler->getBaseUrl() . '/wp-json/' . $this->pluginData->getFullPrefix() . '/v1/wordpress-blocks/render/' . $block->value;

		add_action( 'rest_api_init', function () use ($block) {
			register_rest_route(
				$this->pluginData->getFullPrefix() . '/v1',
				'/wordpress-blocks/render/' . $block->value,
				array(
					'methods' => 'POST',
					'callback' => function ( WP_REST_Request $request ) use ( $block ) {
						return $this->buildRestResponse($request, $block);
					},
					'permission_callback' => __return_true(...)
				)
			);
		});

		register_block_type(
			$name,
			[
				'$schema' => 'https://schemas.wp.org/trunk/block.json',
				'apiVersion' => 3,
				'name' => $name,
				'title' => $block->getTitle(),
				'category' => $this->pluginData->getFullPrefix(),
				'description' => $block->getDescription(),
				'attributes' => array(
					'template' => array(
						'type' => 'string',
						'enum' => $class::getAllowedTemplates($this->featureToggleSettings),
					),
					'config' => array(
						'type' => 'object'
					),
					'lastChanged' => array(
						'type' => 'number'
					),
					'UUID' => array(
						'type' => 'string'
					)
				),
				'editor_script' => $this->pluginData->getFullPrefix() . '-block-editor-script',
				'render_callback' => function ($attributes) use ($block) {
					return $this->renderBlock($attributes, $block);
				},
				'editor_style' => $this->pluginData->getFullPrefix() . '-block-editor-style',
			]
		);
		wp_add_inline_script(
			$this->pluginData->getFullPrefix() . '-block-editor-script',
			"window.planadayRegisterBlock('$name', '{$block->getTitle()}', " . json_encode($templates) . ", '$renderURL');"
		);
	}

	public function renderBlock(array $attributes, WordPressBlock $block): string {
		$stop = $this->timer->start("rendering block $block->value");
		$output = "<!-- planaday-block: $block->value -->";
		try {
			$output .= $this->registry->getInstance( FeatureService::class)
			                          ->getParsed($block->getClass(), $attributes);
		} catch ( Exception $e){
			$output .= "<!-- parse failed: {$e->getMessage()} -->";
		}
		$output .= "<!-- /planaday-block: $block->value -->";
		$stop();
		return $output;
	}


	/**
	 * @param WP_REST_Request $attributes
	 * @param WordPressBlock $block
	 *
	 * @return array{options:array}|WP_Error
	 */
	protected function buildRestResponse(WP_REST_Request $attributes, WordPressBlock $block): array|WP_Error {
		try {
			$form = $this->registry->getInstance(FeatureService::class)
			                       ->getSettingsForm($block->getClass(), $attributes->get_json_params());
		} catch ( Exception $e){
			return new WP_Error(500, $e->getMessage());
		}

		return [ 'options' => $form ];
	}
}