package org.black_ixx.bossshop.command;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.black_ixx.bossshop.BossShop;
import org.black_ixx.bossshop.core.BSShopManager;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.TabCompleter;

import cc.util.bossshop.Function;

public class CommandExc implements CommandExecutor,TabCompleter{

    private final Map<String,ACommandBase> mCommands=new LinkedHashMap<>();
    private final String mPluginCmdLabel="/shop";
    private BossShop mPlugin;
    
    /**
     * 必须在配置文件启用后才能调用此方法
     * @param pPlugin
     */
    public CommandExc(BossShop pPlugin){
        this.mPlugin=pPlugin;
        //绑定执行器
        PluginCommand tCmd=null;
        for(String sMainCmd : this.mPlugin.getDescription().getCommands().keySet()){
            if((tCmd=this.mPlugin.getCommand(sMainCmd))!=null){
                tCmd.setExecutor(this);
                tCmd.setTabCompleter(this);
            }
        }
        //注册子命令
        this.register("clear",new CommandClear(this));
        this.register("close",new CommandClose(this));
        this.register("help",new CommandHelp(this));
        this.register("name",new CommandName(this));
        this.register("mail",new CommandMail(this));
        this.register("nbt",new CommandNBT(this));
        this.register("open",new CommandOpen(this));
        this.register("reload",new CommandReload(this));
        this.register("sale",new CommandSale(this));
        this.register("unsale",new CommandUnsale(this));
    }

    /**获取主插件实例*/
    public BossShop getPlugin(){
        return this.mPlugin;
    }

    /**获取主命令标签,包括斜杠*/
    public String getLabel(){
        return this.mPluginCmdLabel;
    }

    /**获取命令标签Set集合的拷贝*/
    public Set<String> keySet(){
        HashSet<String> cmdLabels=new HashSet<>();
        cmdLabels.addAll(this.mCommands.keySet());
        return cmdLabels;
    }

    /**
     * 根据标签名获取子命令,忽略标签大小写
     */
    public ACommandBase getCommand(String pLabel){
        for(Entry<String,ACommandBase> sEntry : this.mCommands.entrySet()){
            if(sEntry.getKey().equalsIgnoreCase(pLabel)) return sEntry.getValue();
        }
        return null;
    }

    /**
     * 根据标类获取子命令
     */
    public ACommandBase getCommand(Class<? extends ACommandBase> pClazz){
        for(ACommandBase scmd : this.mCommands.values()){
            if(scmd.getClass()==pClazz) return scmd;
        }
        return null;
    }

    /**
     * 注册指令到指令列表中
     * @param pLabel 指令标签
     * @param pCmd 指令实例
     */
    public ACommandBase register(String pLabel,ACommandBase pCmd){
        return this.mCommands.put(pLabel==null?null:pLabel.toLowerCase(),pCmd);
    }

    /**
     * 更改命令模块的标签名
     * @param pCmdClazz 命令模块类
     * @param pNewLabel 新的名字
     * @return 是否成功
     */
    @Deprecated
    public boolean replaceLabel(Class<? extends ACommandBase> pCmdClazz,String pNewLabel){
        if(StringUtils.isBlank(pNewLabel)) return false;
        pNewLabel=pNewLabel.toLowerCase();
        if(this.mCommands.get(pNewLabel)!=null) return false;
        for(Map.Entry<String,ACommandBase> tCmdEntry : this.mCommands.entrySet()){
            if(pCmdClazz.isInstance(tCmdEntry.getValue())){
                this.mCommands.put(pNewLabel,this.mCommands.remove(tCmdEntry.getKey()));
                return true;
            }
        }
        return false;
    }
    
    @Override
    public boolean onCommand(CommandSender pSender,Command command,String pLabel,String[] pArgs){
        try{
            String cmdLabel=this.mPlugin.getConfigManager().getMainShop();
            if(pArgs.length>0) cmdLabel=pArgs[0];
            ACommandBase cmd=this.getCommand(cmdLabel);
            
            if(cmd!=null){
                if(pArgs.length>0) pArgs=Arrays.copyOfRange(pArgs,1,pArgs.length);
                return cmd.execute(pSender,pArgs);
            }else{
                if(this.mPlugin.getManager(BSShopManager.class).getShop(cmdLabel)!=null)
                    this.getCommand(CommandOpen.class).execute(pSender,new String[]{cmdLabel});
                else return this.mPlugin.send(pSender,this.mPlugin.C("Cmd.UnknowCommand"));
            }
        }catch(Throwable exp){
            this.mPlugin.severe(this.mPlugin.C("Cmd.ErrorHappedWhenHandlerCmd")+exp.getMessage(),exp);
            this.mPlugin.send(pSender,this.mPlugin.C("Main.ErrorHappend"));
        }
        return true;
    }
    
    /**
     * Tab命令自动补全
     * <p>
     * 会首先检查 插件名.cmdcomplete权限,如果不存在直接返回</br>
     * </p>
     * @return
     */
    public List<String> onTabComplete(CommandSender pSender,Command pCmd,String pStr,String[] pArgs){
        if(!pSender.hasPermission(this.mPlugin.getPluginName()+".cmdcomplete")) return null;
        ArrayList<String> list=new ArrayList<>();
        if(pArgs.length==0){
            list.addAll(this.mCommands.keySet());
        }else if(pArgs.length==1){
            Collection<String> samePrefixTabs=Function.getSamePrefixIgnoreCase(this.mCommands.keySet(),pArgs[0],true);
            if(samePrefixTabs.size()==0){
                String findTab=Function.getIgnoreCase(this.mCommands.keySet(),pArgs[0]);
                if(findTab!=null){
                    if(this.getCommand(findTab).getMaxArgumentLength()>0) list.add(findTab+" ");
                    else list.add(findTab);
                }
            }else if(samePrefixTabs.size()==1){
                String findTab=samePrefixTabs.toArray()[0].toString();
                if(this.getCommand(findTab).getMaxArgumentLength()>0) list.add(findTab+" ");
                else list.add(findTab);
            }else list.addAll(samePrefixTabs);
        }else{
            ACommandBase tCmd=this.getCommand(pArgs[0]);
            if(tCmd!=null&&tCmd.getMaxArgumentLength()>0) list.addAll(tCmd.onTabComplete(pSender,Arrays.copyOfRange(pArgs,1,pArgs.length)));
        }
//        this.mPlugin.send(pSender,"Tab输入:"+Function.asList(pArgs));
//        this.mPlugin.send(pSender,"Tab返回:"+list);
        return list;
    }

    public void reload(){}
    
}
