<?php
/**
 * VIP
 * https://webenginecms.org/
 * 
 * @version 1.1.0
 * @author Lautaro Angelico <http://lautaroangelico.com/>
 * @copyright (c) 2013-2020 Lautaro Angelico, All Rights Reserved
 * @build 3d220b662522c313f5980cd685842c3d
 */

namespace Plugin\VIP;

class VIP {
	
	private $_removePlatinumPackage = true;
	private $serverFiles;
	
	private $_configXml = 'config.xml';
	private $_modulesPath = 'modules';
	
	private $_configId;
	private $_vipTypeData;
	
	private $_username;
	private $_type;
	private $_days;
	
	private $_usercpmenu = array(
		array(
			'active' => true,
			'type' => 'internal',
			'phrase' => 'vip_title',
			'link' => 'vip/info',
			'icon' => 'vip.png',
			'visibility' => 'user',
			'newtab' => false,
			'order' => 999,
		),
	);
	
	// CONSTRUCTOR
	
	function __construct() {
		
		// webengine configs
		$this->config = webengineConfigs();
		$this->serverFiles = strtolower($this->config['server_files']);
		
		// load databases
		$this->common = new \common();
		$this->mu = \Connection::Database('MuOnline');
		$this->me = \Connection::Database('Me_MuOnline');
		
		// load configs
		$this->configFilePath = __PATH_VIP_ROOT__.$this->_configXml;
		if(!file_exists($this->configFilePath)) throw new \Exception(lang('vip_error_2'));
		$xml = simplexml_load_file($this->configFilePath);
		if(!$xml) throw new \Exception(lang('vip_error_2'));
		
		// set configs	
		$this->_configId = $xml->credit_config;
		if($xml->credit_config == 0) throw new \Exception(lang('vip_error_12'));
		
		$this->_vipTypeData = array(
			1 => array(
				'enabled' => (int) $xml->enable_vip_type_1,
				'title' => lang('vip_title_type_1'),
				'packages' => explode(',', $xml->vip_packages_1),
				'discounts' => explode(',', $xml->vip_discount_1),
				'cost' => (int) $xml->vip_cost_per_day_1,
			),
			2 => array(
				'enabled' => (int) $xml->enable_vip_type_2,
				'title' => lang('vip_title_type_2'),
				'packages' => explode(',', $xml->vip_packages_2),
				'discounts' => explode(',', $xml->vip_discount_2),
				'cost' => (int) $xml->vip_cost_per_day_2,
			),
			3 => array(
				'enabled' => (int) $xml->enable_vip_type_3,
				'title' => lang('vip_title_type_3'),
				'packages' => explode(',', $xml->vip_packages_3),
				'discounts' => explode(',', $xml->vip_discount_3),
				'cost' => (int) $xml->vip_cost_per_day_3,
			),
			4 => array(
				'enabled' => (int) $xml->enable_vip_type_4,
				'title' => lang('vip_title_type_4'),
				'packages' => explode(',', $xml->vip_packages_4),
				'discounts' => explode(',', $xml->vip_discount_4),
				'cost' => (int) $xml->vip_cost_per_day_4,
			),
		);
		
		// remove platinum package if not igcn
		if($this->serverFiles != 'igcn' && $this->_removePlatinumPackage == true) {
			unset($this->_vipTypeData[4]);
		}
		
	}
	
	// PUBLIC FUNCTIONS
	
	public function loadModule($module) {
		if(!\Validator::Alpha($module)) throw new \Exception(lang('vip_error_3'));
		if(!$this->_moduleExists($module)) throw new \Exception(lang('vip_error_3'));
		if(!@include_once(__PATH_VIP_ROOT__ . $this->_modulesPath . '/' . $module . '.php')) throw new \Exception(lang('vip_error_3'));
	}
	
	public function isVipTypeEnabled($type) {
		if(!check_value($type)) return;
		if(!\Validator::UnsignedNumber($type)) return;
		if(!array_key_exists($type, $this->_vipTypeData)) return;
		return $this->_vipTypeData[$type]['enabled'];
	}
	
