<?php
declare(strict_types = 1);

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

/**
 * Gestion des commentaires.
 *
 * @license https://www.gnu.org/licenses/gpl-3.0.html
 * @link https://www.igalerie.org/
 */
class AdminComments extends Admin
{
	/**
	 * Actions sur la sélection.
	 *
	 * @return void
	 */
	public static function actions(): void
	{
		if (isset($_POST['cancel']) || !isset($_POST['selection']))
		{
			return;
		}
		switch (self::_getSelectedIds($selected_ids))
		{
			case 'activate' :
				$r = Comment::status($selected_ids, 1);
				if ($r < 0)
				{
					Report::error();
				}
				else if ($r < 1)
				{
					Report::info(__('Aucun commentaire n\'a été activé.'));
				}
				else
				{
					Report::success($r > 1
						? sprintf(__('%s commentaires ont été activés.'), $r)
						: __('1 commentaire a été activé.'));
				}
				break;

			case 'ban_author' :
				$r = Comment::ban('names', $selected_ids);
				if ($r < 0)
				{
					Report::error();
				}
				else if ($r < 1)
				{
					Report::info(__('Aucun auteur n\'a été ajouté à la liste noire.'));
				}
				else
				{
					Report::success($r > 1
						? sprintf(__('%s auteurs ont été ajoutés à la liste noire.'), $r)
						: __('1 auteur a été ajouté à la liste noire.'));
				}
				break;

			case 'ban_ip' :
				$r = Comment::ban('ips', $selected_ids);
				if ($r < 0)
				{
					Report::error();
				}
				else if ($r < 1)
				{
					Report::info(__('Aucune IP n\'a été ajoutée à la liste noire.'));
				}
				else
				{
					Report::success($r > 1
						? sprintf(__('%s IP ont été ajoutées à la liste noire.'), $r)
						: __('1 IP a été ajoutée à la liste noire.'));
				}
				break;

			case 'deactivate' :
				$r = Comment::status($selected_ids, 0);
				if ($r < 0)
				{
					Report::error();
				}
				else if ($r < 1)
				{
					Report::info(__('Aucun commentaire n\'a été désactivé.'));
				}
				else
				{
					Report::success($r > 1
						? sprintf(__('%s commentaires ont été désactivés.'), $r)
						: __('1 commentaire a été désactivé.'));
				}
				break;

			case 'delete' :
				$r = Comment::delete($selected_ids);
				if ($r < 0)
				{
					Report::error();
				}
				else if ($r < 1)
				{
					Report::info(__('Aucun commentaire n\'a été supprimé.'));
				}
				else
				{
					Report::success($r > 1
						? sprintf(__('%s commentaires ont été supprimés.'), $r)
						: __('1 commentaire a été supprimé.'));
				}
				break;
		}
	}

	/**
	 * Édition des informations.
	 *
	 * @return void
	 */
	public static function edit(): void
	{
		if (!isset($_POST['comments']) || !isset($_POST['save']))
		{
			return;
		}

		$r = Comment::edit($_POST['comments']);
		if ($r < 0)
		{
			Report::error();
		}
		else if ($r < 1)
		{
			Report::info(__('Aucun commentaire n\'a été modifié.'));
		}
		else
		{
			Report::success($r > 1
				? sprintf(__('%s commentaires ont été modifiés.'), $r)
				: __('1 commentaire a été modifié.'));
		}
	}

	/**
	 * Construit une liste des catégories contenant des commentaires.
	 *
	 * @return void
	 */
	public static function getCategoriesLists(): void
	{
		$get_url = function($page)
		{
			$filter = '';
			if (isset($_GET['filter']))
			{
				switch ($_GET['filter'])
				{
					case 'pending' :
						$filter = '/' . $_GET['filter'];
						break;
					case 'date' :
					case 'ip' :
					case 'item' :
					case 'search' :
					case 'user' :
						$filter = '/' . $_GET['filter'] . '/' . $_GET['filter_value'];
						break;
				}
			}
			return App::getURL('comments/' . $page . $filter);
		};
		$cat_id = isset($_GET['filter_cat_id']) && $_GET['filter_cat_id'] > 0
			? $_GET['filter_cat_id']
			: ($_GET['category_id'] ?? 1);
		$categories = Category::getList($makelist, $get_url, (int) $cat_id);
		if (!$makelist)
		{
			return;
		}

		// Réduction de la liste "parcourir".
		self::_sqlWhere($sql_where, $params);
		$sql = "SELECT cat.cat_id,
					   COUNT(com_id) AS count
				  FROM {comments} AS com
			 LEFT JOIN {items} AS i USING (item_id)
			 LEFT JOIN {categories} AS cat USING (cat_id)
				 WHERE cat.cat_id = i.cat_id
				   AND $sql_where
			  GROUP BY cat.cat_id";
		if (!DB::execute($sql, $params))
		{
			return;
		}
		$infos = DB::fetchAll('cat_id', 'count');
		Category::reduceList($categories, $infos);
		self::_categoriesBrowse($makelist($categories));
	}

