<?php
declare(strict_types = 1);

/**
 * Options, réglages et paramètres de configuration.
 *
 * @license https://www.gnu.org/licenses/gpl-3.0.html
 * @link https://www.igalerie.org/
 */
class AdminSettings extends Admin
{
	/**
	 * Récupération et modification des paramètres de configuration.
	 *
	 * @return void
	 */
	public static function config(): void
	{
		$db_config = array_keys(Config::$params);

		// Modification.
		if (isset($_POST['config']) && is_array($_POST['config']))
		{
			App::checkboxes($_POST['config']);

			$params = Category::getOrderByParams();

			// Critères de tri des catégories et fichiers.
			foreach (['album' => 'items', 'category' => 'categories'] as $p => $o)
			{
				if (isset($_POST['config'][$o]) && isset($_POST['config'][$o]['sortby_1']))
				{
					$order_by = [];
					foreach ([1, 2, 3] as $n)
					{
						$sortby = $_POST['config'][$o]['sortby_' . $n];
						$orderby = $_POST['config'][$o]['orderby_' . $n];
						if (isset($params[$p][$sortby]) && $sortby != 'none'
						&& in_array($orderby, ['ASC', 'DESC']))
						{
							$order_by[] = $sortby . ' ' . $orderby;
						}
					}
					if (count($order_by))
					{
						$_POST['config'][$o . '_sql_order_by'] = implode(', ', $order_by);
					}
				}
			}
			if (isset($_POST['config']['browse']))
			{
				$sortby = $_POST['config']['browse_sortby'] ?? '';
				$orderby = $_POST['config']['browse_orderby'] ?? '';
				if (isset($params['category'][$sortby]) && in_array($orderby, ['ASC', 'DESC']))
				{
					$_POST['config']['browse_sql_order_by'] = $sortby . ' ' . $orderby;
				}
			}

			// Qualité GD.
			foreach (['items_resize_quality', 'thumbs_quality', 'upload_resize_quality'] as $q)
			{
				if (isset($_POST['config'][$q])
				&& ((int) $_POST['config'][$q] > 100 || (int) $_POST['config'][$q] < 1))
				{
					unset($_POST['config'][$q]);
				}
			}

			// Format de fichiers.
			foreach (['items_resize_type', 'thumbs_type'] as $f)
			{
				if (isset($_POST['config'][$f])
				&& (!in_array($_POST['config'][$f], ['', 'avif', 'jpeg', 'webp'])))
				{
					unset($_POST['config'][$f]);
				}
			}

			// Géolocalisation : type de carte.
			if (isset($_POST['config']['geolocation_default_layer'])
			&& !in_array($_POST['config']['geolocation_default_layer'], ['map', 'satellite']))
			{
				unset($_POST['config']['geolocation_default_layer']);
			}

			// Configuration en base de données.
			$db_params = [];
			foreach ($db_config as &$p)
			{
				if (!isset($_POST['config'][$p]))
				{
					continue;
				}
				$value = $_POST['config'][$p];

				// Mot de passe pour les inscriptions.
				if ($p == 'users_registration_password')
				{
					if (preg_match('`^\*+$`', trim($value)))
					{
						continue;
					}
					$value = Utility::isEmpty($value) ? '' : Security::passwordHash($value);
				}

				$db_params[$p] = $value;
			}

			// Fichier de configuration.
			$file_params = [];
			if (isset($_POST['config']['CONF_URL_REWRITE'])
			&& CONF_URL_REWRITE != $_POST['config']['CONF_URL_REWRITE'])
			{
				$file_params['CONF_URL_REWRITE'] = (int) $_POST['config']['CONF_URL_REWRITE'];
			}

			self::_updateConfig($db_params, $file_params);
		}

		// Récupération des valeurs (base de données).
		$params = [];
		foreach ($db_config as &$p)
		{
			$value = isset($_POST['config'][$p]) ? $_POST['config'][$p] : Config::$params[$p];
			if ($p == 'users_registration_password')
			{
				$value = isset($_POST['config'][$p])
					? (strlen($_POST['config'][$p]) ? '**********' : '')
					: (strlen((string) Config::$params[$p]) ? '**********' : '');
			}
			$params[$p] = $value;
		}
		Template::set('config', $params);

		// Récupération des valeurs (fichier de configuration).
		$params = ['CONF_URL_REWRITE' => CONF_URL_REWRITE];
		if (!isset(Template::$data['config']['CONF_URL_REWRITE']))
		{
			Template::set('config', $params);
		}

		// Nombre de vignettes par page.
		$nb_per_page = function($p, $o, $multiple)
		{
			$param = Config::$params['thumbs_' . $p . '_nb_per_page'];
			$nb_per_page = [];
			for ($i = 1; $i <= 10; $i++)
			{
				$value = $multiple * $i;
				$nb_per_page[] =
				[
					'selected' => $param == $value,
					'text' => $value,
					'value' => $value
				];
			}
			$nb_per_page[] =
			[
				'selected' => $param == 0,
				'text' => '*' . __('Aucune limite'),
				'value' => 0
			];
			Template::set($o . '_nb_per_page', $nb_per_page);
		};
		$nb_per_page('cat', 'categories', 12);
		$nb_per_page('item', 'items', 12);

		// Critères de tri des catégories et fichiers.
		foreach (['album' => 'items', 'browse' => 'browse', 'category' => 'categories']
		as $p => $o)
		{
			$order_by = explode(',', Config::$params[$o . '_sql_order_by']);
			foreach ($order_by as &$db_config)
			{
				$db_config = explode(' ', trim($db_config));
			}
			if (!isset($order_by[1]))
			{
				$order_by[1] = ['none', 'ASC'];
			}
			if (!isset($order_by[2]))
			{
				$order_by[2] = ['none', 'ASC'];
			}
			$params = Category::getOrderByParams()[$p == 'browse' ? 'category' : $p];
			unset($params['default']);
			if ($p == 'browse')
			{
				unset($params['none']);
			}
			Template::set($o . '_sort_by', $order_by);
			Template::set($o . '_sort_by_params', $params);
		}
		Template::set('order_by_params', Category::getOrderByParams()['order']);

		// Format des vignettes du diaporama.
		$ratio_list =
		[
			'normal' => __('Normal'),
			'square' => __('Carré')
		];
		$ratio = [];
		foreach ($ratio_list as $name => &$text)
		{
			$ratio[] =
			[
				'name' => $name,
				'selected' => Config::$params['diaporama_carousel_thumbs_ratio'] == $name,
				'text' => $text
			];
		}
		Template::set('diaporama_carousel_thumbs_ratio', $ratio);

		// Effets de transition du diaporama.
		$effect_list =
		[
			'none' => __('Aucun'),
			'fade' => __('Fondu'),
			'slideX' => __('Défilement (horizontal)'),
			'slideY' => __('Défilement (vertical)'),
			'slideXLeft' => __('Diapositive (horizontal)'),
			'slideYBottom' => __('Diapositive (vertical)'),
			'curtainX' => __('Rideau (horizontal)'),
			'curtainY' => __('Rideau (vertical)'),
			'puff' => __('Souffle'),
			'zoom' => __('Zoom'),
			'random' => __('Aléatoire')
		];
		$effect = [];
		foreach ($effect_list as $name => &$text)
		{
			$effect[] =
			[
				'name' => $name,
				'selected' => Config::$params['diaporama_transition_effect'] == $name,
				'text' => $text
			];
		}
		Template::set('diaporama_transition_effect', $effect);
	}

