<?php

namespace bedwars\entity;

use pocketmine\Player;
use pocketmine\entity\Entity;

use pocketmine\item\Item;

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

use bedwars\BedWars;
use bedwars\game\Game;
use bedwars\inventory\Inventory;

use pocketmine\level\sound\ExpPickupSound;
use pocketmine\level\sound\SplashSound;

class Shop extends VillagerNPC {
    
    /** @var int */
    public $type = 15;
    
    /** @var array */
    public $nametag = ["§r§f§lITEMSHOP", "§eRight Click"];
    
    const MENU = array(
        "blocks" => array("§r§eBlocks", 35, 0, null),
        "armor" => array("§r§fArmor", 307, 0, null),
        "pickaxe" => array("§r§3Pickaxe", 270, 0, null),
        "axe" => array("§r§3Axe", 271, 0, null),
        "swords" => array("§r§fSwords", 267, 0, null),
        "arrow" => array("§r§fArrows", 261, 0, null),
        "potions" => array("§r§fPotions", 374, 0, null),
        "util" => array("§r§fAccessories", 378, 0, null)
    );
    
    const ITEMS = array(
        "blocks" => array(
            "§r§fLã" => array(35, 0, 16, null, 4, 0),
            "§r§eClay Block" => array(172, 0, 16, null, 10, 0),
            "§r§fGrass block" => array(20, 0, 4, null, 7, 1),
            "§r§3End Block" => array(121, 0, 12, null, 4, 1),
            
            "§r§3Wood Block" => array(5, 0, 16, null, 7, 1),
            "§r§0Obsidian" => array(49, 0, 4, null, 4, 2)
        ),
        "armor" => array(
             "§r§fPickaxe" => array(303, 0, 1, null, 12, 0),
            "§r§fIron Armor" => array(307, 0, 1, null, 12, 1),
            "§r§bDiamond Armor" => array(311, 0, 1, null, 6, 2)
        ),
        "pickaxe" => array(
            "§r§3Wooden Pickaxe" => array(270, 0, 1, null, 10, 0),
            "§r§7Stone Pickaxe" => array(274, 0, 1, null, 4, 1),
            "§r§fIron Pickaxe" => array(257, 0, 1, null, 30, 0),
            "§r§bDiamond Pickaxe" => array(278, 0, 1, null, 4, 2)
        ),
        "axe" => array(
            "§r§3Wooden Axe" => array(271, 0, 1, null, 8, 0),
            "§r§7Stone Axe" => array(275, 0, 1, null, 12, 0),
            "§r§fIron Axe" => array(258, 0, 1, null, 12, 1),
            "§r§bDiamond Axe" => array(279, 0, 1, null, 7, 2)
        ),
        "swords" => array(
            "§r§3Wooden Sword" => array(268, 0, 1, null, 4, 0),
            "§r§7Stone Sword" => array(272, 0, 1, null, 12, 1),
            "§r§fIron Sword" => array(267, 0, 1, null, 7, 1),
            "§r§bDiamond Sword" => array(276, 0, 1, null, 4, 2)
        ),
        "arrow" => array(
            "§r§aBow" => array(261, 0, 1, null, 12, 1),
            "§r§cArrow" => array(262, 0, 4, null, 2, 1)
        ),
        "potions" => array(
            "§r§aSpeed Potion" => array(373, 11, 1, null, 4, 2),
            "§r§fJump Potion" => array(373, 16, 1, null, 4, 2),
            "§r§7Invisablity Potion" => array(373, 7, 1, null, 4, 2),
        ),
        "util" => array(
            "§r§cFireBall" => array(378, 0, 1, null, 32, 0),
            "§r§fEnder Pearl" => array(351, 5, 1, null, 4, 2),
            "§r§cTNT" => array(46, 0, 1, null, 8, 1),
            "§r§fSheers" => array(359, 0, 1, null, 6, 1),
            "§r§cGolden Apple" => array(322, 0, 1, null, 3, 1),
            "§r§cEnchanted Golden Apple" => array(466, 0, 1, null, 4, 2),
            "§r§cRocket" => array(368, 0, 1, null, 7, 2)
        )
    );
    
    const ICONS = array();
    
    const TYPE_VIEWER = "§r§7(Click To View)";
    const TYPE_BUY = " §r§7(Click To Buy)";
    const LINE_PRICE = "§r§8Price:§f {price} {type}";
    const BACK_TO_MENU = "§r§cGo Back To §lMENU§r";
    
