<?php
declare(strict_types = 1);

require_once(__DIR__ . '/Admin.class.php');

/**
 * Section "groupes".
 *
 * @license https://www.gnu.org/licenses/gpl-3.0.html
 * @link https://www.igalerie.org/
 */
class AdminGroups extends Admin
{
	/**
	 * Création d'un nouveau groupe.
	 *
	 * @return bool
	 */
	public static function addGroup(): bool
	{
		Template::set('field_error', '');
		Template::set('new_group', ['fail' => 0, 'name' => '', 'title' => '', 'desc' => '']);

		if (!isset($_POST['group_add']))
		{
			return TRUE;
		}

		$r = Group::create($_POST);
		if ($r === FALSE)
		{
			Report::error();
		}
		else if (is_array($r))
		{
			Report::warning($r['message']);
			Template::set('field_error', $r['param']);
		}
		else if ($r === NULL)
		{
			return TRUE;
		}
		else
		{
			Report::success(__('Le groupe a été créé.'));
			return TRUE;
		}

		Template::set('new_group',
		[
			'fail' => 1,
			'name' => $_POST['name'] ?? '',
			'title' => $_POST['title'] ?? '',
			'desc' => $_POST['desc'] ?? ''
		]);
		return FALSE;
	}

	/**
	 * Modification des informations de groupe.
	 *
	 * @return void
	 */
	public static function changeGroupInfos(): void
	{
		Template::set('field_error', '');
		if ($_POST)
		{
			$r = Group::edit($_GET['group_id'], $_POST);
			if ($r === TRUE)
			{
				Report::success();
			}
			else if ($r === FALSE)
			{
				Report::error();
			}
			else if (is_array($r))
			{
				Report::warning($r['message']);
				Template::set('field_error', $r['param']);
			}
			else
			{
				Report::noChange();
			}
		}
	}

	/**
	 * Modification des permissions d'accès aux catégories.
	 *
	 * @return void
	 */
	public static function changePermsCategories(): void
	{
		if (!Utility::checkPost('blacklist', '`^(\d+(,\d+)*|)$`')
		 || !Utility::checkPost('whitelist', '`^(\d+(,\d+)*|)$`')
		 || !isset($_POST['list']))
		{
			return;
		}

		$blacklist = explode(',', $_POST['blacklist']);
		$whitelist = explode(',', $_POST['whitelist']);

		$r = Group::changePermsCategories($_GET['group_id'],
			$_POST['list'], $blacklist, $whitelist);

		if ($r === FALSE)
		{
			Report::error();
		}
		else if ($r === TRUE)
		{
			Report::success();
		}
		else
		{
			Report::noChange();
		}
	}

	/**
	 * Modification des permissions d'accès aux fonctionnalités.
	 *
	 * @return void
	 */
	public static function changePermsFeatures(): void
	{
		if ($_POST)
		{
			$r = Group::changePermsFeatures($_GET['group_id'], $_POST);

			if ($r === FALSE)
			{
				Report::error();
			}
			else if ($r === TRUE)
			{
				Report::success();
			}
			else
			{
				Report::noChange();
			}
		}
	}

	/**
	 * Supprime un groupe.
	 *
	 * @return void
	 */
	public static function delete(): void
	{
		if (isset($_POST['delete']))
		{
			if (Group::delete($_GET['group_id']))
			{
				App::redirect('groups');
			}
			else
			{
				Report::error();
			}
		}
	}

