package org.black_ixx.bossshop.managers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.black_ixx.bossshop.BossShop;
import org.black_ixx.bossshop.core.BSShopManager;
import org.black_ixx.bossshop.misc.Enchant;
import org.black_ixx.bossshop.points.PointsManager;
import org.black_ixx.timedCommands.StoreHandler;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;

import cc.util.bossshop.FBukkit;
import net.milkbowl.vault.permission.Permission;

public class WorthHandler{

    private BossShop mPlugin;
    
    public WorthHandler(BossShop pPlugin){
        this.mPlugin=pPlugin;
    }
    
    public String C(String pNode){
        return this.mPlugin.getLangManager().getNode(pNode);
    }
    
    public void giveRewardCommand(Player pPlayer,List<String> pCommands){
        for(String scmd : pCommands){
            scmd=StringManager.transform(BossShop.replaceParam(pPlayer,scmd));
            boolean tOp=pPlayer.isOp();
            try{
                pPlayer.setOp(true);
                pPlayer.performCommand(scmd);
            }catch(Throwable exp){
            }finally {
                pPlayer.setOp(tOp);
            }
        }
    }

    public void giveRewardPlayerCommand(Player pPlayer,List<String> pCommands){
        for(String scmd : pCommands){
            String command=StringManager.transform(BossShop.replaceParam(pPlayer,scmd));
            PlayerCommandPreprocessEvent event=new PlayerCommandPreprocessEvent(pPlayer,"/"+command);
            Bukkit.getPluginManager().callEvent(event);
            if(event.isCancelled()) continue;
            pPlayer.performCommand(event.getMessage().substring(1));
        }
    }

    public void giveRewardTimeCommand(Player pPlayer,HashMap<Integer,String> pCommands){
        StoreHandler s=this.mPlugin.getManager(TimeHandler.class).getTimedCommands().getStoreHandler();
        for(int i : pCommands.keySet()){
            String cmd=BossShop.replaceParam(pPlayer,pCommands.get(i));
            s.addCommandToHashMap(System.currentTimeMillis()+1000*i,cmd);
        }
    }

    public void giveRewardItem(Player p,ItemStack item){
        item=transformRewardItem(item.clone(),p);
        if(p.getInventory().firstEmpty()==-1){ // Inventory full
            if(item.getMaxStackSize()==1){ // Max Stack Size == 1
                p.getWorld().dropItem(p.getLocation(),item); // -> Drop Item
                return;
            }
        }
        int free=0;
        for(ItemStack sitem : p.getInventory().getContents()){
            if(sitem!=null&&sitem.getTypeId()!=0){
                if(ItemStackChecker.isSame(sitem,item)){ 
                    free+=sitem.getMaxStackSize()-sitem.getAmount();
                }
            }else{
                free+=item.getMaxStackSize();
            }
            if(free>=item.getAmount()) break;
        }
        if(free<item.getAmount()){
            ItemStack drop_item=item.clone();
            drop_item.setAmount(item.getAmount()-free);
            item.setAmount(free);
            p.getWorld().dropItem(p.getLocation(),drop_item);// Drop Item!
        }
        p.getInventory().addItem(item);
    }
    
    public void giveRewardItem(Player p,List<ItemStack> items){
        for(ItemStack i : items){
            this.giveRewardItem(p,i);
        }
    }

    public void giveRewardPermission(Player p,List<String> permissions){
        Permission per=this.mPlugin.getManager(VaultHandler.class).getPermission();
        for(String s : permissions){
            per.playerAdd(p,s);
        }
    }

    public void giveRewardMoney(Player p,double money){
        VaultHandler vaultMan=this.mPlugin.getManager(VaultHandler.class);
        if(!vaultMan.getEconomy().hasAccount(p.getName())){
            this.mPlugin.send(p,C("Economy.NoAccount"));
            this.mPlugin.severe("Unable to give "+p.getName()+" his/her money: He/She does not have an Economy Account");
            return;
        }
        vaultMan.getEconomy().depositPlayer(p.getName(),money);
    }

    public void giveRewardPoints(Player p,Integer points){
        this.mPlugin.getManager(PointsManager.class).givePoints(p,points);
    }

    public void giveRewardShop(Player p,String shopName){
        if(shopName==null||shopName==""||shopName.length()<1){
            p.closeInventory();
            return;
        }
        this.mPlugin.getManager(BSShopManager.class).openShop(p,shopName);
    }

    public void giveRewardEnchantment(Player p,Enchant e){
        if(p.getItemInHand()!=null){
            p.getItemInHand().addUnsafeEnchantment(e.getType(),e.getLevel());
        }
    }
    
    public boolean hasExp(Player p,int price){
        if((p.getLevel()<(Integer)price)){
            this.mPlugin.send(p,C("NotEnough.Exp"));
            return false;
        }
        return true;
    }

    public boolean hasItems(Player p,List<ItemStack> items){
        for(ItemStack i : items){
            if(!ItemStackChecker.inventoryContainsItem(p,i)){
                this.mPlugin.send(p,C("NotEnough.Item"));
                return false;
            }
        }
        return true;
    }

    public boolean hasMoney(Player p,double money){
        VaultHandler vaultMan=this.mPlugin.getManager(VaultHandler.class);
        if(!vaultMan.getEconomy().hasAccount(p.getName())){
            this.mPlugin.send(p,C("Economy.NoAccount"));
            return false;
        }
        if(vaultMan.getEconomy().getBalance(p.getName())<money){
            this.mPlugin.send(p,C("NotEnough.Money"));
            return false;
        }
        return true;
    }

    public boolean hasPoints(Player p,Integer points){
        if(this.mPlugin.getManager(PointsManager.class).getPoints(p)<points){
            this.mPlugin.send(p,C("NotEnough.Points"));
            return false;
        }
        return true;
    }
    
    
    public String takeExp(Player p,int exp){
        p.setLevel(p.getLevel()-exp);
        return ""+p.getLevel();
    }

    public String takeItems(Player p,List<ItemStack> items){
        for(ItemStack i : items){
            ItemStackChecker.takeItem(i,p);
        }
        return null;
    }

    public String takeMoney(Player p,double money){
        VaultHandler vaultMan=this.mPlugin.getManager(VaultHandler.class);
        if(!vaultMan.getEconomy().hasAccount(p.getName())){
            this.mPlugin.severe("Unable to take money! No economy account existing! ("+p.getName()+", "+money+")");
            return "";
        }
        vaultMan.getEconomy().withdrawPlayer(p.getName(),money);
        return ""+vaultMan.getEconomy().getBalance(p.getName());
    }

    public String takePoints(Player p,Integer d){
        return ""+this.mPlugin.getManager(PointsManager.class).takePoints(p,d);
    }
    
    private ItemStack transformRewardItem(ItemStack i,Player p){
        if(i.hasItemMeta()){
            ItemMeta meta=i.getItemMeta();
            //设置骷髅所有者
            if(meta instanceof SkullMeta){
                SkullMeta skullMeta=(SkullMeta)meta;
                if(skullMeta.hasOwner()) skullMeta.setOwner(BossShop.replaceParam(p,skullMeta.getOwner()));
            }
            if(meta.hasDisplayName()){
                meta.setDisplayName(BossShop.replaceParam(p,meta.getDisplayName()));
            }
            if(meta.hasLore()){
                List<String> new_lore=new ArrayList<String>();
                for(String s : meta.getLore()){
                    new_lore.add(BossShop.replaceParam(p,s));
                }
                meta.setLore(new_lore);
            }
            if(!FBukkit.isItemMetaEmpty(meta))
                i.setItemMeta(meta);
        }
        return i;
    }
    
}