	/**
	 * Récupération des commentaires.
	 *
	 * @return void
	 */
	public static function getComments(): void
	{
		Template::set('objects_count', 0);

		// Nombre de commentaires par page.
		$nb_per_page = Auth::$infos['user_prefs']['comments']['nb_per_page'];

		// Clause WHERE.
		self::_sqlWhere($sql_where, $params);

		// Limitation à la catégorie courante.
		if (isset($_GET['category_id']) && $_GET['category_id'] > 1)
		{
			$sql = 'SELECT cat_id,
						   cat_path,
						   cat_name,
						   cat_parents,
						   CASE WHEN cat_filemtime IS NULL
								THEN "category" ELSE "album"
								 END AS cat_type
					  FROM {categories}
					 WHERE cat_id = ?';
			if (DB::execute($sql, $_GET['category_id']))
			{
				$cat_infos = DB::fetchRow();
				$sql_where .= ' AND item_path LIKE :path';
				$params['path'] = DB::likeEscape($cat_infos['cat_path']) . '/%';
			}
		}
		if (!isset($cat_infos))
		{
			$cat_infos = 
			[
				'cat_id' => 1,
				'cat_name' => __('galerie'),
				'cat_parents' => '1',
				'cat_type' => NULL
			];
		}

		// Fil d'Ariane.
		Template::breadcrumb($cat_infos, FALSE, 'comments/category');

		// Nombre de commentaires.
		$sql = "SELECT COUNT(*)
				  FROM {comments} AS com
			 LEFT JOIN {items} USING (item_id)
				 WHERE $sql_where";
		if (!DB::execute($sql, $params))
		{
			return;
		}
		Template::set('objects_count', $nb_comments = DB::fetchVal());

		// Nombre de pages.
		Template::set('nb_pages', ceil($nb_comments / $nb_per_page));
		$sql_limit_start = $nb_per_page * ($_GET['page'] - 1);

		// Critère de tri.
		$sql_order_by = Auth::$infos['user_prefs']['comments']['order_by_column'];
		$sql_order_by_order = Auth::$infos['user_prefs']['comments']['order_by_order'];

		// Récupération des commentaires.
		$sql = "SELECT com.*,
					   user_avatar,
					   user_login,
					   user_nickname,
					   item_adddt,
					   item_name,
					   item_path,
					   item_type,
					   item_duration,
					   item_orientation,
					   item_status,
					   cat.cat_id,
					   cat_name
				  FROM {comments} AS com
			 LEFT JOIN {users} AS u USING (user_id)
			 LEFT JOIN {items} AS i USING (item_id)
			 LEFT JOIN {categories} AS cat USING (cat_id)
				 WHERE $sql_where
			  ORDER BY com_$sql_order_by $sql_order_by_order
			     LIMIT $sql_limit_start,$nb_per_page";
		if (!DB::execute($sql, $params))
		{
			return;
		}
		$db_comments = DB::fetchAll('com_id');
		if (!self::_objectsNoResult(count($db_comments)))
		{
			return;
		}

		// Formatage des données.
		$comments = [];
		foreach ($db_comments as &$i)
		{
			$comments[] = self::getFormatedInfos($i);
		}
		Template::set('comments', $comments);
	}

	/**
	 * Formate les informations d'un commentaire.
	 *
	 * @param array $i
	 *   Informations brutes du commentaire.
	 *
	 * @return array
	 */
	public static function getFormatedInfos(array &$i): array
	{
		return
		[
			'id' => $i['com_id'],
			'gallery_link' => Config::$params['comments']
				&& $i['com_status'] == 1 && $i['item_status'] == 1
				? App::getURLGallery('item/' . $i['item_id']) . '#comment-' . $i['com_id']
				: NULL,

			// État.
			'activated' => $i['com_status'] == 1,
			'deactivated' => $i['com_status'] == 0,
			'pending' => $i['com_status'] == -1,
			'status' => $i['com_status'],
			'status_text' => L10N::getTextStatus((int) $i['com_status']),

			// Album.
			'album_id' => (int) $i['cat_id'],
			'album_link' => App::getURL('album/' . $i['cat_id']),
			'album_name' => $i['cat_name'],

			// Dates.
			'date_created' => L10N::dt(__('%A %d %B %Y'), $i['com_crtdt']),
			'datetime_created' => L10N::dt(__('%A %d %B %Y à %H:%M:%S'), $i['com_crtdt']),
			'date_updated' => $i['com_lastupddt']
				? L10N::dt(__('%A %d %B %Y'), $i['com_lastupddt'])
				: NULL,
			'datetime_updated' => $i['com_lastupddt']
				? L10N::dt(__('%A %d %B %Y à %H:%M:%S'), $i['com_lastupddt'])
				: NULL,

			// Filtres.
			'filter_album_link' => App::getURL('comments/album/' . $i['cat_id']),
			'filter_date_link' => App::getURL('comments/date/' . substr($i['com_crtdt'], 0, 10)),
			'filter_ip_link' => App::getURL('comments/ip/' . $i['com_ip']),
			'filter_item_link' => App::getURL('comments/item/' . $i['item_id']),
			'filter_user_link' => App::getURL('comments/user/' . $i['user_id']),

			// Fichier.
			'item_duration_text' => $i['item_duration']
				? App::formatDuration($i['item_duration'])
				: '00:00',
			'item_id' => $i['item_id'],
			'item_link' => App::getURL('item-edit/' . $i['item_id']),
			'item_name' => $i['item_name'],
			'item_text' => Item::isVideo($i['item_type'])
				? __('la vidéo %s')
				: __('la photo %s'),
			'item_thumb_src' => function($size = '', $quality = '') use ($i)
			{
				$thumb_src = App::getThumbSource('item',
					$i, self::$thumbSize, self::$thumbQuality);
				return htmlspecialchars($thumb_src);
			},
			'item_type' => Item::isVideo($i['item_type']) ? 'video' : 'image',

			// Message.
			'message' => $i['com_message'],

			// Utilisateur.
			'user_avatar_src' => Avatar::getURL(
				(int) $i['user_id'], (bool) $i['user_avatar']
			),
			'user_email' => $i['user_id'] == 2 ? $i['com_email'] : NULL,
			'user_id' => $i['user_id'],
			'user_ip' => $i['com_ip'],
			'user_link' => $i['user_id'] == 2
				? NULL
				: App::getURL('user/' . $i['user_id']),
			'user_name' => $i['user_id'] == 2
				? $i['com_author']
				: User::getNickname($i['user_login'], $i['user_nickname']),
			'user_website' => $i['user_id'] == 2 ? $i['com_website'] : NULL
		];
	}

