<?php
/**
 * Define a notification.
 * @author Valentin CARRUESCO
 * @category Plugin
 * @license MIT
 */
class Notification extends Entity{
	public $id,$label,$html,$type,$meta,$end,$start,$pinned;
	protected $TABLE_NAME = 'notification';
	public $fields =
	array(
		'id' => 'key',
		'label' => 'string',
		'html' => 'longstring',
		'type' => 'string',
		'meta' => 'longstring',
		'start' => 'date',
		'end' => 'date',
		'pinned' => 'int'
	);

	function __construct(){
 		parent::__construct();
 		$this->pinned = 0;
	}

	public static function types($key = null){
		global $conf;
		$types = array(
			'notice' => array(
				'label' =>'Information',
				'color' =>'#007fdc',
				'icon'  =>'far fa-flag',
				'description'  =>"Notifications d'informations mineures",
				'default_methods' => array(
					'interface' => !empty($conf->get('notice_interface')) ? $conf->get('notice_interface') : true,
					'mail' => !empty($conf->get('notice_mail')) ? $conf->get('notice_mail') : false
				)
			),
			'announcement' => array(
				'label' =>'Annonce',
				'color' =>'#30336b',
				'icon'  =>'fas fa-bullhorn',
				'description'  =>"Annonce générale",
				'default_methods' => array(
					'interface' => !empty($conf->get('announcement_interface')) ? $conf->get('announcement_interface') : true,
					'mail' => !empty($conf->get('announcement_mail')) ? $conf->get('announcement_mail') : false
				)
			),
			'alert' => array(
				'label' =>'Alerte',
				'color' =>'#ff3100',
				'icon'  =>'fas fa-fire',
				'description'  =>"Notifications importantes ou critiques",
				'default_methods' => array(
					'interface' => !empty($conf->get('alert_interface')) ? $conf->get('alert_interface') : true,
					'mail' => !empty($conf->get('alert_mail')) ? $conf->get('alert_mail') : false
				)
			)
		);

		Plugin::callHook('notification_type',array(&$types));
		return $key ? (isset($types[$key]) ? $types[$key] : null)  : $types;
	}

	public static function categories(){
		$categories = array();

		foreach(Notification::types() as $slug => $type){
			$type['slug'] = $slug;
			if(!isset($type['category'])) $type['category'] = 'Général';
			if(!isset($categories[slugify($type['category'])])) $categories[slugify($type['category'])] = array('label'=>$type['category'],'items'=>array());
			$categories[slugify($type['category'])]['items'][] = $type;
		}

		return $categories;
	}

	public static function emit($infos){
		global $myFirm;
		$sendTypes = array();
		Plugin::callHook("notification_methods", array(&$sendTypes));

		$default = array(
			'label' => "Notification sans titre",
			'html' => "",
			'type' => "notice",
			'pinned' => 0,
			'meta' => array(),
			'start' => time(),
			'end' => strtotime('+3month'),
			'recipients' => array()
		);
		$infos = array_merge($default,$infos);

		$notification = new Notification();
		$notification->label = $infos['label'];
		$notification->html = $infos['html'];
		$notification->type = $infos['type'];
		$notification->pinned = $infos['pinned'];
		$notification->meta = json_encode($infos['meta']);
		$notification->end = $infos['end'];
		$notification->start = $infos['start'];
		$notification->save();

		$users = User::getAll();
		$users_rights = array();
		foreach ($users as $user) {
			if(!is_object($myFirm)) continue;
			$ranks = $user->getRanksId($myFirm->id);
			if (isset($ranks)) $users_rights[$user->login] = $ranks;
		}

		// Traitement des rangs
		$recipients = array();
		foreach ($infos['recipients'] as $recipient) {
			if (is_numeric($recipient)) {
				$users = array_keys(array_filter($users_rights, function($v) use ($recipient) {
				    return in_array($recipient, $v);
				}));
				$recipients = array_merge($users, $recipients);
			} else {
				$recipients[] = $recipient;
			}
		}
		$recipients = array_unique($recipients);

		// pour chaque destinataire, vérification des préférences
		foreach ($recipients as $recipient) {
			//$userPreferences = Notification::getNotificationPreferences($recipient);
			$userPreferences = Notification::settingPreferences($recipient);
			// pour chaque type d'envoi
			foreach ($sendTypes as $sendType) {
				if(!isset($userPreferences[$infos['type']]) || !isset($userPreferences[$infos['type']][$infos['type'].'_'.$sendType['slug']]) || !$userPreferences[$infos['type']][$infos['type'].'_'.$sendType['slug']]) continue;
				$sendType['callback']($recipient, $infos,$notification);
			}
		}
	}

	public static function clear(){
		require_once(__DIR__.SLASH.'UserNotification.class.php');
		$toDelete = array();
		//on fetch pour economiser de la mémoire
		foreach (Notification::staticQuery('SELECT id FROM {{table}} WHERE end < ?',array(time()))->fetchAll() as $notification) {
			$toDelete[] = $notification['id'];
		}
		Notification::delete(array('id:IN'=>$toDelete));
		UserNotification::delete(array('notification:IN'=>$toDelete));
	}

	public static function settingPreferences($user, $userPreferences=array()){
		global $conf;
		require_once(__DIR__.SLASH.'UserNotification.class.php');

		// récupération préférences par défault
		$defaultPreferences = array();
		foreach(Notification::types() as $slug => $type){
			$defaultMethods = array();
			foreach ($type['default_methods'] as $method => $state)
				$defaultMethods[$slug.'_'.$method] = $state;

			$defaultPreferences[$slug] = $defaultMethods;
		}

		if(empty($userPreferences)){
			// récupération préférences utilisateur
			$preferences = UserPreference::loadAll(array('user'=>$user, 'key'=>'notification_categories'));
			$userPreferences = array();
			foreach($preferences as $preference)
				$userPreferences = json_decode($preference->value, JSON_OBJECT_AS_ARRAY);
		}

		$notificationPreferences = array();
		foreach ($defaultPreferences as $slug => $type){
			$tab = array();
			$notificationPreferences[$slug] = $defaultPreferences[$slug];

			foreach ($type as $method => $state){
				if(isset($userPreferences[$slug][$method])){
					$tab[$method] =  $userPreferences[$slug][$method];
					unset($userPreferences[$slug][$method]);
				}else{
					$tab[$method] = $conf->get($method) ? $conf->get($method) : $defaultPreferences[$slug][$method];
				}
			}


			$notificationPreferences[$slug] = $tab;
		}

		foreach($userPreferences as $slug=>$types){
			if(!isset($notificationPreferences[$slug])) $notificationPreferences[$slug] = array();
			if(!is_array($types)) continue;
			$notificationPreferences[$slug] = array_merge($notificationPreferences[$slug],$types);
		}

		return $notificationPreferences;
	}
}
?>