<?php
	
	Class User {
		
		public $userSessionName;
		public $avatarDir;
		private $session;
		private $db;
		private $config;
		
		function __construct() {
			global $config, $session, $db;
			
			$this->userSessionName = 'userSession';
		
			$this->db = $db;
			$this->session = $session;
			$this->avatarDir = AVATAR_IMG_DIR;
			$this->config = $config;
		}
		
		public function login($userData=null) {
			return $this->refreshUserSession($userData);
		}
		
		public function refreshUserSession($userData=null) {
			if (is_array($userData) && !empty($userData)) {
				
				if (!isset($userData['id'])) return false;
				if (!isset($userData['username'])) return false;
				if (!isset($userData['name'])) return false;
				if (!isset($userData['surname'])) return false;
				if (!isset($userData['language_default'])) return false;
				if (!isset($userData['language_data'])) return false;
				if (!isset($userData['country_data'])) return false; //Could be an empty array
				if (!isset($userData['roles'])) return false;
				if (!isset($userData['updated_at'])) return false;
				if (!isset($userData['group_id'])) return false;
				
				$roleLocale = [];
				if (is_array($userData['roles'])) {
					foreach($userData['roles'] as $roleItem) {
						$roleLocale[$roleItem['id']] = $roleItem['role_names'];
					}
				}
				
				$data['userId'] = $userData['id'];
				$data['userStatus'] = $userData['status'];
				$data['userUsername'] = $userData['username'];
				$data['userName'] = $userData['name'];
				$data['userSurname'] = $userData['surname'];
				$data['userDefaultLang'] = $userData['language_default'];
				$data['userDefaultString'] = isset($userData['language_data']['name_string']) ? $userData['language_data']['name_string'] : null;
				$data['userCountryId'] = isset($userData['country_data']['id']) ? $userData['country_data']['id'] : 0;
				$data['userCountryName'] = isset($userData['country_data']['country_name']) ? $userData['country_data']['country_name'] : '';
				$data['userCountryCode'] = isset($userData['country_data']['country_iso2_code']) ? $userData['country_data']['country_iso2_code'] : '';
				$data['userRoles'] = $userData['roles'];
				$data['userRolesLocale'] = is_array($roleLocale) ? $roleLocale : [];
				$data['userUpdatedAt'] = $userData['updated_at'];
				$data['userGroupId'] = $userData['group_id'];
				
				$medicalSpecialties = [];
				if (isset($roleLocale[REFERRER_ROLE_ID])) {
					$medicalSpecialties = $this->getMedicalSpecialties($userData['id']);
				}
				
				$data['medicalSpecialties'] = $medicalSpecialties;
				
				$this->session->refreshSession($this->userSessionName, $data);
			}
			
			return $this->session->sessionExists($this->userSessionName);
		}
		
		public function refreshSessionField($fieldKey, $value=null) {
			
			$userSession = $this->getUser();
			
			if (isset($userSession[$fieldKey])) {
				$userSession[$fieldKey] = $value;
				
				return $this->session->refreshSession($this->userSessionName, $userSession);
			}
			
			return false;
		}
		
		public function logout() {
			return $this->session->deleteSession($this->userSessionName);
		}
		
		public function getValidUserData($username='') {
			return $this->db->where('status', 0, '<>')->where('username', $username, 'like')->getOne('users');
		}
		
		public function setUserMeta($user=[]) {
			$user['roles'] = $this->getUserRolesDB($user['id']);
			$user['country_data'] = [];
			$user['language_data'] = [];
			
			$countryData = $this->db->where('country_iso2_code', $user['country_code'])->getOne('countries');
			if (is_array($countryData) && !empty($countryData)) {
				$user['country_data'] = $countryData;
			}
			
			$languageData = $this->db->where('lang_code', $user['language_default'])->getOne('users_languages');
			if (is_array($languageData) && !empty($languageData)) {
				$user['language_data'] = $languageData;
			}
			
			return $user;
		}
		
		public function getUserId() {
			$userData = $this->session->getSessionValue($this->userSessionName);
			
			if (is_array($userData) && isset($userData['userId'])) return (int)$userData['userId'];
			
			return false;
		}
		
		public function isUsernameInUse($username='') {
			$return = true;
			
			$user = $this->db->where('username', $username, 'like')->getOne('users');
			$return = is_array($user) && !empty($user) ? true : false;
			
			return $return;
		}
		
		public function getUserStatus() {
			$userData = $this->session->getSessionValue($this->userSessionName);
			
			if (is_array($userData) && isset($userData['userStatus'])) return (int)$userData['userStatus'];
			
			return false;
		}
		
		public function getGroupId() {
			$userData = $this->session->getSessionValue($this->userSessionName);
			
			if (is_array($userData) && isset($userData['userGroupId'])) return (int)$userData['userGroupId'];
			
			return false;
		}
		
		public function getUserLang() {
			$userData = $this->session->getSessionValue($this->userSessionName);
			
			if (is_array($userData) && isset($userData['userDefaultLang'])) return $userData['userDefaultLang'];
			
			return false;
		}
		
		public function getMedicalSpecialties($passedUserId=0) {
			$userId = $passedUserId == 0 ? $this->getUserId() : $passedUserId;
			$specialties = [];
			
			$results = $this->db
				->where('umst.user_id', $userId)
				->join('users_medical_specialties ums', 'ums.id=umst.specialty_id', 'INNER')
				->orderBy('ums.description', 'asc')
				->get('users_medical_specialties_to umst', null, ['ums.description']);
				
			if (is_array($results)) {
				foreach($results as $result) {
					$specialties[] = _($result['description']);
				}
			}
			
			return $specialties;
		}
		
		public function getUser() {
			if ($this->isLogged()) {
				return $this->session->getSessionValue($this->userSessionName);
			} else {
				return false;
			}
		}
		
		public function getUserField($fieldKey='') {
			$user = $this->getUser();
			
			if ($user !== false) {
				return isset($user[$fieldKey]) ? $user[$fieldKey] : false;
			}
			
			return false;
		}
		
		//Deprecated
		public function getUserRoles() {
			$userData = $this->session->getSessionValue($this->userSessionName);
			
			if (is_array($userData) && isset($userData['userRoles'])) {
				return $userData['userRoles'];
			}
			
			return false;
		}
		
		public function getUserRolesLocale() {
			$userData = $this->session->getSessionValue($this->userSessionName);
			
			if (is_array($userData) && isset($userData['userRolesLocale'])) {
				return $userData['userRolesLocale'];
			}
			
			return false;
		}
		
		public function getUserDB($passedUserId=0) {
			$userId = $passedUserId == 0 ? $this->getUserId() : $passedUserId;
			
			if ($userId !== false) {
				return $this->db->where('id', $userId)->getOne('users');
			}
			
			return false;
		}
		
		public function getUserRolesDB($passedUserId=false) {
			$userId = $passedUserId !== false ? $passedUserId : $this->getUserId();
			$roleList = [];
			
			if ($userId !== false) {
				
				$roles = $this->db->rawQuery("SELECT ur.id, ur.name_translations, GET_JSON_VALUE_BY_KEY(ur.name_translations, u.language_default, '".$this->config['settings']['default-lang']."') AS role_names FROM users_roles_to AS urt JOIN users_roles AS ur ON ur.id=urt.role_id JOIN users AS u on u.id=urt.user_id WHERE urt.user_id=? AND ur.role_status=?", [$userId, 1]);
				
				if (is_array($roles) && !empty($roles)) {
					foreach($roles as $index => $values) {
						$roleList[$values['id']] = $values;
					}
				}
				
			}
			
			return $roleList;
		}
		
		//Deprecated (see userController)
		public function getRoleList() {
			return [];
			$list = [];
			$helper = new Helper();
			$roles = $this->getUserField('userRoles');
			
			if (is_array($roles) && !empty($roles)) {
				foreach($roles as $role) {
					$list[] = $helper->getJsonTranslation($role['name_translations'], $this->getUserLang(), $role['role_name']);
				}
			}
			
			return $list;
		}
		
		public function gerRoleStringByArray($array=[]) {
			$tmp = [];
			$helper = new Helper();
			
			if (is_array($array) && !empty($array)) {
				foreach($array as $item) {
					$tmp[] = $helper->getJsonTranslation($item['name_translations'], $this->getUserLang(), $item['role_name']);
				}
			}
			
			return implode(', ', $tmp);
		}
		
		/*public function getRoles() {
			$roles = $this->db->where('id', 1, '<>')->where('role_status', 1)->orderBy('role_name', 'ASC')->get('users_roles');
			
			$roles = $this->db->rawQuery("SELECT ur.id, ur.name_translations, GET_JSON_VALUE_BY_KEY(ur.name_translations, u.language_default, ?) AS role_names FROM users_roles_to AS urt JOIN users_roles AS ur ON ur.id=urt.role_id JOIN users AS u on u.id=urt.user_id WHERE urt.user_id=? AND ur.role_status=?", [$this->config['settings']['default-lang'], $userId, 1]);
			
			if (is_array($roles) && !empty($roles)) {
			
				$helper = new Helper();
			
				foreach($roles as $index => $role) {
					$roles[$index]['role_name'] = $helper->getJsonTranslation($role['name_translations'], $this->getUserLang(), $role['role_name']);
				}
			}
			
			return !(empty($roles) && is_array($roles)) ? $roles : false;
		}*/
		
		public function getRoles() {
			$list = [];
			$roles = $this->db->where('r.role_status', 1)->where('r.id', 1, '<>')->orderBy('role_name', 'asc')->get('users_roles r', null, ["r.id", "GET_JSON_VALUE_BY_KEY(r.name_translations, '".$this->getLanguage()."', '".$this->config['settings']['default-lang']."') role_name"]);
			
			if (is_array($roles) && !empty($roles)) {
				foreach($roles as $role) {
					$list[$role['id']] = $role['role_name'];
				}
			}
			
			return $list;
		}
		
		public function getUserAltLangsDB($passedUserId=0) {
			$userId = $passedUserId == 0 ? $this->getUserId() : $passedUserId;
			$altLangList = [];
			
			if ($userId !== false) {
				$altLangs = $this->db->rawQuery("SELECT ul.* FROM users_languages_to AS ult JOIN users_languages AS ul ON ul.id=ult.language_id WHERE ult.user_id=?", [$userId]);
				if (is_array($altLangs) && !empty($altLangs)) {
					foreach($altLangs as $index => $values) {
						$altLangList[$values['id']] = $values;
					}				
				}
			}
			return $altLangList;
		}
		
		public function disclaimerAccepted() {
			$userId = $this->getUserId();
			$result = $this->db->where('id', $userId)->getOne('users');
			return $result['disclaimers_accepted'] && (int)$result['disclaimers_accepted'] > 0 ? true : false;
		}
		
		public function isLogged() {
			return $this->session->sessionExists($this->userSessionName);
		}
		
		public function removeUserSession() {
			return $this->session->deleteSession($this->userSessionName);
		}
		
		public function setUserIdSessionField() {
			$userId = $this->getUserId();
			$sessionId = $this->session->getSessionId();
						
			if ($userId !== false) {
				
				$this->db->where('session_id', $sessionId);
				
				if ($this->db->update('sessions', ['user_id' => $userId, 'session_updated_at' => date('Y-m-d H:i:s')])) {
					return true;
				} else {
					return false;
				}
				
			}

		}
		
		public function removeAllUserSessionRecords($passedUserId=0) {
			$this->db->where('user_id', $passedUserId);
			return $this->db->delete('sessions');
		}
		
		public function getLanguage() {
			return $this->getUserField('userDefaultLang');
		}
		
		public function setDisplayName($passedUser=[]) {
			$user = (empty($passedUser) || !is_array($passedUser)) ? $this->getUser() : $passedUser;
			$helper = new Helper();
			
			if ($user !== false) {
				return $helper->setDottedFullname($user['userName'], $user['userSurname']);
			}
			
			return '';
		}
		
		public function is($roleIds=null) {
			$userRoles = $this->getUserRoles();
			
			if (is_array($roleIds)) {
				foreach($roleIds as $roleId) {
					if (isset($userRoles[$roleId])) {
						return true;
					}
				}
			} else if (is_integer($roleIds)) {
				return isset($userRoles[$roleIds]);
			}
			
			return false;
		}
		
		public function hasOneRole($roleId=0) {
			$userRoles = $this->getUserRoles();
			
			if (count($userRoles) == 1 && isset($userRoles[$roleId])) return true;
			
			return false;
		}
		
		public function checkPermissions($allowedRoles=[]) {
			$user = $this->getUser();
			
			if (is_array($allowedRoles)) {
				foreach($allowedRoles as $roleId) {
					if (isset($user['userRoles'][$roleId])) {
						return true;
					}
				}
			}
			
			return false;
		}
		
		public function setAvatar($passedUserId=0, $tmpFileName=null) {
			try {
				$userId = $passedUserId == 0 ? $this->getUserId() : $passedUserId;
				$image = new ImageResize($tmpFileName);
				$image->quality_jpg = $this->config['settings']['avatar-jpg-quality'];
				$image->resizeToBestFit($this->config['settings']['avatar-width'], $this->config['settings']['avatar-height']);
				$fileName = $userId.'.jpg';
				$fileNamePath = AVATAR_IMG_DIR.$fileName;
				
				if (file_exists($fileNamePath)) {
					@unlink($fileNamePath);
				}
				
				@unlink($tmpFileName);
				
				$image->save($fileNamePath, IMAGETYPE_JPEG);
				
				return true;
			} catch (ImageResizeException $e) {
				return false;
			}
			
			return false;
		}
		
		public function getAvatar($passedUserId=0) {
			$userId = $passedUserId == 0 ? $this->getUserId() : $passedUserId;
			$fileName = $userId.'.jpg';
			$fileNamePath = AVATAR_IMG_DIR.$fileName;
			$uri = $this->config['settings']['avatar-uri'];
			
			if (file_exists($fileNamePath)) {
				return $uri.$fileName;
			} else {
				return $uri.$this->config['settings']['avatar-default'];
			}
		}
		
		public function deleteAvatar($passedUserId=0) {
			$userId = $passedUserId == 0 ? $this->getUserId() : $passedUserId;
			$fileName = $userId.'.jpg';
			$fileNamePath = AVATAR_IMG_DIR.$fileName;
			$uri = $this->config['settings']['avatar-uri'];
			
			if (file_exists($fileNamePath)) {
				@unlink($fileNamePath);
			}
			
			return !file_exists($fileNamePath);
		}
		
		public function getDefaultAvatar() {
			$uri = $this->config['settings']['avatar-uri'];
			$image = $this->config['settings']['avatar-default'];
			return $uri.$image;
		}
		
		public function hasAvatar($passedUserId=0) {
			$userId = $passedUserId == 0 ? $this->getUserId() : $passedUserId;
			$fileName = $userId.'.jpg';
			$fileNamePath = AVATAR_IMG_DIR.$fileName;
			return file_exists($fileNamePath);
		}
		
	}