<?php


ini_set('session.cookie_lifetime', 315360000);
ini_set('session.gc_maxlifetime', 315360000);

if (session_status() !== PHP_SESSION_ACTIVE) {
	session_start();
}
function generatesessionhash()
{
	$bytes = random_bytes(36);
	return hash('sha256', bin2hex($bytes));
}

function user_access($usertype)
{

	if (strtolower($usertype) === 'ult') {
		$accesslist = [
			'all'
		];
	} else if (strtolower($usertype) === 'super operator') {
		$accesslist = [
			'all',
			'manage_users',
			'manage_roles',
			'manage_permissions'
		];
	} else if (strtolower($usertype) === 'operator') {
		$accesslist = [
			'view_tickets',
			'create_tickets',
			'edit_tickets',
			'close_tickets',
			'manage_assigned_tickets'
		];
	} else if (strtolower($usertype) === 'coordinator') {
		$accesslist = [
			'view_tickets',
			'create_tickets',
			'edit_tickets',
			'close_tickets',
			'manage_assigned_tickets',
			'view_reports'
		];
	} else if (strtolower($usertype) === 'usher') {
		$accesslist = [
			'view_tickets',
			'create_tickets',
			'edit_tickets',
			'close_tickets'
		];
	} else if (strtolower($usertype) === 'user') {
		$accesslist = [
			'view_tickets',
			'create_tickets'
		];
	} else if (strtolower($usertype) === 'viewer') {
		$accesslist = [
			'view_tickets'
		];
	} else if (strtolower($usertype) === 'disabler') {
		$accesslist = [];
	} else {
		$accesslist = [];
	}

	return $accesslist;

}

class WhatUserType
{
	public $Usertype;

	public function __construct($usertype = '---currentuser---')
	{
		if ($usertype === '---currentuser---') {
			global $CurrentUserType;
			$this->Usertype = $CurrentUserType;
		} else {
			$this->Usertype = $usertype;
		}
	}

	private function ReadAndMatchType($arrayorStringUserTypes, $Targettype)
	{
		if (!$arrayorStringUserTypes || empty($arrayorStringUserTypes)) {
			return false;
		}
		$types = $arrayorStringUserTypes;
		if (!is_array($arrayorStringUserTypes)) {
			$types = tryjsondecode($arrayorStringUserTypes);
		}

		if (is_array($types)) {
			return in_array($Targettype, $types);
		} else {
			return $Targettype === $types;
		}

	}

	public function IsUltimate()
	{
		return $this->ReadAndMatchType($this->Usertype, 'ult');
	}
	public function IsSuperOperator()
	{
		return $this->ReadAndMatchType($this->Usertype, 'super operator');
	}
	public function IsOperator()
	{
		return $this->ReadAndMatchType( $this->Usertype, 'operator');
	}
	public function IsCoordinator()
	{
		return $this->ReadAndMatchType( $this->Usertype, 'coordinator');
	}
	public function IsDisabler()
	{
		return $this->ReadAndMatchType( $this->Usertype, 'disabler');
	}
	public function IsAgent()
	{
		return $this->ReadAndMatchType( $this->Usertype, 'agent');
	}
	public function IsViewer()
	{
		return $this->ReadAndMatchType(  $this->Usertype, 'viewer');
	}
	public function IsStoreManager()
	{
		return $this->ReadAndMatchType( $this->Usertype, 'store manager');
	}
	public function IsStoreOwner()
	{
		return $this->ReadAndMatchType( $this->Usertype, 'store owner');
	}
	public function IsRider()
	{
		return $this->ReadAndMatchType(  $this->Usertype, 'rider');
	}
	public function IsAdminStaff()
	{
		return $this->ReadAndMatchType(  $this->Usertype, 'admin staff');
	}
	public function IsTeamLeader()
	{
		return $this->ReadAndMatchType(  $this->Usertype, 'team leader');
	}
	public function IsAudit()
	{
		return $this->ReadAndMatchType(   $this->Usertype, 'audit');
	}
	public function IsRegionalDirector()
	{
		return $this->ReadAndMatchType(  $this->Usertype, 'regional director');
	}
	public function IsRegularUser()
	{
		return $this->ReadAndMatchType(  $this->Usertype, 'user');
	}
	

}
function WhatUserType($usertype = '---currentuser---')
{
	return new WhatUserType($usertype);
}



