<?php
/**
 * Grand Reset Plugin
 * https://webenginecms.org/
 * 
 * @version 1.0.0
 * @author Lautaro Angelico <http://lautaroangelico.com/>
 * @copyright (c) 2013-2019 Lautaro Angelico, All Rights Reserved
 */

namespace Plugin\GrandReset;

class GrandReset {
	
	private $_configXml = 'config.xml';
	private $_modulesPath = 'modules';
	
	private $_requiredZen;
	private $_requiredResets;
	private $_requiredLevel;
	private $_resetStats;
	private $_rewardLvlUpPoints;
	private $_multiplyLvlUpPoints;
	private $_rewardCredits;
	private $_rewardCreditsConfig;
	private $_rewardCreditsAmount;
	
	private $_username;
	private $_characters;
	private $_player;
	private $_reset_limit_day;
	private $_reset_limit_wek;
	private $_reset_limit_mon;
	
	// CONSTRUCTOR
	
	function __construct() {
		global $custom;
		
		// load databases
		$this->mu = \Connection::Database('MuOnline');
		
		// load configs
		$this->configFilePath = __PATH_GRANDRESET_ROOT__.$this->_configXml;
		if(!file_exists($this->configFilePath)) throw new \Exception(lang('grandreset_error_2'));
		$xml = simplexml_load_file($this->configFilePath);
		if(!$xml) throw new \Exception(lang('grandreset_error_2'));
		
		// set configs
		$this->_requiredZen = (int) $xml->zen_requirement;
		$this->_requiredResets = (int) $xml->resets_requirement;
		$this->_requiredLevel = (int) $xml->level_requirement;
		$this->_resetStats = (int) $xml->reset_stats;
		$this->_rewardLvlUpPoints = (int) $xml->reward_leveluppoints;
		$this->_multiplyLvlUpPoints = (int) $xml->multiply_leveluppoints;
		$this->_rewardCredits = (int) $xml->reward_credits;
		$this->_rewardCreditsConfig = (int) $xml->reward_credits_config;
		$this->_rewardCreditsAmount = (int) $xml->reward_credits_amount;
		// add limit relife
		$this->_reset_limit_day = (int) $xml->reset_limit_day;
		$this->_reset_limit_wek = (int) $xml->reset_limit_wek;
		$this->_reset_limit_mon = (int) $xml->reset_limit_mon;
		
		// custom
		$this->custom = $custom;
		
	}
	
	// PUBLIC FUNCTIONS
	
	public function loadModule($module) {
		if(!\Validator::Alpha($module)) throw new \Exception(lang('grandreset_error_3'));
		if(!$this->_moduleExists($module)) throw new \Exception(lang('grandreset_error_3'));
		if(!@include_once(__PATH_GRANDRESET_ROOT__ . $this->_modulesPath . '/' . $module . '.php')) throw new \Exception(lang('grandreset_error_3'));
	}
	
	public function setUsername($username) {
		$this->_username = $username;
		$this->_loadAccountPlayerList();
	}
	
	public function setPlayer($player) {
		if(!check_value($this->_username)) return;
		$this->_player = $player;
	}
	
	public function getAccountPlayerList() {
		if(!check_value($this->_username)) return;
		if(!is_array($this->_characters)) return;
		return $this->_characters;
	}
	
	public function getRequiredZen() {
		return $this->_requiredZen;
	}
	
	public function getRequiredResets() {
		return $this->_requiredResets;
	}
	
	public function getRequiredLevel() {
		return $this->_requiredLevel;
	}
	
