<?php
/**
 * Define a history.
 * @author  Valentin CARRUESCO
 * @category Core
 * @license MIT
 */
class History extends Entity{

	public $id;
	public $scope; //Scope (plugin, page...) (Texte)
	public $uid; //Item ID/UID concerné (Texte)
	public $comment; //Commentaire (Texte Long)
	public $type; //Type d'historique (Texte)
	public $importance; //Importance de message (Texte)
	public $meta; //Meta données (Texte Long)
	public $sort; //Ordre (int)

	const TYPE_READ = 'read';
	const TYPE_COMMENT = 'comment';
	const TYPE_EDIT = 'edit';
	const TYPE_DELETE = 'delete';

	const IMPORTANCE_NORMAL = 'normal';
	const IMPORTANCE_IMPORTANT = 'important';

	public $entityLabel = 'Historique';

	protected $TABLE_NAME = 'history';
	public $fields = array(
		'id' => array('label'=> 'Identifiant' , 'type'=>'key'),
		'scope' => array('label'=> 'Périmetre de l\'entité liée' , 'type'=>'text'),
		'uid' => array('label'=> 'Identifiant de l\'entité liée' , 'type'=>'text'),
		'comment' => array('label'=> 'Commentaire' , 'type'=>'textarea'),
		'type' => array('label'=> 'Type d\'historique' , 'type'=>'text'),
		'importance' => array('label'=> 'Importance' , 'type'=>'text'),
		'sort' => array('label'=> 'Ordre' , 'type'=>'integer'),
		'meta' => array('label'=> 'Meta informations' , 'type'=>'textarea')
	);

	function __construct(){
		parent::__construct();
		$this->importance = 'normal';
	}

	public static function importance($key=null){
		$importances = array(
			self::IMPORTANCE_NORMAL => array('label'=>'Normal','color' => '#222222'),
			self::IMPORTANCE_IMPORTANT => array('label'=>'Urgent','color' => '#dc3545'),
		);
		if(!isset($key)) return $importances;
		return isset($importances[$key]) ? $importances[$key] : array();
	}

	//Colonnes indexées
	public $indexes = array();

	public static function types($key=null){
		$types = array(
			self::TYPE_READ => array('slug'=>self::TYPE_READ,'label' => 'Consultation','icon' => 'far fa-eye','color' => '#e2ec55'),
			self::TYPE_COMMENT => array('slug'=>self::TYPE_COMMENT,'label' => 'Commentaire','icon' => 'far fa-comments','color' => '#6ab04c'),
			self::TYPE_EDIT => array('slug'=>self::TYPE_EDIT,'label' => 'Édition','icon' => 'fas fa-marker','color' => '#686de0'),
			self::TYPE_DELETE => array('slug'=>self::TYPE_DELETE,'label' => 'Suppression','icon' => 'fas fa-trash-restore','color' => '#eb4d4b')
		);
		Plugin::callHook('history_type',array(&$types));
		if(!isset($key)) return $types;
		return isset($types[$key]) ? $types[$key] : array('slug'=>'undefined','label'=>'','icon'=>'','color'=>'');
	}

	//Ajout rapide d'un historique
	public static function put($scope,$uid,$comment,$type=null){
		$history = new History();
		$history->scope = $scope;
		$history->uid = $uid;
		$history->comment = $comment;
		if(isset($type)) $history->type = $type;
		$history->save();
	}

	// Créé un historique sur changement d'une entité
	// prend en compte le scope, l'item dans l'ancien etat, l'item dans l'etat actuel
	// et détaille en Human readable les modifications
	public static function entityChange($scope,$oldItem,$item){
		$differenties = Entity::compare($oldItem,$item);
		$fieldTypes = FieldType::available();
		$detail = '';
		foreach($differenties as $difference){
			$fields = $oldItem->fields(false);
			$fieldKey = $difference['field'];
			if(!isset($fields[$fieldKey])) continue;
			$field =  $fields[$fieldKey];

			$value1 = $difference['value1'];
			$value2 = $difference['value2'];

			//gestion des transformations de valeurs de liste en dur
			if($field['fieldtype']=='list' && method_exists ($item,$fieldKey.'s' ) ){
				$method = $fieldKey.'s';
				$value1 = $item::$method($difference['value1']);
				$value1 =isset($value1['label']) ? $value1['label'] : $difference['value1'];
				$value2 = $item::$method($difference['value2']);
				$value2 =isset($value2['label']) ? $value2['label'] : $difference['value2'];
			//gestion de stransformations de valeurs de fieldtype
			}else if(isset($fieldTypes[$field['fieldtype']]) ){
				$fieldType = $fieldTypes[$field['fieldtype']];
				if(property_exists($fieldType,'onRawDisplay')){
					$method = $fieldType->onRawDisplay;
					$value1 = $method($difference['value1'], $field);
					$value2 = $method($difference['value2'], $field);
				}
				//si le champs est une foreign key on affiche l'eventuel libellé de cette foreign key
				if(isset($field['link'])){
					require_once $field['link'];
					$class =  str_replace('.class.php','',basename($field['link']));
					if(property_exists($class,'label')){

						$instance1 = $class::getById($difference['value1']);
						if($instance1) $value1 =  $instance1->label;

						$instance2 = $class::getById($difference['value2']);
						if($instance2) $value2 =  $instance2->label;
					}
				}
			}

			$detail.= '<br/>Champ <code>'.$field['label'].'</code> ';
			if(empty($value1)){
				$detail.= ' ajout de la valeur <span class="font-weight-bold">'.truncate($value2,100).'</span>';
			}else if(empty($value2)){
				$detail.= ' suppression de la valeur <span class="font-weight-bold">'.truncate($value1,100).'</span>';
			}else{
				$detail.=' modifié de <span class="font-weight-bold">'.truncate($value1,100).'</span> en <span class="font-weight-bold">'.truncate($value2,100).'</span>';
			}
		}

		$history = new History();
		$history->scope = $scope;
		$history->uid = $item->id;
		$history->comment = (!empty($oldItem->id) ? "Modification":"Création")." ".$detail;
		$history->type = History::TYPE_EDIT;
		$history->save();
	}
}