	public function getVipTypePackage($type) {
		if(!check_value($type)) return;
		if(!\Validator::UnsignedNumber($type)) return;
		if(!array_key_exists($type, $this->_vipTypeData)) return;
		if(!is_array($this->_vipTypeData[$type]['packages'])) return;
		return $this->_vipTypeData[$type]['packages'];
	}
	
	public function getVipCost($days=1, $type=1) {
		if(!check_value($type)) return;
		if(!\Validator::UnsignedNumber($type)) return;
		if(!array_key_exists($type, $this->_vipTypeData)) return;
		
		$discount = 0;
		foreach($this->_vipTypeData[$type]['packages'] as $key => $value) {
			if($days == $value) {
				if(array_key_exists($key, $this->_vipTypeData[$type]['discounts'])) {
					$discount = $this->_vipTypeData[$type]['discounts'][$key];
				}
			}
		}
		
		$result = $days*$this->_vipTypeData[$type]['cost'];
		if($discount > 0) {
			$result = $result*((100-$discount)/100);
		}
		
		return round($result);
	}
	
	public function setUsername($username) {
		if(!\Validator::UsernameLength($username)) return;
		$this->_username = $username;
	}
	
	public function setVipType($type) {
		if(!array_key_exists($type, $this->_vipTypeData)) throw new \Exception(lang('vip_error_5'));
		$this->_type = $type;
	}
	
	public function setVipPackage($days) {
		if(!check_value($this->_type)) throw new \Exception(lang('vip_error_6'));
		if(!in_array($days, $this->_vipTypeData[$this->_type]['packages'])) throw new \Exception(lang('vip_error_6'));
		$this->_days = $days;
	}
	
	public function getVip() {
		if(!check_value($this->_username)) throw new \Exception(lang('vip_error_8'));
		if(!check_value($this->_type)) throw new \Exception(lang('vip_error_8'));
		if(!check_value($this->_days)) throw new \Exception(lang('vip_error_8'));
		
		// check if vip type enabled
		if(!$this->_vipTypeData[$this->_type]['enabled']) throw new \Exception(lang('vip_error_5'));
		
		// account vip data
		$accountVipData = $this->getAccountVipData();
		if(!is_array($accountVipData)) throw new \Exception(lang('vip_error_7'));
		
		// if extending check vip type
		if($this->isAccountVip()) {
			if($this->_type != $accountVipData[_CLMN_VIP_TYPE_]) throw new \Exception(lang('vip_error_9'));
		}
		
		// account info
		$Account = new \Account();
		$accountInfo = $Account->accountInformation($_SESSION['userid']);
		if(!is_array($accountInfo)) throw new \Exception(lang('vip_error_10'));
		
		// check credits
		$creditSystem = new \CreditSystem();
		$creditSystem->setConfigId($this->_configId);
		$configInfo = $creditSystem->showConfigs(true);
		switch($configInfo['config_user_col_id']) {
			case 'userid':
				$creditSystem->setIdentifier($accountInfo[_CLMN_MEMBID_]);
				break;
			case 'username':
				$creditSystem->setIdentifier($accountInfo[_CLMN_USERNM_]);
				break;
			case 'email':
				$creditSystem->setIdentifier($accountInfo[_CLMN_EMAIL_]);
				break;
			default:
				throw new \Exception(lang('vip_error_7'));
		}
		
		// account credits
		$accountCredits = $creditSystem->getCredits();
		
		// vip package info
		$vipTypeData = $this->_vipTypeData[$this->_type];
		
		// calculate cost
		$finalCost = $this->getVipCost($this->_days, $this->_type);
		
		// compare credits
		if($accountCredits < $finalCost) throw new \Exception(lang('vip_error_11'));
		
		// subtract credits
		$creditSystem->subtractCredits($finalCost);
		
		// extend
		if($this->isAccountVip()) {
			$this->_extendVip();
			redirect(1, 'vip/info/success/1/');
			return;
		}
		
		// add vip
		$this->_addVip();
		redirect(1, 'vip/info/success/1/');
	}
	
	public function isAccountVip() {
		if(!check_value($this->_username)) throw new \Exception(lang('vip_error_4'));
		$accountVipData = $this->_getAccountVipData();
		if(!array_key_exists($accountVipData[_CLMN_VIP_TYPE_], $this->_vipTypeData)) return;
		if(!check_value($accountVipData[_CLMN_VIP_DATE_])) return;
		$vipTimestamp = strtotime($accountVipData[_CLMN_VIP_DATE_]);
		if(time() > $vipTimestamp) return;
		return true;
	}
	
