package org.black_ixx.bossshop.core;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.black_ixx.bossshop.BossShop;
import org.black_ixx.bossshop.managers.DefaultCreator;
import org.black_ixx.bossshop.nbt.NBTEditManager;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;

import cc.util.bossshop.FBukkit;
import cc.util.bossshop.pluginmodel.INeedReload;

public class BSShopManager implements INeedReload{

    private long mLastReloadTime=0;
    private BossShop mPlugin;
    private File folder;
    private final HashMap<String,BSShop> shops=new HashMap<String,BSShop>();
    
    /**
     * 商店管理器
     * @param plugin
     */
    public BSShopManager(BossShop plugin){
        this.mPlugin=plugin;
        this.folder=new File(plugin.getDataFolder().getAbsolutePath()+"/shops/");
        this.mPlugin.registerReloadModel(this);
    }

    /**
     * 重载或载入所有商店
     */
    @Override
    public boolean reloadConfig(){
        if(!folder.isDirectory()) createDefaults();
        Iterator<Map.Entry<String,BSShop>> it=this.shops.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry<String,BSShop> entry=it.next();
            BSShop shop=entry.getValue();
            if(!shop.reloadShop()){
                this.mPlugin.debug("商店["+shop.mShopName+"]由于配置文件不存在,移除");
                it.remove();
            }
        }
        for(File file : folder.listFiles()){
            if(file==null||!file.isFile()) continue;
            String name=file.getName();
            if(name.toLowerCase().endsWith(".yml")) this.loadShop(file);
        }
        this.mPlugin.info("载入了 "+shops.size()+" Shops!");
        this.mLastReloadTime=System.currentTimeMillis();
        // 一定要在调用清理函数之前调用时间
        if(this.mPlugin.getConfigManager().isAutoClearNBT())
            this.mPlugin.getManager(NBTEditManager.class).clearNBT();
        this.updataAllInventory();
        return true;
    }
    
    public long getLastReloadTime(){
        return this.mLastReloadTime;
    }
    
    /**
     * 重载所有由BS插件生成的背包
     * <p>商店配置重载后悔自动调用该函数</p>
     */
    public void updataAllInventory(){
        for(Player player : FBukkit.getOnlinePlayers()){
            Inventory inv=player.getOpenInventory().getTopInventory();
            if(inv.getHolder() instanceof BSShopHolder){
                BSShopHolder holder=(BSShopHolder)inv.getHolder();
                holder.getShop().updateInventory(inv,player);
            }
        }
    } 
    
    /**
     * 检查根据机读名称(文件名)对应的商店是否存在
     * @param name 商店机读名称,忽略大小写
     * @return 是否存在
     */
    public boolean isShopExist(String name){
        return !(this.getShop(name)==null);
    }
    
    /**
     * 检查指定的商店是否存在(多用于配置重载后的商店数据检验)
     * @param shop 商店
     * @return 是否存在
     */
    public boolean isShopExist(BSShop shop){
        return this.shops.containsValue(shop);
    }

    /**
     * 根据商店机读名称(文件名)获取指定的商店,不存在则返回null
     * @param name 商店机读名称,忽略大小写
     * @return 商店
     */
    public BSShop getShop(String name){
        for(Map.Entry<String,BSShop> entry : this.shops.entrySet()){
            if(entry.getKey().equalsIgnoreCase(name)) return entry.getValue();
        }
        return null;
    }

    /**
     * 增加一个商店到管理器中
     */
    public void addShop(BSShop pShop){
        this.shops.put(pShop.getShopName(),pShop);
    }
    
    public BSShop removeShop(BSShop pShop){
        return this.shops.remove(pShop);
    }
    
    /**
     * 根据指定的文件载入所需的商店
     * <p>如果商店已经载入,则重新载入但是商店对象不变,如果商店文件不存在,则去除该商店</p>
     * @param file 要载入商店的文件
     * @return 载入后的商店,自动添加到商店列表
     */
    private BSShop loadShop(File file){
        String fileName=file.getName();
        String shopName=getName(fileName);
        BSShop shop=this.getShop(shopName);
        if(shop!=null) return shop;
        else{
            shop=new BSShop(this.mPlugin,fileName,shopName);
            shop.reloadConfig();
            this.shops.put(shopName,shop);
        }
        return shop;
    }

    /**
     * 根据文件名生成商店名
     * @param filename 文件名
     * @return 去掉后缀的字符串
     */
    public static String getName(String filename){
        int pos=filename.lastIndexOf('.');
        if(pos!=-1) return filename.substring(0,pos);
        else return filename;
    }
    
    /**
     * 根据机读名字移除指定的商店
     * @param name 机读名字
     * @return 被移除的商店,如果不存在则为null
     */
    private BSShop removeShop(String name){
        Iterator<Map.Entry<String,BSShop>> it=this.shops.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry<String,BSShop> entry=it.next();
            if(entry.getKey().equalsIgnoreCase(name)){
                it.remove();
                return entry.getValue();
            }
        }
        return null;
    }
    
    /**
     * 根据机读名称为玩家打开指定的商店
     * @param player 玩家
     * @param name 商店机读名
     */
    public void openShop(Player player,String name){
        BSShop shop=this.getShop(name);
        if(shop==null){
            this.mPlugin.send(player,this.mPlugin.getLangManager().getNode("Main.ShopNotExisting"));
            return;
        }
        this.openShop(player,shop);
    }

    /**
     * 为玩家打开指定的商店
     * @param player 玩家
     * @param shop 商店
     */
    public void openShop(Player player,BSShop shop){
        shop.openInventory(player);
        this.mPlugin.send(player,shop.getEnterMessage());
    }
 
    public HashMap<String,BSShop> getShops(){
        return shops;
    }

    /**
     * 创建默认的商店
     */
    public void createDefaults(){
        new DefaultCreator().addAllExamples();
    }
}
