<?php

namespace bedwars\util;

use bedwars\game\BasicGame;
use bedwars\entity\GeneretorText;

use pocketmine\level\format\FullChunk;

use pocketmine\level\sound\AnvilUseSound;

use pocketmine\item\Item;
use pocketmine\math\Vector3;

use pocketmine\level\Level;

use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\nbt\tag\IntTag;

class Generetor {

    /** @var BasicGame */
    private $basicGame;

    /** @var array */
    private $fills = array();
    
    /** @var int */
    private $timeUpgrade = 450; //30s

    /** @var array */
    private $upgrade = array(
        "diamond" => 1,
        "emerald" => 1
    );

    /** @var array */
    private $ores = array();
    
    /** 
    * @param BasicGame $game
    */
    public function __construct(BasicGame $basicGame) {
        $this->basicGame = $basicGame;
    }
    
    public function start() {
        $generetors = (array) $this->basicGame->generetors;
        
        foreach ($generetors as $key => $value) {
            foreach ($value as $toString) {
                $args = explode(":", $toString);
                $this->spawn($key, $args);
            }
        }
        
    }
    
    public function close() {
        foreach ($this->fills as $key => $fill) {
            if ($fill instanceof GeneretorFill) {
                $fill->stop();
            }
            unset($this->fills[$key]);
        }
    }
    
    
    /**
     * @return array
     */
    public function getNextUpgrade() : array {
        $diamond = $this->upgrade['diamond'];
        $esmerald = $this->upgrade['emerald'];
        
        if ($diamond < 3) {
            return array("diamond", ++$diamond, $this->timeUpgrade);
        } else if ($esmerald < 3) {
            return array("emerald", ++$esmerald, $this->timeUpgrade);
        }
        
        return array(null, 0, 0);
    }

    public function run() {
        foreach ($this->fills as $fill) {
            $fill->onUpdate();
        }

        $type = $this->getNextUpgrade()[0];
    
        if ($type !== null) {
            if (--$this->timeUpgrade <= 0) {
                $this->timeUpgrade = 450;
                $this->upgrade[$type]++;
                $canMessage = 1;

                foreach ($this->fills as $fill) {
                    if ($fill->getType() === $type) {
                        $fill->setTier($this->upgrade[$type]);
                    }

                    if ($canMessage > 0) {
                        $canMessage--;
                        $this->basicGame->print("§r \n \n §fThe generators of " . $fill::TYPE_FORMAT[$fill->getType()] . " §fhave been upgraded to level " . $fill->getTier() . "§r \n \n \n");
            
                        foreach ($this->basicGame->getPlayers() as $player) {
                            if ($player instanceof Player) {
                                $player->level->addSound(new AnvilUseSound($player), array($player));
                            }
                        }
                    }
                }
            }
        }
        
        foreach ($this->basicGame->teams as $team => $args) {
            if (isset($this->basicGame->defaultTeams[$team])) {
                $data = $this->basicGame->defaultTeams[$team];
                
                if (isset($data["ores"])) {
                    if (isset($this->ores[$team])) {
                        $level = $this->basicGame->getUpgradeLevel($team, "forge");
                        
                        $ore = explode(":", $data["ores"]);
                        
                        if ($this->ores[$team][0]-- <= 0) {
                            $this->basicGame->level->dropItem(new Vector3($ore[0], $ore[1] + 1, $ore[2]), Item::get(265), new Vector3(0,0,0));
                            $this->ores[$team][0] = 5 - (array(0 => 0, 1 => 2, 2 => 3, 3 => 3))[$level];
                        }
                        
                        if ($this->ores[$team][1]-- <= 0) {
                            $this->basicGame->level->dropItem(new Vector3($ore[0], $ore[1] + 1, $ore[2]), Item::get(266), new Vector3(0,0,0));
                            $this->ores[$team][1] = 10 - (array(0 => 0, 1 => 2, 2 => 3, 3 => 3))[$level];
                        }
                        
                        if (mt_rand(0,3) == 1 and $level >= 3) {
                            $this->basicGame->level->dropItem(new Vector3($ore[0], $ore[1] + 1, $ore[2]), Item::get(388), new Vector3(0,0,0));
                        }
                    } else {
                        $this->ores[$team] = array(0 => 5, 1 => 10);
                    }
                }
            }
        }
    }

    /**
    * @param string $name
    * @param array  $args
    */
    public function spawn(string $name, array $args) {   
        if (!($this->basicGame->level instanceof Level)) {
            return false;
        }

        $x = ($args[0] + 0.5);
        $y = ($args[1] + 2.4);
        $z = ($args[2] + 0.5);

        $tier = 1;
        $type = $name;
        $time = ($name == "diamond" ? 40 : 60);

        $fill = new GeneretorFill($x, $y, $z, $this->basicGame->level, $tier, $type, $time);

        $this->fills[] = $fill;
    }
}
?>