	/**
	 * Récupération des paramètres de statistiques des catégories.
	 *
	 * @return void
	 */
	public static function getCategoriesStats(): void
	{
		$order = Config::$params['categories_stats_order'];
		$params = Config::$params['categories_stats_params'];

		$title = function($name)
		{
			switch ($name)
			{
				case 'albums'        : return __('Nombre d\'albums');
				case 'comments'      : return __('Nombre de commentaires');
				case 'favorites'     : return __('Nombre de favoris');
				case 'filesize'      : return __('Poids des photos et vidéos');
				case 'images'        : return __('Nombre de photos');
				case 'items'         : return __('Nombre de photos et vidéos');
				case 'rating'        : return __('Note moyenne');
				case 'recent_images' : return __('Nombre de photos récentes');
				case 'recent_items'  : return __('Nombre de photos et vidéos récentes');
				case 'recent_videos' : return __('Nombre de vidéos récentes');
				case 'videos'        : return __('Nombre de vidéos');
				case 'views'         : return __('Nombre de vues');
				case 'votes'         : return __('Nombre de votes');
			}
		};

		$stats = [];
		foreach ($order as $id => &$name)
		{
			$stats[] =
			[
				'id' => (int) $id,
				'name' => $name,
				'status' => (bool) $params[$name]['status'],
				'title' => $title($name)
			];
		}

		Template::set('categories_stats', $stats);
	}