	/**
	 * Modification des options.
	 *
	 * @return void
	 */
	public static function options(): void
	{
		require_once(__DIR__ . '/AdminSettings.class.php');
		AdminSettings::config();

		// Ordre d'affichage des commentaires.
		$comments_order_by = Config::$params['comments_order_by'];
		Template::set('comments_order_by', [
			[
				'selected' => $comments_order_by == 'ASC',
				'text' => __('Du plus ancien au plus récent'),
				'value' => 'ASC'
			],
			[
				'selected' => $comments_order_by == 'DESC',
				'text' => __('Du plus récent au plus ancien'),
				'value' => 'DESC'
			],
		]);
	}

	/**
	 * Informations de template pour le moteur de recherche.
	 *
	 * @param array $functions
	 *
	 * @return void
	 */
	public static function tplSearch(array &$functions): void
	{
		// Colonnes.
		$columns = $functions['columns'](
		[
			'com_author' => FALSE,
			'com_email' => FALSE,
			'com_ip' => FALSE,
			'com_message' => TRUE,
			'com_website' => FALSE
		]);

		// État.
		$status = $functions['select']('status',
		[
			[
				'value' => '*',
				'text' => '*' . __('Tous')
			],
			[
				'value' => '1',
				'text' => __('Activé')
			],
			[
				'value' => '0',
				'text' => __('Désactivé')
			],
			[
				'value' => '-1',
				'text' => __('En attente')
			]
		]);

		Template::set('search', $functions['date']());
		Template::set('search',
		[
			'date' => self::$search->options['date'] ?? FALSE,
			'date_column' => self::$search->options['date_column'] ?? 'com_crtdt',
			'columns' => $columns,
			'status' => $status
		]);
	}

	/**
	 * 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('comments'),
			'title' => __('Commentaires')
		]);
		Template::set('section', str_replace('_', '-', $tpl_filename));
		Template::set('template',
		[
			'file' => $tpl_filename . '.tpl.php'
		]);
	}



	/**
	 * Clause WHERE d'une requête SQL.
	 *
	 * @param mixed $sql
	 * @param mixed $params
	 *
	 * @return void
	 */
	private static function _sqlWhere(&$sql, &$params): void
	{
		$sql = '1=1';
		$params = [];
		switch ($_GET['filter'] ?? '')
		{
			case 'date' :
				$sql = 'com_crtdt >= :date_start AND com_crtdt <= :date_end';
				$params =
				[
					'date_start' => $_GET['filter_value'] . ' 00:00:00',
					'date_end' => $_GET['filter_value'] . ' 23:59:59'
				];
				break;

			case 'ip' :
				$sql = 'com_ip = :filter';
				$params['filter'] = $_GET['filter_value'];
				break;

			case 'item' :
				$sql = 'com.item_id = :filter';
				$params['filter'] = $_GET['filter_value'];
				break;

			case 'pending' :
				$sql = 'com_status = "-1"';
				break;

			case 'search' :
				if (!$search = self::$search->sql())
				{
					App::redirect($_GET['q_filterless']);
				}
				$sql = $search['sql'];
				$params = $search['params'];
				break;

			case 'user' :
				$sql = 'com.user_id = :filter';
				$params['filter'] = $_GET['filter_value'];
				break;
		}
	}
}
?>