function SendCookieSession($sessionId, $expiration_strtotime = '')
{
	if (!$sessionId) {
		return false;
	}
	if ($expiration_strtotime) {
		$expiration_strtotime = time() + 720000000;
	}
	setcookie('TA_SESSION_COOKIE', $sessionId, [
		'expires' => $expiration_strtotime, // 30 days
		'path' => '/',
		'secure' => true, // Only send over HTTPS
		'httponly' => false, // Accessible only by the server
		'samesite' => 'Strict' // CSRF protection
	]);
}

function getSessionKeyEitherCookieorSession()
{
	if (!isset($_SESSION['TA']['SESSIONKEY']) or !$_SESSION['TA']['SESSIONKEY']) {
	} else {
		return $_SESSION['TA']['SESSIONKEY'];
	}
	if (isset($_COOKIE["TA_SESSION_COOKIE"]) and $_COOKIE["TA_SESSION_COOKIE"]) {
		return $_COOKIE["TA_SESSION_COOKIE"];
	} else {
		return false;
	}
}

function DeleteRemoveSessionKeyCookie()
{
	setcookie("TA_SESSION_COOKIE", "", time() - 3600, "/");
	$_SESSION['TA']['SESSIONKEY'] = '';
}

function UpdateSessionorCookieKey($sessionid, $expiration_strtotime = '')
{
	if (!$sessionid) {
		return false;
	}
	$_SESSION['TA']['SESSIONKEY'] = $sessionid;
	SendCookieSession($sessionid, $expiration_strtotime);

}






function loginstatus()
{

	if (!getSessionKeyEitherCookieorSession()) {
		return false;
	}


	$sessiondata = getActiveSessionData(getSessionKeyEitherCookieorSession());
	if (!$sessiondata) {
		return false;
	}
	$expiry = strtotime($sessiondata['expiry']);
	$now = strtotime('now');
	$active = $sessiondata['userdata']['active'];
	$expired = $now > $expiry;
	$time_difference = $expiry - $now;
	$NOT_EXPIRED = !$expired;

	if ($sessiondata and $NOT_EXPIRED and $active) {
		if ($time_difference < 300) {
			$newexpiry = $expiry + (5 * 60);
			$newexpiry = date("Y-m-d H:i:s", $newexpiry);
			ModifySession($sessiondata['hashkey'], ['expiry' => $newexpiry]);
			$sessiondata['expiry'] = $newexpiry;
		}
		if (YesNoRandom() and false) {//remove false to allow regeneration of id. currently logsuser out immediately
			$newsessionid = regeneratesessionidANDUpdateSessionVar();
			if ($newsessionid) {
				$sessiondata['hashkey'] = $newsessionid;
			}
		}
		UpdateSessionorCookieKey($sessiondata['hashkey'], strtotime($sessiondata['expiry']));
		return $sessiondata;
	} else {
		deleteSession(getSessionKeyEitherCookieorSession());
		return false;
	}
}
function getRandomNumber($length = 1)
{
	$random_bytes = openssl_random_pseudo_bytes($length);
	return ord($random_bytes[0]);
}
function YesNoRandom()
{
	$regenerate_threshold = 50;
	$random_number = getRandomNumber(1);
	if ($random_number <= $regenerate_threshold) {
		return true;
	} else {
		return false;
	}
}

function regeneratesessionid($currensessionhash)
{
	if (!$currensessionhash) {
		return false;
	}
	$newhash = generatesessionhash();
	$data['hashkey'] = $newhash;
	$modify = ModifySession($currensessionhash, $data);
	if (!$modify) {
		return false;
	}
	return $newhash;
}

function regeneratesessionidANDUpdateSessionVar()
{
	$sessionnewid = regeneratesessionid(getSessionKeyEitherCookieorSession());
	if ($sessionnewid) {
		UpdateSessionorCookieKey($sessionnewid);
		return $sessionnewid;
	}
	return false;
}