	/**
	 * Récupération des informations d'un groupe.
	 *
	 * @return void
	 */
	public static function getGroup(): void
	{
		$i = Group::getInfos($_GET['group_id']);
		if ($i === FALSE)
		{
			return;
		}
		if ($i === NULL)
		{
			App::redirect('groups');
			return;
		}
		if ($_GET['section'] == 'group-categories' && $i['group_admin'])
		{
			App::redirect('group-features/' . $_GET['group_id']);
			return;
		}

		// Permissions.
		$perms = $i['group_perms'];
		$perms['admin'] = $i['group_admin'];
		foreach ($perms as $p => &$v)
		{
			if ($p == 'upload_type')
			{
				$v = $_POST[$p] ?? $perms[$p];
			}
			else if ($p != 'perm_list')
			{
				$v = (int) (count($_POST)
					? (isset($_POST[$p]) && in_array($_POST[$p], ['on', '1']))
					: $perms[$p]);
			}
		}
		Template::set('perms', $perms);

		// Informations éditables.
		$description = L10N::getTextGroupDesc((int) $i['group_id'], (string) $i['group_desc']);
		$name = L10N::getTextGroupName((int) $i['group_id'], (string) $i['group_name']);
		$title = L10N::getTextGroupTitle((int) $i['group_id'], (string) $i['group_title']);

		// Donnée de template : infos de groupe.
		Template::set('group',
		[
			'admin' => (int) $i['group_admin'],
			'crtdt' => L10N::dt(__('%A %d %B %Y'), $i['group_crtdt']),
			'description' => $description,
			'id' => $i['group_id'],
			'name' => $name,
			'nb_users' => L10N::formatNumber((int) $i['nb_users']),
			'perm_list' => $perms['perm_list'] ?? '',
			'perm_upload_type' => [
				[
					'current' => $perms['upload_type'] == 'all',
					'text' => __('Tous'),
					'value' => 'all'
				],
				[
					'current' => $perms['upload_type'] == 'images',
					'text' => __('Images'),
					'value' => 'images'
				],
				[
					'current' => $perms['upload_type'] == 'videos',
					'text' => __('Vidéos'),
					'value' => 'videos'
				]
			],
			'title' => $title
		]);

		// Données de template : infos d'édition.
		if ($i['group_id'] > 3)
		{
			Template::set('edition',
			[
				'description' => $_POST['description'] ?? $description,
				'name' => $_POST['name'] ?? $name,
				'title' => $_POST['title'] ?? $title
			]);
		}
		else
		{
			Template::set('edition',
			[
				'description' => $description,
				'name' => $name,
				'title' => $title
			]);
		}
	}

	/**
	 * Récupération des informations de tous les groupes.
	 *
	 * @return void
	 */
	public static function getGroups(): void
	{
		$sql = 'SELECT *,
			   (SELECT COUNT(*)
				  FROM {users}
				 WHERE group_id = g.group_id
				   AND user_status != "-2") AS nb_users
				  FROM {groups} AS g
			  ORDER BY group_id ASC';
		if (!DB::execute($sql))
		{
			return;
		};
		$db_groups = DB::fetchAll();
		foreach ($db_groups as &$i)
		{
			$groups[] =
			[
				'admin' => (bool) $i['group_admin'],
				'superadmin' => $i['group_id'] == 1,
				'description' => L10N::getTextGroupDesc(
					(int) $i['group_id'], (string) $i['group_desc']
				),
				'id' => $i['group_id'],
				'name' => L10N::getTextGroupName(
					(int) $i['group_id'], (string) $i['group_name']
				),
				'nb_users' => $i['nb_users'],
				'title' => L10N::getTextGroupTitle(
					(int) $i['group_id'], (string) $i['group_title']
				),
				'type_text' => $i['group_id'] == 1
					? __('Super-administrateur')
					: ($i['group_id'] == 2
						? __('Invité')
						: ($i['group_admin'] ? __('Administrateur') : __('Membre')))
			];
		}
		Template::set('groups', $groups);
	}