	/**
	 * Récupération des paramètres EXIF.
	 *
	 * @return void
	 */
	public static function getExif(): void
	{
		$order = Config::$params['exif_order'];
		$params = Config::$params['exif_params'];

		$exif = [];
		foreach ($order as $id => &$name)
		{
			$exif[] =
			[
				'format' => $params[$name]['format'] ?? NULL,
				'id' => (int) $id,
				'name' => $name,
				'status' => (bool) $params[$name]['status'],
				'title' => Metadata::getExifLocale($name)
			];
		}

		Template::set('exif', $exif);
	}

	/**
	 * Récupération des paramètres IPTC.
	 *
	 * @return void
	 */
	public static function getIptc(): void
	{
		$order = Config::$params['iptc_order'];
		$params = Config::$params['iptc_params'];

		$iptc = [];
		foreach ($order as $id => &$name)
		{
			$iptc[] =
			[
				'id' => (int) $id,
				'name' => $name,
				'status' => (bool) $params[$name]['status'],
				'title' => Metadata::getIptcLocale($name)
			];
		}

		Template::set('iptc', $iptc);
	}

	/**
	 * Récupération des liens externes.
	 *
	 * @return void
	 */
	public static function getLinks(): void
	{
		$links_params = Config::$params['links_params'];

		$links = [];
		foreach ($links_params as $id => &$i)
		{
			$links[] =
			[
				'activated' => (bool) $i['activated'],
				'desc' => $i['desc'],
				'id' => (int) $id,
				'title' => $i['title'],
				'url' => $i['url']
			];
		}

		Template::set('links', $links);
	}

	/**
	 * Récupération des paramètres des thèmes.
	 *
	 * @return void
	 */
	public static function getThemes(): void
	{
		$themes_dir = GALLERY_ROOT . '/template';
		$themes = [];
		foreach (scandir($themes_dir) as $dir)
		{
			if (preg_match(App::TPL_REGEXP, $dir) && is_dir($themes_dir . '/' . $dir)
			&& is_file($themes_dir . '/' . $dir . '/screenshot.jpg'))
			{
				$themes[] =
				[
					'current' => Config::$params['theme_template'] == $dir,
					'name' => $dir,
					'screenshot_source' => CONF_GALLERY_PATH
						. '/template/' . $dir . '/screenshot.jpg'
				];
			}
		}

		Template::set('themes', $themes);
	}

	/**
	 * Récupération des paramètres XMP.
	 *
	 * @return void
	 */
	public static function getXmp(): void
	{
		$order = Config::$params['xmp_order'];
		$params = Config::$params['xmp_params'];

		$xmp = [];
		foreach ($order as $id => &$name)
		{
			$xmp[] =
			[
				'id' => (int) $id,
				'name' => $name,
				'status' => (bool) $params[$name]['status'],
				'title' => Metadata::getXmpLocale($name)
			];
		}

		Template::set('xmp', $xmp);
	}