    /** 
    * @param Player $player
    */
    public function open(Player $player) {
        $game = BedWars::$loaded->getGame($player);

        if (!($game instanceof Game)) {
            $player->sendMessage("§cThe store is only available within the game!");
            return false;
        }
        
        if ($game->index != 3) {
            $player->sendMessage("§cYou can only see the store when the game starts!");
            return false;
        }
        
        if (isset($game->espects[$player->getName()]) or isset($game->respawn[$player->getName()])) {
            $player->sendMessage("§cPlayers in spectator mode cannot open the upgrade shop!");
            return false;
        }
        
        $team = $game->getTeam($player->getName());
        $damage = $game->getDamage($team->getName());
        
        $inventory = new Inventory($player, "§r§l§fSHOP§r");
        $player->addWindow($inventory);
        
        $this->addMenu($inventory, $damage);
        
        $inventory->addEvent($player, function(Player $player, Item $item, $inventory) {
            $game = BedWars::$loaded->getGame($player);

            if (!($game instanceof Game)) {
                return false;
            }
        
            $team = $game->getTeam($player->getName());
            $damage = $game->getDamage($team->getName());
            $custom = $item->getCustomName();
            $namedtag = $item->getNamedTag();
            
            if ($custom === self::BACK_TO_MENU) {
                $this->addMenu($inventory, $damage);
                return true;
            }
            
            if ($namedtag instanceof CompoundTag) {
                if (isset($namedtag["Type"])) {
                    $type = $namedtag["Type"];

                    if (isset(self::ITEMS[$type])) {
                        if (isset($namedtag["Price"], $namedtag["Real"], $namedtag["newName"])) {
                            $price = (int) $namedtag["Price"];
                            $real = (int) $namedtag["Real"];
                            $realById = ($real == 0 ? 265 : ($real == 1 ? 266 : 388));
                            $realFormat = ($real == 0 ? "§fIron" : ($real == 1 ? "§eGold" : "§2Emeralds"));
                            $itemName = $namedtag["ItemName"];
                            $newName = $namedtag["newName"];
                            $count = 0;
                        
                            foreach ($player->getInventory()->getContents() as $slot => $itemI) {
                                if ($itemI->getId() == $realById) {
                                   $count += $itemI->getCount();
                                   if ($count >= $price) 
                                       break;
                               }
                            }
                        
                            if ($count >= $price) {
                                $player->sendMessage("§r§aYou bought §l" . $itemName . "§r§a " . $item->getCount() . " for " . $price . " §l" . $realFormat . "§r§a!");
                                $player->getInventory()->removeItem(Item::get($realById, 0, $price));
                                
                                $isArmor = false;
                                
                                $purchsed = $item;
                                $namedtag = new CompoundTag("", []);
                                $player->level->addSound(new ExpPickupSound($player), array($player));
                                
                                switch ($item->getId()) {
                                    case 270:
                                    case 257:
                                        $game->tools[$player->getName()]["pickaxe"] = Item::get($item->getId());
                                        break;
                                    
                                    case 271:
                                    case 258:
                                        $game->tools[$player->getName()]["axe"] = Item::get($item->getId());
                                        break;
                                        
                                    case 299:
                                    case 307:
                                    case 303:
                                    case 311:
                                        $isArmor = true;
                                        break;
                                    case 373:
                                        $effectTime = 0;
                                        $effectId = 0;
                                        switch ($item->getDamage()) {
                                            case 11:
                                                $effectTime = 30;
                                                $effectId = 8;
                                                break;
                                            case 16:
                                                $effectTime = 30;
                                                $effectId = 1;
                                                break;
                                            case 7:
                                                $effectTime = 30;
                                                $effectId = 14;
                                                break;
                                        }
                                        $namedtag->EffectTime = new IntTag("EffectTime", $effectTime);
                                        $namedtag->EffectId = new IntTag("EffectId", $effectId);
                                        break;
                                }
                                
                                $purchsed->setNamedTag($namedtag);
                                $purchsed->setCustomName($newName);
                                
                                if ($isArmor) {
                                    $chestplate = $purchsed;
                                    $leggings = Item::get(($purchsed->getId() + 1), $purchsed->getDamage());
                                    $player->getInventory()->setChestplate($chestplate);
                                    $player->getInventory()->setLeggings($leggings);
                                    
                                    $game->armors[$player->getName()] = array(
                                        $chestplate,
                                        $leggings
                                    );
                                    $player->removeWindow($inventory);
                                } else {
                                    $player->getInventory()->addItem($purchsed);
                                }
                                $game->updateItems($team->getName(), $player);
                            } else {
                                $player->sendMessage("§r§cYou don't have enough items! You need: " . ($price - $count) . " §l" . $realFormat);
                                $player->removeWindow($inventory);
                                $player->level->addSound(new SplashSound($player), array($player));
                            }
                        } else {
                            $contents = array();
                            $slot = 0;
                            
                            foreach (self::ITEMS[$type] as $name => $data) {
                                $item = Item::get($data[0], $data[1], $data[2]);
                            
                                if ($data[0] == 35) {
                                    $item->setDamage($damage);
                                }
                                $lines = explode("\n", $name);
                                $lines[0] .= self::TYPE_BUY;
                                $lines[1] = str_replace(["{price}", "{type}"], [$data[3], ($data[5] == 0 ? "§fIron" : ($data[5] == 1 ? "§eGold" : "§2Emeralds"))], self::LINE_PRICE);
                                $item->setCustomName(implode("\n", $lines));
                                
                                $nbt = $item->getNamedTag();
                                $nbt->Type = new StringTag("Type", $type);
                                $nbt->Price = new IntTag("Price", $data[4]);
                                $nbt->Real = new IntTag("Real", $data[5]);
                                $nbt->newName = new StringTag("newName", $name);
                                $item->setNamedTag($nbt);
                                $contents[$slot++] = $item;
                            }
                            $back = Item::get(152);
                            $back->setCustomName(self::BACK_TO_MENU);
                            $contents[25] = $back;
                            $inventory->setContents($contents);
                        }
                    }
                }
            }
        });
        return true;
    }
    
    /**
    * @param Inventory $inventory
    * @param int       $damage
    */
    public function addMenu($inventory, $damage) {
        $contents = array();
        $slot = 0;
        
        foreach (Shop::MENU as $type => $args) {
            $item = Item::get($args[1], $args[2]);
            
            if ($item->getId() == Item::WOOL) {
                $item->setDamage($damage);
            }
            
            $item->setCustomName($args[0] . " " . self::TYPE_VIEWER);
            $nbt = $item->getNamedTag();
            $nbt->Type = new StringTag("Type", $type);
            $item->setNamedtag($nbt);
            
            $contents[$slot++] = $item;
        }
        $inventory->setContents($contents);
    }
    
}
?>