<?php

namespace App\Helpers;

use Illuminate\Support\Arr;
use Illuminate\Support\Collection;

/**
 * Useful tools (js/css) used when rendering pages
 */
class PageAssets
{
	// Types that we can handle
	private const array types = [
		'css',
		'js',
	];

	public const array assets = [
		'datatables' => [
			'base' => [
				'css' => [
					'//cdn.datatables.net/2.1.2/css/dataTables.bootstrap4.css',
					//'//cdn.datatables.net/2.1.2/css/dataTables.dataTables.min.css',
				],
				'js' => [
					'//cdn.datatables.net/2.1.2/js/dataTables.min.js',
					'//cdn.datatables.net/2.1.2/js/dataTables.bootstrap4.min.js',
				],
			],
			'buttons' => [
				'css' => [
					'//cdn.datatables.net/buttons/3.1.0/css/buttons.bootstrap4.min.css',
					//'//cdn.datatables.net/buttons/3.1.0/css/buttons.dataTables.min.css',
				],
				'js' => [
					'//cdn.datatables.net/buttons/3.1.0/js/dataTables.buttons.min.js',
					//'//cdn.datatables.net/buttons/3.1.0/js/buttons.dataTables.min.js',
					'//cdn.datatables.net/buttons/3.1.0/js/buttons.bootstrap4.min.js',
					'//cdnjs.cloudflare.com/ajax/libs/jszip/3.2.0/jszip.min.js',
				],
			],
			'conditionalpaging' => [
				'js' => [
					'//cdn.datatables.net/plug-ins/2.0.5/features/conditionalPaging/dataTables.conditionalPaging.min.js',
				],
			],
			'fixedheader' => [
				'css' => [
					'//cdn.datatables.net/fixedheader/4.0.1/css/fixedHeader.bootstrap4.min.css',
					//'//cdn.datatables.net/fixedheader/4.0.1/css/fixedHeader.dataTables.min.css',
				],
				'js' => [
					'//cdn.datatables.net/fixedheader/4.0.1/js/dataTables.fixedHeader.min.js',
					//'//cdn.datatables.net/fixedheader/4.0.1/js/fixedHeader.dataTables.min.js',
					'//cdn.datatables.net/fixedheader/4.0.1/js/fixedHeader.bootstrap4.min.js',
				]
			],
			'responsive' => [
				'css' => [
					'//cdn.datatables.net/responsive/3.0.2/css/responsive.bootstrap4.min.css',
					//'//cdn.datatables.net/responsive/3.0.2/css/responsive.dataTables.min.css',
				],
				'js' => [
					'//cdn.datatables.net/responsive/3.0.2/js/dataTables.responsive.min.js',
					//'//cdn.datatables.net/responsive/3.0.2/js/responsive.bootstrap.min.js',
					'//cdn.datatables.net/responsive/3.0.2/js/responsive.bootstrap4.min.js',
				]
			],
			'rowgroup' => [
				'css' => [
					'//cdn.datatables.net/rowgroup/1.5.0/css/rowGroup.bootstrap4.min.css',
					//'//cdn.datatables.net/rowgroup/1.5.0/css/rowGroup.dataTables.min.css',
				],
				'js' => [
					'//cdn.datatables.net/rowgroup/1.5.0/js/dataTables.rowGroup.min.js',
					//'//cdn.datatables.net/rowgroup/1.5.0/js/rowGroup.dataTables.min.js',
					'//cdn.datatables.net/rowgroup/1.5.0/js/rowGroup.bootstrap4.min.js',
				],
			],
			'searchpanes' => [
				'css' => [
					'//cdn.datatables.net/searchpanes/2.3.1/css/searchPanes.bootstrap4.min.css',
					//'//cdn.datatables.net/searchpanes/2.3.1/css/searchPanes.dataTables.min.css',
				],
				'js' => [
					'//cdn.datatables.net/searchpanes/2.3.1/js/dataTables.searchPanes.min.js',
					//'//cdn.datatables.net/searchpanes/2.3.1/js/searchPanes.dataTables.min.js',
					'//cdn.datatables.net/searchpanes/2.3.1/js/searchPanes.bootstrap4.min.js',
				],
			],
			'searchpanes-left' => [
				'css' => [
					'/plugin/dataTables/leftSearchPanes.css',
				],
			],
			'select' => [
				'css' => [
					'//cdn.datatables.net/select/2.0.3/css/select.bootstrap4.min.css',
					//'//cdn.datatables.net/select/2.0.3/css/select.dataTables.min.css',
				],
				'js' => [
					'//cdn.datatables.net/select/2.0.3/js/dataTables.select.min.js',
					//'//cdn.datatables.net/select/2.0.3/js/select.dataTables.min.js',
					'//cdn.datatables.net/select/2.0.3/js/select.bootstrap4.min.js',
				]
			],
		],
		'select2' => [
			'base' => [
				'css' => [
					'//cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css',
				],
				'js' => [
					'//cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js',
				],
			],
			'autofocus' => [
				'js' => [
					'/plugin/select2/fix-autofocus.js',
				],
			]
		],
		'simplemde' => [
			'base' => [
				'css' => [
					'//cdn.jsdelivr.net/simplemde/latest/simplemde.min.css',
				],
				'js' => [
					'//cdn.jsdelivr.net/simplemde/latest/simplemde.min.js',
				],
			],
		],
	];

	// Items to manage
	public static Collection $items;

	// Add an item to the list
	public static function add(string $type,Collection|array|string $asset): void
	{
		if (! in_array($type,self::types))
			throw new \Exception('Invalid type: '.$type);

		if (! isset(self::$items))
			self::init();

		if (is_string($asset))
			self::$items
				->get($type)
				->push($asset)
				->unique();
		else
			self::$items->put($type,
				self::$items
					->get($type)
					->merge($asset->values())
					->unique());
	}

	// Add a predefined asset
	public static function asset(string $id): void
	{
		if (! isset(self::$items))
			self::init();

		if (str_contains($id,',')) {
			[$item,$arguments] = explode(',',$id,2);
			$arguments = collect(explode('|',$arguments));

		} else {
			$item = $id;
			$arguments = collect();
		}

		$arguments = $arguments->prepend('base');
		$asset = collect(Arr::get(self::assets,$item))->only($arguments);

		foreach (self::types as $type)
			if ($x=$asset->pluck($type)->filter()->flatten())
				self::add($type,$x);
	}

	// Render the CSS items
	public static function css(): string
	{
		return isset(self::$items)
			? self::$items
				->get('css')
				->map(fn($item)=>sprintf('<link rel="stylesheet" href="%s">',$item))
				->join('')
			: '';
	}

	public static function init(): void
	{
		self::$items = collect([
			'js' => collect(),
			'css' => collect(),
		]);
	}

	// Render the JS items
	public static function js(): string
	{
		return isset(self::$items)
			? self::$items
				->get('js')
				->map(fn($item)=>sprintf('<script type="text/javascript" src="%s"></script>',$item))
				->join('')
			: '';
	}
}