package org.black_ixx.bossshop.command;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.black_ixx.bossshop.BossShop;
import org.bukkit.command.CommandSender;

import cc.util.bossshop.Function;

/**
 * @author 聪聪
 *
 */
public abstract class ACommandBase{

    public final static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");
    
    /**命令执行器*/
    protected CommandExc mExector;
    /**主插件*/
    protected BossShop mPlugin;
    /**主命令,包括斜杠*/
    protected String mMainCmdLabel;
    /**插件名,用于权限节点的生成*/
    protected String mPluginName;

    public ACommandBase(CommandExc pExector){
        this.mExector=pExector;
        this.mPlugin=pExector.getPlugin();
        this.mMainCmdLabel=pExector.getLabel();
        this.mPluginName=this.mPlugin.getPluginName();
    }

    /**
     * 给玩家发送一条消息
     * @return true 
     */
    public boolean send(CommandSender pSender,String pMsg){
        this.mPlugin.send(pSender,pMsg);
        return true;
    }

    /**
     * 给玩家发送多条消息
     * @return true 
     */
    public boolean send(CommandSender pSender,List<String> pMsgs){
        for(String sMsg : pMsgs)
            this.mPlugin.send(pSender,sMsg);
        return true;
    }

    /**
     * 翻译一个语言节点
     */
    public String C(String node){
        return this.mPlugin.getLangManager().getNode(node);
    }

    /**
     * 发送该命令的帮助到指定的用户
     * @param pSender 需要获取帮助的用户
     * @return 永远为true
     */
    public boolean help(CommandSender pSender){
        ArrayList<String> chelp=getHelp(pSender,false);
        if(chelp==null||chelp.isEmpty()){
            send(pSender,this.C("Cmd.UnknowCommand"));
        }else for(String ccc : chelp){
            send(pSender,ccc);
        }
        return true;
    }

    /**
     * 如果命令无法处理其子命令时调用,命令类名字的格式必须是Command***
     * <p>
     * 调用此函数的命令需要支持命令的子命令help<br />
     * 最好在子命令条数大于2条或者帮助行数>=4行数调用此函数
     * </p>
     * @param pSender 命令发送者
     * @param pLabel 未知的子命令标签,可以为null
     * @return true
     */
    public boolean unKnowChildCommand(CommandSender pSender,String pLabel){
        ArrayList<String> helpList=this.getHelp(pSender,false);
        if(helpList==null||helpList.isEmpty())
            return send(pSender,this.C("Cmd.UnknowCommand"));
        String cmdLabel=this.getClass().getSimpleName().substring(7).toLowerCase();
        if(pLabel==null) pLabel="";
        else pLabel="["+pLabel+"]";
        return send(pSender,C("Cmd.unknowChildCommand")+pLabel+","+C("Word.Input")+"/BS "+cmdLabel+" help "+C("Cmd.GetHelp"));
    }
    
    public boolean noPermit(CommandSender sender){
        return this.send(sender,this.C("Cmd.NoPermission"));
    }
    
    public boolean consoleNotAllow(CommandSender pSender){
        return this.send(pSender,this.C("Cmd.ConsoleNotAllow"));
    }
    
    /**
     * 获取该命令的标签
     * <p>
     * 默认使用类名第7位开始的小写字符串<br />
     * 如果类名不足七位,将截取全部的小写字符串
     * </p>
     */
    public String getCommandLabel(){
        String className=this.getClass().getSimpleName().toLowerCase();
        if(className.length()>7) return className.substring(7);
        else return className;
    }

    /**
     * 默认为空,请确保不为null
     * @param pArgs 玩家Tab的文字参数
     */
    public ArrayList<String> getSubCommand(CommandSender pSender,String[] pArgs){
        return new ArrayList<>();
    }

    /**
     * 在按下Tab时,完成子命令提示
     * <p>
     * 此函数默认只处理子命令参数为1位的情况,如需处理多位,请重写方法
     * </p>
     * @param pSender Tab请求用户
     * @param pArgs 已有的参数
     */
    public ArrayList<String> onTabComplete(CommandSender pSender,String[] pArgs){
        if(pArgs==null) return new ArrayList<>();

        ArrayList<String> subLabels=this.getSubCommand(pSender, pArgs);
        String lastParam=pArgs[pArgs.length-1];
        if(StringUtils.isEmpty(lastParam)) return subLabels;
        ArrayList<String> findTabs=new ArrayList<>();
        Collection<String> findLabels=Function.getSamePrefixIgnoreCase(subLabels,lastParam,true);
        if(findLabels.size()==0){
            String findLabel=Function.getIgnoreCase(subLabels,lastParam);
            if(findLabel!=null){
                if(this.getMaxArgumentLength()>pArgs.length) findTabs.add(findLabel+" ");
                else findTabs.add(findLabel);
            }
        }else if(findLabels.size()==1){
            String findLabel=findLabels.toArray()[0].toString();
            if(this.getMaxArgumentLength()>pArgs.length) findTabs.add(findLabel+" ");
            else findTabs.add(findLabel);
        }else findTabs.addAll(findLabels);
        return findTabs;
    }

    /**
     * 获取除去子命令自身的参数最大长度
     * @return >=0
     */
    public int getMaxArgumentLength(){
        return 0;
    }

    /**
     * 执行该命令
     * @param pSender 命令的执行者
     * @param pArgs 参数
     * @return 执行成功与否(默认为true)
     */
    public abstract boolean execute(CommandSender pSender,String[] pArgs);

    /**
     * 获取该命令的帮助的文本
     * @param pAll true帮扩help帮助命令,false则排除
     * @return 帮助文本的合集,如果没有帮助指令,集合为Empty
     */
    public abstract ArrayList<String> getHelp(CommandSender pSender,boolean pAll);

}