	public function grandResetPlayer() {
		
		// check selected player
		$playerData = $this->_getPlayerData();
		if(!is_array($playerData)) throw new \Exception(lang('grandreset_error_5'));
		
		// grand resets
		$playerGrandResets = check_value($playerData[_CLMN_CHR_GRSTS_]) ? $playerData[_CLMN_CHR_GRSTS_] : 0;
		$playerNewGrandResets = $playerGrandResets+1;
		
		// account id
		$Account = new \Account();
		$accountId = $Account->retrieveUserID($this->_username);
		if(!check_value($accountId)) throw new \Exception(lang('error_12'));
		
		// check if account is online
		if($Account->accountOnline($this->_username)) throw new \Exception('Tài khoản của bạn đang Online');
		
		// zen requirement
		if($this->_requiredZen > 0) {
			if($playerData[_CLMN_CHR_ZEN_] < $this->_requiredZen) throw new \Exception(lang('grandreset_error_6'));
		}
		
		// resets requirement
		if($this->_requiredResets > 0) {
			if($playerData[_CLMN_CHR_RSTS_] < $this->_requiredResets) throw new \Exception(lang('grandreset_error_7'));
		}
		
		// level requirement
		if($this->_requiredLevel > 0) {
			if($playerData[_CLMN_CHR_LVL_] < $this->_requiredLevel) throw new \Exception(lang('grandreset_error_8'));
		}
		
		// level up points
		$levelUpPoints = $this->_rewardLvlUpPoints;
		if($this->_multiplyLvlUpPoints == 1) {
			$levelUpPoints = $this->_rewardLvlUpPoints*$playerNewGrandResets;
		}
		
		// stats
		if($this->_resetStats == 1) {
			$baseStats = $this->custom['character_class'][$playerData[_CLMN_CHR_CLASS_]]['base_stats'];
			if(!is_array($baseStats)) throw new \Exception(lang('grandreset_error_9'));
		}
		
		// kiểm tra xem đẵ bằng top  hay chưa
		
		$top1 = $this->mu->query_fetch("SELECT TOP 1 MasterResetCount, MasterResetMon, MasterResetWek,MasterResetDay FROM Character WHERE MasterResetCount = (SELECT MAX(MasterResetCount) FROM Character)");
		if(!is_array($top1)) throw new \Exception('Lỗi không xác định');
		foreach($top1 as $key => $row) {
		    if($row[MasterResetCount] > $playerData[MasterResetCount]+1) {
		        $playerData[MasterResetMon] = 0;
		        $playerData[MasterResetWek] = 0;
		        $playerData[MasterResetDay] = 0;
		    }
		    else if($row[MasterResetCount] == $playerData[MasterResetCount]+1) {
		        if($playerData[MasterResetMon] < $row[MasterResetMon]){
    		        $playerData[MasterResetMon] = $row[MasterResetMon]-1;
    		        $playerData[MasterResetWek] = $row[MasterResetWek]-1;
    		        $playerData[MasterResetDay] = $row[MasterResetDay]-1;
		        }
		    } else {
		        //Kiểm Tra xem ngày hôm nay nó đã reset chưa
        		if($playerData[MasterResetMon] >= $this->_reset_limit_mon) throw new \Exception('Bạn đã đạt giới hạn 12 lần Relife 1 tháng');
        		if($playerData[MasterResetWek] >= $this->_reset_limit_wek) throw new \Exception('Bạn đã đạt giới hạn 4 lần Relife 1 tuần');
        		if($playerData[MasterResetDay] >= $this->_reset_limit_day) throw new \Exception('Hôm nay bạn đã đạt giới hạn Relife, ngày mai Relife tiếp nhé!');
		    }
		    
		}
		
		// perform grand reset
		$query = "UPDATE "._TBL_CHR_." SET ";
		$query .= ""._CLMN_CHR_LVL_." = 1, ";
		$query .= ""._CLMN_CHR_RSTS_." = "._CLMN_CHR_RSTS_." - ?, ";
		$query .= ""._CLMN_CHR_ZEN_." = "._CLMN_CHR_ZEN_." - ?, ";
		$query .= ""._CLMN_CHR_GRSTS_." = ?, ";
		$query .= ""._CLMN_CHR_LVLUP_POINT_." = ?";
		if($this->_resetStats == 1) {
			$query .= ", "._CLMN_CHR_STAT_STR_." = ?";
			$query .= ", "._CLMN_CHR_STAT_AGI_." = ?";
			$query .= ", "._CLMN_CHR_STAT_VIT_." = ?";
			$query .= ", "._CLMN_CHR_STAT_ENE_." = ?";
			$query .= ", "._CLMN_CHR_STAT_CMD_." = ?";
		}
		//Thêm lit cho relife
		$query .= ", MasterResetDay = ?";
		$query .= ", MasterResetWek = ?";
		$query .= ", MasterResetMon = ?";
		$query .= ", ResetMasterTime = ?";
		
		$query .= " WHERE "._CLMN_CHR_NAME_." = ?";
		
		$data[] = $this->_requiredResets;
		$data[] = $this->_requiredZen;
		$data[] = $playerNewGrandResets;
		$data[] = $levelUpPoints;
		if($this->_resetStats == 1) {
			$data[] = $baseStats['str'];
			$data[] = $baseStats['agi'];
			$data[] = $baseStats['vit'];
			$data[] = $baseStats['ene'];
			$data[] = $baseStats['cmd'];
		}
		$data[] = $playerData[MasterResetDay] + 1;
		$data[] = $playerData[MasterResetWek] + 1;
		$data[] = $playerData[MasterResetMon] + 1;
		//$data[] = date("Y-m-d H:i:sa");
		$data[] = date("Y-m-d H:i:s", strtotime("+7 hours"));
		$data[] = $playerData[_CLMN_CHR_NAME_];
		
		$reset = $this->mu->query($query, $data);
		if(!$reset) throw new \Exception(lang('grandreset_error_10'));
		
		// reward credits
		if($this->_rewardCredits == 1) {
			$creditSystem = new \CreditSystem();
			$creditSystem->setConfigId($this->_rewardCreditsConfig);
			$configSettings = $creditSystem->showConfigs(true);
			switch($configSettings['config_user_col_id']) {
				case 'userid':
					$creditSystem->setIdentifier($accountId);
					break;
				case 'username':
					$creditSystem->setIdentifier($this->_username);
					break;
				default:
					throw new Exception(lang('error_73'));
			}
			$creditSystem->addCredits($this->_rewardCreditsAmount);
		}

		redirect(1, 'usercp/grandreset/');
	}
	
	// PRIVATE FUNCTIONS
	
	private function _moduleExists($module) {
		if(!check_value($module)) return;
		if(!file_exists(__PATH_GRANDRESET_ROOT__ . $this->_modulesPath . '/' . $module . '.php')) return;
		return true;
	}
	
	private function _loadAccountPlayerList() {
		if(!check_value($this->_username)) throw new \Exception('The provided account username is not valid.');
		
		$Character = new \Character();
		$AccountCharacters = $Character->AccountCharacter($this->_username);
		if(!is_array($AccountCharacters)) throw new \Exception(lang('error_46'));
		
		foreach($AccountCharacters as $player) {
			$characterData = $Character->CharacterData($player);
			if(!is_array($characterData)) continue;
			if(!array_key_exists(_CLMN_CHR_GRSTS_, $characterData)) throw new \Exception(lang('grandreset_error_4'));
			$result[] = $characterData;
		}
		
		if(!is_array($result)) return;
		$this->_characters = $result;
	}
	
	private function _getPlayerData() {
		if(!check_value($this->_player)) return;
		if(!is_array($this->_characters)) return;
		foreach($this->_characters as $character) {
			if($character[_CLMN_CHR_NAME_] == $this->_player) return $character;
		}
		return;
	}
	
}