	public function getAccountVipData() {
		if(!check_value($this->_username)) throw new \Exception(lang('vip_error_4'));
		return $this->_getAccountVipData();
	}
	
	public function getVipTypeData() {
		return $this->_vipTypeData;
	}
	
	public function checkPluginUsercpLinks() {
		if(!is_array($this->_usercpmenu)) return;
		$cfg = loadConfig('usercp');
		if(!is_array($cfg)) return;
		foreach($cfg as $usercpMenu) {
			$usercpLinks[] = $usercpMenu['link'];
		}
		foreach($this->_usercpmenu as $pluginMenuLink) {
			if(in_array($pluginMenuLink['link'],$usercpLinks)) continue;
			$cfg[] = $pluginMenuLink;
		}
		usort($cfg, function($a, $b) {
			return $a['order'] - $b['order'];
		});
		$usercpJson = json_encode($cfg, JSON_PRETTY_PRINT);
		$cfgFile = fopen(__PATH_CONFIGS__.'usercp.json', 'w');
		if(!$cfgFile) throw new \Exception('There was a problem opening the usercp file.');
		fwrite($cfgFile, $usercpJson);
		fclose($cfgFile);
	}
	
	// PROTECTED FUNCTIONS
	
	protected function _getAccountVipData() {
		if(!check_value($this->_username)) return;
		$accountVipData = $this->me->query_fetch_single("SELECT * FROM "._TBL_VIP_." WHERE "._CLMN_VIP_ID_." = ?", array($this->_username));
		if(!is_array($accountVipData)) {
			// add account to vip table (IGCN)
			if($this->serverFiles == 'igcn') {
				$this->me->query("INSERT INTO "._TBL_VIP_." ("._CLMN_VIP_ID_.", "._CLMN_VIP_TYPE_.") VALUES (?, 0)", array($this->_username));
			}
			return;
		}
		return $accountVipData;
	}
	
	protected function _addVip() {
		if(!check_value($this->_username)) return;
		if(!check_value($this->_type)) return;
		if(!check_value($this->_days)) return;
		$expirationDateTime = $this->_generateExpirationTimestamp($this->_days);
		$addVip = $this->me->query("UPDATE "._TBL_VIP_." SET "._CLMN_VIP_TYPE_." = ?, "._CLMN_VIP_DATE_." = ? WHERE "._CLMN_VIP_ID_." = ?", array($this->_type, $expirationDateTime, $this->_username));
		if(!$addVip) return;
		return $addVip;
	}
	
	protected function _extendVip() {
		if(!check_value($this->_username)) return;
		if(!check_value($this->_days)) return;
		$accountVipData = $this->_getAccountVipData();
		if(!is_array($accountVipData)) return;
		$expirationDateTime = $this->_generateExpirationTimestamp($this->_days, $accountVipData[_CLMN_VIP_DATE_]);
		$addVip = $this->me->query("UPDATE "._TBL_VIP_." SET "._CLMN_VIP_DATE_." = ? WHERE "._CLMN_VIP_ID_." = ?", array($expirationDateTime, $this->_username));
		if(!$addVip) return;
		return $addVip;
	}
	
	protected function _removeVip() {
		if(!check_value($this->_username)) return;
		$removeVip = $this->me->query("UPDATE "._TBL_VIP_." SET "._CLMN_VIP_TYPE_." = 0 WHERE "._CLMN_VIP_ID_." = ?", array($this->_username));
		if(!$removeVip) return;
		return true;
	}
	
	// PRIVATE FUNCTIONS
	
	private function _moduleExists($module) {
		if(!check_value($module)) return;
		if(!file_exists(__PATH_VIP_ROOT__ . $this->_modulesPath . '/' . $module . '.php')) return;
		return true;
	}
	
	private function _generateExpirationTimestamp($days, $baseDate="") {
		if(check_value($baseDate)) {
			return date("Y-m-d H:i:s", strtotime($baseDate)+(86400*$days));
		}
		return date("Y-m-d H:i:s", time()+(86400*$days));
	}
	
}