function tryloginwcookies($SESSION_ID)
{
	$sessiondata = getActiveSessionData($SESSION_ID);
	if (!$sessiondata) {
		return false;
	}
	//$_SESSION['TA']['SESSIONKEY']

}
function getUserType()
{
	$loginstatus = loginstatus();
	if (!$loginstatus) {
		return false;
	}


	if (isset($loginstatus['userdata']['acct_type']) and $loginstatus['userdata']['acct_type']) {
		return $loginstatus['userdata']['acct_type'];
	}
}

function IsUserCoordinator()
{
	if (strtolower(getUserType()) == 'coordinator') {
		return true;
	} else {
		return false;
	}
}


function IsUserUltimate()
{
	if (strtolower(getUserType()) == 'ult') {
		return true;
	} else {
		return false;
	}
}

function IsUserOperator()
{
	if (strtolower(getUserType()) == 'operator') {
		return true;
	} else {
		return false;
	}
}

function IsUserSuperOperator()
{
	if (strtolower(getUserType()) == 'super operator') {
		return true;
	} else {
		return false;
	}
}

function IsUserUsher()
{
	if (strtolower(getUserType()) == 'usher') {
		return true;
	} else {
		return false;
	}
}

function IsUserViewer()
{
	if (strtolower(getUserType()) == 'viewer') {
		return true;
	} else {
		return false;
	}
}
function IsUserDisabler()
{
	if (strtolower(getUserType()) == 'disabler') {
		return true;
	} else {
		return false;
	}
}


function IsNormalUser()
{
	if (strtolower(getUserType()) == 'user') {
		return true;
	} else {
		return false;
	}
}


function CurrentUserUID()
{
	$loginstatus = loginstatus()['userdata']['uid'] ?? false;
	return $loginstatus;
}





function loginnow($username, $password, $keep_alive = false)
{
	if (!$username or !$password) {

		return false;
	}
	if (loginstatus()) {
		return loginstatus();
	}
	$trylogin = trylogin($username, $password);
	if (!$trylogin) {

		return false;
	}
	$userid = $trylogin['uid'];
	if ($keep_alive) {
		$expiry = date("Y-m-d H:i:s", strtotime('+ 10 years'));
	} else {
		$expiry = date("Y-m-d H:i:s", strtotime('+ 2 hours'));
	}
	$newsessionkey = NewSession($userid, 1, $expiry);

	$_SESSION['TA']['SESSIONKEY'] = $newsessionkey;

	return $newsessionkey;
}

function logoutnow()
{
	deleteAllUserSessions(CurrentUserUID());
	unset($_SESSION['TA']);
}



function NewSession($userid, $active = 1, $expiry = false)
{





	$user = checkifexists('users', ['uid' => $userid], ['hashkey', 'nickname', 'acct_type', 'mnumber', 'active', 'parentuid', 'targetuids', 'multiple_logins']);
	if (!$user) {
		return 'NO USER';
	}

	if (checkifexists('sessions', ['userid' => $userid, 'active' => 1], $fieldstoselectarray = '')) {
		if (!$user['multiple_logins']) {
			deleteAllUserSessions($userid);
		}
	}

	if (!$expiry) {
		$expiry = date("Y-m-d H:i:s", strtotime('+10 years'));
	}
	unset($user['password']);
	unset($user['creation_date']);
	unset($user['modified_date']);
	$newhash = generatesessionhash();
	$data['hashkey'] = $newhash;
	$data['userid'] = $userid;
	$data['active'] = $active;
	$data['expiry'] = $expiry;
	$data['userdata'] = json_encode($user);

	$usertype = user_access($user['acct_type']);

	$data['accesslist'] = json_encode($usertype);
	$key = insertintodb(DB(), 'sessions', $data);

	$sessiondata = getSessionData($newhash);
	if (!$sessiondata) {
		return false;
	}
	$sessionHistory = NewSession_History($userid, $sessiondata, $active, $expiry);

	if (!$sessionHistory) {
		deleteSession($newhash);

		return false;
	}

	return $newhash;
}

