<?php

namespace Juqn\Arena;

use Juqn\Loader;
use Juqn\Utils\Utils;
use pocketmine\block\Block;
use pocketmine\item\enchantment\Enchantment;
use pocketmine\item\Item;
use pocketmine\level\Position;
use pocketmine\math\Vector3;
use pocketmine\Player;
use pocketmine\Server;

class Arena {
	
	public $data;
	
	const STATUS_WAITING = 0;
	const STATUS_STARTING = 1;
	const STATUS_RUN = 2;
	
	public $status = 0;
	
	public $starting = 20;
	
	public $players = [];
	
	public $lastHit = [];

	public $slots = [];
	
	public function __construct(array $data){
		$this->data = $data;
		$this->initMap();
		$this->reset(false);
	}

	public function getPlugin() : Loader {
	    $return = '';
	    $plugin = Server::getInstance()->getPluginManager()->getPlugin("MLGBlock");
	    if($plugin instanceof Loader and $plugin->isEnabled()){
	        $return = $plugin;
        }
	    return $return;
    }

    public function getUtils(){
	    return (new Utils($this->getPlugin()));
    }
    
    public function initMap(){
    	$utils = $this->getUtils();
    	$map = $this->data["level-name"];
    	if($utils->backupExists($map)){
    		$this->resetMap();
    		return true;
    	}
    	$utils->backupMap($map, $this->getPlugin()->getDataFolder());
    	return true;
    }
    
    public function resetMap(){
    	$utils = $this->getUtils();
		$map = $this->data["level-name"];
		$utils->resetMap($map);
    }
	
	public function getPlayer($name){
		if(isset($this->players[$name])){
			return true;
		}
		return false;
	}
	
	public function getPlayers(){
		return $this->players;
	}
	
	public function getName(){
		return $this->data["name"];
	}
	
	public function getLevel(){
		return Server::getInstance()->getLevelByName($this->data["level-name"]);
	}
	
	public function getSlots(){
		return $this->data["slots"];
	}
	
	public function getStatus(){
		return $this->status;
	}
	
	public function getSpawn($slots = 1){
		$data = $this->data["spawns"];
		if(isset($data[$slots])){
			$spawn = $data[$slots];
			return new Position($spawn[0], $spawn[1], $spawn[2] , $this->getLevel());
		}
		return false;
	}
	
	public function startGame(){
		for($i = 1; $i <= $this->getSlots(); $i++){
			$spawn = $this->getSpawn($i);
			$block = $this->getLevel()->getBlock(new Vector3($spawn->x, $spawn->y - 1, $spawn->z));
			if($block->getId() == 20){
				$this->getLevel()->setBlock(new Vector3($spawn->x, $spawn->y - 1, $spawn->z), Block::get(0));
			}
		}
	}
	
	public function backPosition(Player $player){
		$back = false;
		foreach($this->slots as $id => $name){
			if(!$back){
				if($name == $player->getName()){
					$player->teleport($this->getSpawn($id));
					$back = true;
				}
			}
		}
	}
	
	public function reset($type = true){
		$this->status = 0;
		$this->slots = [];
		$this->players = [];
		$this->starting = 20;
		$this->lastHit = [];
		if($type){
		    $this->resetMap();
		}
	}
	
	public function join(Player $player){
		if($this->status == self::STATUS_WAITING){
			if(count($this->getPlayers()) == $this->getSlots()){
				return false;
			}
		}
		if($this->status == self::STATUS_STARTING){
			if(count($this->getPlayers()) == $this->getSlots()){
				return false;
			}
			if($this->starting < 3){
				return false;
			}
		}
		if($this->status == self::STATUS_RUN){
			return false;
		}
		$this->players[$player->getName()] = $player;
		$player->setGamemode(0);
		$player->setFood(20);
		$player->setHealth(20);
		$player->removeAllEffects();
		$player->getInventory()->clearAll();
		$sair = Item::get(355, 0);
		$sair->setCustomName("§cLeave");
		$player->getInventory()->setItem(8, $sair);
		$select = false;
		for($i = 1; $i <= $this->getSlots(); $i++){
			if(!$select){
				if(!isset($this->slots[$i])){
					$this->slots[$i] = $player->getName();
					$player->teleport($this->getSpawn($i));
					$select = true;
				}
			}
		}
		foreach($this->getPlayers() as $players){
			$players->sendMessage("§8(§aM§fB§8) §e{$player->getName()}§f joined the game! §7[".count($this->getPlayers())."/{$this->getSlots()}]");
		}
		return true;
	}
	
	public function quit(Player $player){
		$player->setFood(20);
		$player->setHealth(20);
		$player->removeAllEffects();
		$player->getInventory()->clearAll();
		$player->teleport(Server::getInstance()->getDefaultLevel()->getSafeSpawn());
		foreach ($this->slots as $key => $value) {
			if($value == $player->getName()){
				unset($this->slots[$key]);
			}
		}
		unset($this->players[$player->getName()]);
		return true;
	}
	
	public function getKit(Player $player){
		$inv = $player->getInventory();
		$inv->clearAll();
		$helmet = Item::get(302, 0);
		$chestplate = Item::get(303, 0);
		$leggings = Item::get(304, 0);
		$boots = Item::get(305, 0);
		$feathers = Item::get(288, 0);
		$feathers->setCount(8);
		$goldenApple = Item::get(322, 0);
		$goldenApple->setCount(2);
		$snowBlock = Item::get(80, 0);
		$snowBlock->setCount(64);
		$inv->setHelmet($helmet);
		$inv->setChestplate($chestplate);
		$inv->setLeggings($leggings);
		$inv->setBoots($boots);
		$inv->setItem(0, $feathers);
		$inv->setItem(1, $goldenApple);
		$inv->setItem(2, $snowBlock);
		$inv->setItem(3, $snowBlock);
		$inv->setItem(4, $snowBlock);
	}
	
	// //
	
	public function setLastHit(Player $player, Player $damager){
		$name = $player->getName();
		$n = $damager->getName();
		if(isset($this->lastHit[$name])){
			$this->lastHit[$name] = [
				"damager" => $n,
				"time" => time()
			];
		} else {
			$this->lastHit[$name] = [
				"damager" => $n,
				"time" => time()
			];
		}
	}
	
	public function getLastHit(Player $player){
		$name = $player->getName();
		if(isset($this->lastHit[$name])){
			$data = $this->lastHit[$name];
			if(time() - $data["time"] <= 20){
				return $data["damager"];
			}
		}
		return false;
	}
}