	/**
	 * Construit la liste des permissions d'accès aux catégories.
	 *
	 * @return void
	 */
	public static function getPermsCategories(): void
	{
		// Récupération des catégories.
		$sql = 'SELECT cat_id,
					   cat_parents,
					   cat_name,
					   parent_id,
					   "" AS blacklist_child,
					   "" AS whitelist_child,
					   CASE WHEN cat_filemtime IS NULL THEN "cat" ELSE "alb" END AS cat_type
				  FROM {categories}
				 WHERE cat_id != 1
			  ORDER BY LOWER(cat_name) ASC';
		if (!DB::execute($sql))
		{
			Report::error();
			return;
		}
		$categories = DB::fetchAll('cat_id');

		// Récupération des permissions d'accès aux catégories.
		$sql = 'SELECT cat_id, perm_list FROM {groups_permissions} WHERE group_id = ?';
		if (!DB::execute($sql, $_GET['group_id']))
		{
			Report::error();
			return;
		}
		$perms = DB::fetchAll();

		// On sépare la liste noire de la liste blanche.
		$perms_list = ['black' => [], 'white' => []];
		foreach ($perms as &$i)
		{
			$perms_list[$i['perm_list']][] = $i['cat_id'];
		}
		Template::set('blacklist', implode(',', $perms_list['black']));
		Template::set('whitelist', implode(',', $perms_list['white']));

		// Construction de la liste.
		$makelist = function($id = 1, $blacklist_parent = '', $whitelist_parent = '')
		use (&$makelist, &$categories, &$perms_list): array
		{
			$sublist = [];
			foreach ($categories as &$i)
			{
				if ($i['parent_id'] != $id)
				{
					continue;
				}

				// Liste noire.
				$blacklist = 'allowed';
				if ($blacklist_parent)
				{
					$blacklist = 'forbidden';
				}
				else if (in_array($i['cat_id'], $perms_list['black']))
				{
					$blacklist = 'forbidden';

					// On indique aux parents qu'un des enfants est dans la liste.
					$parents_id = Category::getParentsIdArray($i['cat_parents']);
					foreach ($parents_id as &$pid)
					{
						if ($pid > 1)
						{
							$categories[$pid]['blacklist_child'] = 'forbidden_child';
						}
					}
				}

				// Liste blanche.
				$whitelist = 'forbidden';
				if ($whitelist_parent)
				{
					$whitelist = 'allowed';
				}
				else if (in_array($i['cat_id'], $perms_list['white']))
				{
					$whitelist = 'allowed';

					// On indique aux parents qu'un des enfants est dans la liste.
					$parents_id = Category::getParentsIdArray($i['cat_parents']);
					foreach ($parents_id as &$pid)
					{
						if ((int) $pid > 1)
						{
							$categories[$pid]['whitelist_child'] = 'allowed_child';
						}
					}
				}

				// Ajout de la catégorie à la liste.
				$sublist[] =
				[
					'type' => 'element_start'
				];
				$sublist[] =
				[
					'type' => 'content',
					'cat_id' => $i['cat_id'],
					'cat_name' => $i['cat_name'],
					'cat_type' => $i['cat_type'],
					'blacklist' => $blacklist,
					'blacklist_child' => &$i['blacklist_child'],
					'blacklist_parent' => $blacklist_parent,
					'whitelist' => $whitelist,
					'whitelist_child' => &$i['whitelist_child'],
					'whitelist_parent' => $whitelist_parent
				];
				if ($i['cat_type'] == 'cat')
				{
					$r = $makelist(
						$i['cat_id'],
						$blacklist == 'forbidden' ? 'by_parent' : '',
						$whitelist == 'allowed' ? 'by_parent' : ''
					);
					if ($r)
					{
						$sublist = array_merge($sublist, $r);
					}
				}
				$sublist[] = ['type' => 'element_end'];

				// Si c'est un album, on le supprime du tableau des catégories.
				if ($i['cat_type'] == 'alb')
				{
					unset($categories[$i['cat_id']]);
				}
			}
			$list = [];
			if ($sublist)
			{
				$list[] = ['type' => 'list_start'];
				$list = array_merge($list, $sublist);
				$list[] = ['type' => 'list_end'];
				
			}
			return $list;
		};
		Template::set('categories', $makelist());
	}

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

		// On ne peut pas modifier
		// les permissions du premier groupe ni de son propre groupe.
		Template::set('edit_perms', isset($_GET['group_id']) && $_GET['group_id'] > 1
			&& $_GET['group_id'] != Auth::$infos['group_id']);

		// On ne peut pas supprimer
		// les trois premiers groupes ni son propre groupe.
		Template::set('delete_group', isset($_GET['group_id']) && $_GET['group_id'] > 3
			&& $_GET['group_id'] != Auth::$infos['group_id']);
	}
}
?>