function getSessionData($sessionhash)
{
	$sessionhash = checkifexists('sessions', ['hashkey' => $sessionhash]);
	if ($sessionhash and is_array($sessionhash) and !empty($sessionhash)) {
		$sessiondata['userdata'] = json_decode($sessionhash['userdata'], 1);
		$userhashkey = $sessiondata['userdata']['hashkey'];
		$fieldstoselect = [
			'uid',
			'hashkey',
			'nickname',
			'acct_type',
			'mnumber',
			'active',
			'parentuid',
			'targetuids'
		];
		$sessionhash['userdata'] = GetUserDatabyUID($userhashkey, $fieldstoselect);
		$usertype = $sessionhash['userdata']['acct_type'];
		$sessionhash['accesslist'] = user_access($usertype);
		return $sessionhash;
	} else {
		return false;
	}
}


function getActiveSessionData($sessionhash)
{
	$session = getSessionData($sessionhash);
	if ($session and $session['active'] === 1) {
		return $session;
	} else {
		return false;
	}

}
function deleteSession($sessionhash)
{
	deletefromdb('sessions', ['hashkey' => $sessionhash]);
	if (checkifexists('sessions', ['hashkey' => $sessionhash], ['hashkey'])) {
		return false;
	}

	return true;

}


function deleteAllUserSessions($userid)
{
	deletefromdb('sessions', ['userid' => $userid]);
	if (checkifexists('sessions', ['userid' => $userid], ['hashkey'])) {
		return false;
	}
	return true;
}

function FindCurrentSessionForUser($userid)
{
	$search = checkifexists('sessions', ['userid' => $userid, 'active' => 1], ['hashkey']);
	if ($search and isset($search['hashkey'])) {
		return $search['hashkey'];
	}
	return false;
}

function ModifySession($sessionhash, $newdata)
{
	if (!$sessionhash) {
		return false;
	}
	$check = checkifexists('sessions', ['hashkey' => $sessionhash]);
	if (!$check or empty($check['hashkey'] or !$check['hashkey'])) {
		return false;
	}
	$whereArray = ['hashkey' => $sessionhash];
	return updatedbsimple(DB(), 'sessions', $newdata, $whereArray);
}

function ExtendSession($sessionhash, $newexpiry = false)
{
	if (!$newexpiry) {
		$newexpiry = date("Y-m-d H:i:s", strtotime('+3 days'));
	}
	return ModifySession($sessionhash, ['expiry' => $newexpiry]);
}
function ExtendSessionbyUID($UID, $newexpiry = false)
{
	if (!$newexpiry) {
		$newexpiry = date("Y-m-d H:i:s", strtotime('+3 days'));
	}
	$usersession = FindCurrentSessionForUser($UID);
	return ModifySession($usersession, ['expiry' => $newexpiry]);
}



//SessionHistory


function NewSession_History($userid, $sessiondata, $active = 1, $expiry = false)
{



	$newhash = generatesessionhash();
	$data['hashkey'] = $newhash;
	$data['userid'] = $sessiondata['userid'];
	$data['old_hashkey'] = $sessiondata['hashkey'];
	$data['active'] = $sessiondata['active'];
	$data['expiry'] = $sessiondata['expiry'];
	$data['accesslist'] = $sessiondata['accesslist'];
	$data['userdata'] = $sessiondata['userdata'];
	$data['login_time'] = serverdatetimesql();
	$data['serverdata'] = json_encode($_SERVER);
	$data['ip_address'] = $_SERVER['REMOTE_ADDR'];


	$key = insertintodb(DB(), 'session_history', $data);

	if (!$key) {
		return false;
	}
	return $key;
}


function NewLog($log_type, $log_category, $description, $useruid = '')
{

	if (!$useruid) {
		$useruid = CurrentUserUID();
	}

	$data['log_time'] = serverdatetimesql();
	$data['log_type'] = $log_type;
	$data['log_category'] = $log_category;
	$data['description'] = $description;
	$data['server_data'] = json_encode($_SERVER);
	$data['session_data'] = json_encode($_SESSION);
	$data['useruid'] = $useruid;


	$key = insertintodb(DB(), 'logs', $data);


	if (!$key) {
		return false;
	}
	return $key;
}



?>