	/**
	 * Outils de maintenance.
	 *
	 * @return void
	 */
	public static function maintenance(): void
	{
		// Vérification des statistiques.
		if (isset($_POST['stats']))
		{
			if (Maintenance::dbStats() < 0)
			{
				Report::error();
				return;
			}

			$count_categories
				= count(Maintenance::$updateStatsReport['categories'])
				+ count(Maintenance::$updateStatsReport['categories_status']);

			$count_items
				= count(Maintenance::$updateStatsReport['items'])
				+ Maintenance::$updateStatsReport['items_status'];

			$report =& Maintenance::$updateStatsReport;
			$gallery_path = ['categories' => [], 'items' => []];
			foreach ($report['categories'] as &$i)
			{
				$gallery_path['categories'][] = $i['id'];
			}
			foreach ($report['items'] as &$i)
			{
				$gallery_path['items'][] = $i['id'];
			}
			$gallery_path = Parents::getGalleryPath($gallery_path);

			foreach ($report['categories'] as $k => &$i)
			{
				$report['categories'][$k]['path'] = $gallery_path['categories'][$i['id']];
			}
			foreach ($report['items'] as $k => &$i)
			{
				$report['items'][$k]['path'] = $gallery_path['items'][$i['id']];
			}

			Template::set('dbstats_report',
			[
				'count' => $count_categories + $count_items,
				'count_categories' => $count_categories,
				'count_items' => $count_items,
				'details' => $report
			]);
		}

		// Nettoyage de la base de données.
		if (isset($_POST['vacuum']))
		{
			Template::set('dbvacuum_report',
			[
				'success' => $success = DB::vacuum(),
				'message' => $success
					? __('La base de données a été nettoyée.')
					: Report::getErrorDefaultMessage()
			]);
		}
	}

	/**
	 * Définit les paramètres de template pour la section.
	 *
	 * @param string $tpl_filename
	 *
	 * @return void
	 */
	public static function tplSectionFeatures(string $tpl_filename): void
	{
		Template::set('page',
		[
			'link' => App::getURL('features'),
			'title' => __('Fonctionnalités')
		]);
		Template::set('section', 'features');
		Template::set('template', ['file' => $tpl_filename . '.tpl.php']);
	}

	/**
	 * Définit les paramètres de template pour la section.
	 *
	 * @param string $tpl_filename
	 *
	 * @return void
	 */
	public static function tplSectionOptions(string $tpl_filename): void
	{
		Template::set('page',
		[
			'link' => App::getURL('options-gallery'),
			'title' => __('Options')
		]);
		Template::set('section', str_replace('_', '-', $tpl_filename));
		Template::set('template', ['file' => $tpl_filename . '.tpl.php']);
	}

	/**
	 * Mise à jour des liens externes.
	 *
	 * @return void
	 */
	public static function updateLinks(): void
	{
		if (!isset($_POST['serial']))
		{
			return;
		}

		$links = [];
		if (isset($_POST['items']))
		{
			foreach ($_POST['items'] as &$i)
			{
				$links[] =
				[
					'activated' => isset($i['activated']),
					'desc' => Utility::isEmpty($i['desc'])
						? NULL
						: mb_substr($i['desc'], 0, 128),
					'title' => Utility::isEmpty($i['title'])
						? NULL
						: mb_substr($i['title'], 0, 64),
					'url' => substr($i['url'], 0, 256),
				];
			}
		}

		self::_updateConfig(['links_params' => $links]);
	}

	/**
	 * Mise à jour des paramètres des thèmes.
	 *
	 * @return void
	 */
	public static function updateThemes(): void
	{
		if (!isset($_POST['theme']) || !preg_match(App::TPL_REGEXP, $_POST['theme']))
		{
			return;
		}

		self::_updateConfig(['theme_template' => $_POST['theme']]);
	}



	/**
	 * Mise à jour de paramètres de configuration.
	 *
	 * @param array $db_params
	 * @param array $file_params
	 *
	 * @return void
	 */
	private static function _updateConfig(array $db_params, array $file_params = []): void
	{
		$success = FALSE;
		$error = FALSE;
		$nochange = FALSE;

		switch (Config::changeDBParams($db_params))
		{
			case -1 :
				$error = TRUE;
				break;

			case 0 :
				$nochange = TRUE;
				break;

			default :
				$success = TRUE;
				break;
		}

		if ($file_params)
		{
			$success = FALSE;
			$error = FALSE;
			$nochange = FALSE;

			if (Config::changeFileParams($file_params))
			{
				$success = TRUE;
				Template::set('config', $file_params);
			}
			else
			{
				$error = TRUE;
			}
		}

		if ($nochange)
		{
			Report::noChange();
			return;
		}

		if ($error)
		{
			Report::error();
			return;
		}

		if ($success)
		{
			Report::success();
			return;
		}
	}
}
?>