<?php

namespace Kirby\Cms;

/**
 * Converts the data from the old builder and editor fields
 * to the format supported by the new block field.
 * @since 3.9.0
 * @deprecated
 *
 * @todo block.converter remove eventually
 * @codeCoverageIgnore
 *
 * @package   Kirby Cms
 * @author    Bastian Allgeier <bastian@getkirby.com>
 * @link      https://getkirby.com
 * @copyright Bastian Allgeier GmbH
 * @license   https://getkirby.com/license
 */
class BlockConverter
{
	public static function builderBlock(array $params): array
	{
		if (isset($params['_key']) === false) {
			return $params;
		}

		$ignore = array_flip(['field', 'options', 'parent', 'siblings', 'params', '_key', '_uid']);
		$params['content'] = array_diff_key($params, $ignore);
		$params['type']    = $params['_key'];

		unset($params['_uid']);

		return $params;
	}

	public static function editorBlock(array $params): array
	{
		if (static::isEditorBlock($params) === false) {
			return $params;
		}

		$method = 'editor' . $params['type'];

		if (method_exists(static::class, $method) === true) {
			$params = static::$method($params);
		} else {
			$params = static::editorCustom($params);
		}

		return $params;
	}

	public static function editorBlocks(array $blocks = []): array
	{
		if ($blocks === []) {
			return $blocks;
		}

		if (static::isEditorBlock($blocks[0]) === false) {
			return $blocks;
		}

		$list = [];
		$listStart = null;

		foreach ($blocks as $index => $block) {
			if (in_array($block['type'], ['ul', 'ol'], true) === true) {
				$prev = $blocks[$index - 1] ?? null;
				$next = $blocks[$index + 1] ?? null;

				// new list starts here
				if (!$prev || $prev['type'] !== $block['type']) {
					$listStart = $index;
				}

				// add the block to the list
				$list[] = $block;

				// list ends here
				if (!$next || $next['type'] !== $block['type']) {
					$blocks[$listStart] = [
						'content' => [
							'text' =>
								'<' . $block['type'] . '>' .
									implode(array_map(
										fn ($item) => '<li>' . $item['content'] . '</li>',
										$list
									)) .
								'</' . $block['type'] . '>',
						],
						'type' => 'list'
					];

					$start = $listStart + 1;
					$end   = $listStart + count($list);

					for ($x = $start; $x <= $end; $x++) {
						$blocks[$x] = false;
					}

					$listStart = null;
					$list = [];
				}
			} else {
				$blocks[$index] = static::editorBlock($block);
			}
		}

		return array_filter($blocks);
	}

	public static function editorBlockquote(array $params): array
	{
		return [
			'content' => [
				'text' => $params['content']
			],
			'type' => 'quote'
		];
	}

	public static function editorCode(array $params): array
	{
		return [
			'content' => [
				'language' => $params['attrs']['language'] ?? null,
				'code'     => $params['content']
			],
			'type' => 'code'
		];
	}

	public static function editorCustom(array $params): array
	{
		return [
			'content' => [
				...$params['attrs'] ?? [],
				'body' => $params['content'] ?? null
			],
			'type' => $params['type'] ?? 'unknown'
		];
	}

	public static function editorH1(array $params): array
	{
		return static::editorHeading($params, 'h1');
	}

	public static function editorH2(array $params): array
	{
		return static::editorHeading($params, 'h2');
	}

	public static function editorH3(array $params): array
	{
		return static::editorHeading($params, 'h3');
	}

	public static function editorH4(array $params): array
	{
		return static::editorHeading($params, 'h4');
	}

	public static function editorH5(array $params): array
	{
		return static::editorHeading($params, 'h5');
	}

	public static function editorH6(array $params): array
	{
		return static::editorHeading($params, 'h6');
	}

	public static function editorHr(array $params): array
	{
		return [
			'content' => [],
			'type'    => 'line'
		];
	}

	public static function editorHeading(array $params, string $level = 'h1'): array
	{
		return [
			'content' => [
				'level' => $level,
				'text'  => $params['content']
			],
			'type' => 'heading'
		];
	}

	public static function editorImage(array $params): array
	{
		// internal image
		if (isset($params['attrs']['id']) === true) {
			return [
				'content' => [
					'alt'      => $params['attrs']['alt'] ?? null,
					'caption'  => $params['attrs']['caption'] ?? null,
					'image'    => $params['attrs']['id'] ?? $params['attrs']['src'] ?? null,
					'location' => 'kirby',
					'ratio'    => $params['attrs']['ratio'] ?? null,
				],
				'type' => 'image'
			];
		}

		return [
			'content' => [
				'alt'      => $params['attrs']['alt'] ?? null,
				'caption'  => $params['attrs']['caption'] ?? null,
				'src'      => $params['attrs']['src'] ?? null,
				'location' => 'web',
				'ratio'    => $params['attrs']['ratio'] ?? null,
			],
			'type' => 'image'
		];
	}

	public static function editorKirbytext(array $params): array
	{
		return [
			'content' => [
				'text' => $params['content']
			],
			'type' => 'markdown'
		];
	}

	public static function editorOl(array $params): array
	{
		return [
			'content' => [
				'text' => $params['content']
			],
			'type' => 'list'
		];
	}

	public static function editorParagraph(array $params): array
	{
		return [
			'content' => [
				'text' => '<p>' . $params['content'] . '</p>'
			],
			'type' => 'text'
		];
	}

	public static function editorUl(array $params): array
	{
		return [
			'content' => [
				'text' => $params['content']
			],
			'type' => 'list'
		];
	}

	public static function editorVideo(array $params): array
	{
		return [
			'content' => [
				'caption' => $params['attrs']['caption'] ?? null,
				'url'     => $params['attrs']['src'] ?? null
			],
			'type' => 'video'
		];
	}

	public static function isEditorBlock(array $params): bool
	{
		if (isset($params['attrs']) === true) {
			return true;
		}

		if (is_string($params['content'] ?? null) === true) {
			return true;
		}

		return false;
	}
}
