package com.eversec.kit.creator;

import com.eversec.common.FileKit;
import com.eversec.common.Kv;
import com.eversec.service.CfgBean;
import com.google.gson.Gson;
import com.jfinal.template.Engine;
import com.lxyer.excel.poi.ExcelKit;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Created by liangxianyou@eversec.cn at 2018/5/3 18:10.
 */
public abstract class ICreator {
    private static CfgBean cfgBean;

    private static String xlsPath;
    public static String tplPath;
    public static String dirPath;
    public static String pageDirPath;

    public static String pkg;
    public static String pageModel;
    public static String author;
    private static List<String> sheetNames;
    /*static {
        xlsPath = PropKit.getProperty("xlsPath", "res/xls/table.xls");
        pkg = PropKit.getProperty("pkg", "");
        tplPath = PropKit.getProperty("tplPath", "");
        dirPath = PropKit.getProperty("dirPath", "");
        pageDirPath = PropKit.getProperty("page.dirPath", dirPath);

        pageModel = PropKit.getProperty("page.model", "");
        author = PropKit.getProperty("author", "lxy-kit");
        sheetNames = sheets(PropKit.getProperty("sheetNames", ""));

        //路径兼容处理
        if (!dirPath.endsWith("/")) dirPath += "/";
        if (!pageDirPath.endsWith("/")) pageDirPath += "/";
    }*/
    public static void setCfgBean(CfgBean cfgBean) {
        ICreator.cfgBean = cfgBean;
        xlsPath = cfgBean.getXlsPath();
        pkg = cfgBean.getPkg();
        tplPath = cfgBean.getTplPath();
        dirPath = cfgBean.getDirPath();
        pageDirPath = cfgBean.getPageDirPath();  //PropKit.getProperty("page.dirPath", dirPath);

        pageModel = cfgBean.getPageModel();
        author = cfgBean.getAuthor();
        sheetNames = cfgBean.getSheetNames();

        //路径兼容处理
        if (!dirPath.endsWith("/")) dirPath += "/";
        if (!pageDirPath.endsWith("/")) pageDirPath += "/";
    }

    private static List<String> sheets(String sheetNames) {
        String[] strArr = sheetNames.split(",");
        List<String> sheets = new ArrayList<>(strArr.length+1);
        for (int i = 0; i < strArr.length; i++) {
            String sheetName = strArr[i].trim();
            if (!sheetName.isEmpty()){
                sheets.add(sheetName);
            }
        }
        return sheets;
    }

    public static String timeStr = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date());
    public static Engine engine = Engine.use();

    public static Map<String, String> cateRelation = Kv.of("varchar", "String").set("text", "String").set("int", "Integer").set("bigint", "Long").set("long", "Long").set(null, "String").set("datetime", "Date");
    public static String[] fields = {"field","cate", "must","remark1", "remark2", "tag", "selects", "column","filter", "ck", "edit"};
    public static Gson gson = new Gson();

    public static List<String> sheetNames() {
        return sheetNames;
    }

    //===================  公用方法  ===================
    public abstract File getFile(String clazz);
    public abstract String createStr(String clazz, List<Map> fieldList, Map para);
    public static List<Map> readExcel(String fileName) throws IOException {
        List<Map> list = ExcelKit.readExcel(new File(xlsPath + fileName + ".xlsx"), fields);
        list.forEach(x->{
            x.put("field", toLowerCaseFirst(x.get("field")+""));
        });
        return list;
    }
    public static List<Map> readExcelSheet(String sheetName) throws IOException {
        List<Map> list = ExcelKit.readExcel(new File(xlsPath), fields, sheetName);
        list.forEach(x->{
            x.put("field", toLowerCaseFirst(x.get("field")+"").trim());
        });
        return list;
    }
    private static Map<String, Map> cacheTpl = new HashMap<>();
    public static Map readExcelHead(File file) throws IOException {
        Long modifiedTime = Files.getLastModifiedTime(file.toPath()).to(TimeUnit.MILLISECONDS);
        String ck = file.getName() + ":" + modifiedTime;//缓存键（name:modifiedTime）
        //缓存tpl模板
        if (cacheTpl.get(ck) == null) {
            cacheTpl.put(ck, ExcelKit.readExcelHead(file, fields));
        }
        return cacheTpl.get(ck);
    }
    public static Kv createTplData(String clazz){
        Kv kv = Kv.of("bean", clazz);
        kv.set("beanFL", toLowerCaseFirst(clazz));
        kv.set("beanL", clazz.toLowerCase());
        kv.set("author", ICreator.author);
        kv.set("pkg", ICreator.pkg);
        kv.set("ctime", timeStr);
        kv.set("pageModel", pageModel);
        return kv;
    }
    public void createFile(String entityBody, String clazz) throws IOException {
        FileKit.strToFile(entityBody, getFile(clazz), true);
    }

    public static String toLowerCaseFirst(String str){
        if (str == null || str.length() < 1) return "";
        return str.substring(0, 1).toLowerCase() + str.substring(1);
    }
    public static String toUpperCaseFirst(String str){
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }
    public static String getFiledType(String cate){
        for (String k : cateRelation.keySet()) {
            if (cate.startsWith(String.valueOf(k))) {
                return cateRelation.get(k);
            }
        }

        System.out.println("cate:"+cate);
        return null;
    }

    public static boolean isMust(Map map) {
        return false;//(map.get("must")+"") .equals("是") || (map.get("must")+"").equals("必须");
    }
    public static boolean isEmpty(Object obj){
        return obj == null || (obj+"").isEmpty();
    }

    public String timeStr(){
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }

    public static String getTableName(String clazz) {
        //分解
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < clazz.length(); i++) {
            if (Character.isUpperCase(clazz.charAt(i)) && i > 0)
                buf.append("_");
            buf.append(clazz.charAt(i));
        }

        return buf.toString().toLowerCase();
    }

    //ti_abc =>  TiAbc
    public static String getClazzName(String tName) {
        tName = tName.toLowerCase();
        String[] arr = tName.split("_");
        String str = "";
        for (String s : arr) {
            str += toUpperCaseFirst(s);
        }
        return str;
    }
    protected static String getClazzName(Map note) {
        String field = note.get("field")+"";
        if (field.isEmpty()) return "";


        int inx = field.indexOf("(");

        if(inx < 0){
            return field;
        }

        field = field.substring(0, inx).toLowerCase();
        String[] arr = field.split("_");
        String str = "";
        for (String s : arr) {
            str += toUpperCaseFirst(s);
        }
        return str;
    }
    //{field:"ti_abc(测试表)"} => 测试表
    protected static String getRemark(Map note) {
        String field = note.get("field")+"";
        if (field.isEmpty()) return "";

        int s = field.indexOf("(");
        int e = field.indexOf(")");
        if (s > 0){
            return field.substring(s+1, e > 0 ? e : field.length());
        }
        return "";
    }
    protected static String getVerify(Map map) {
        if (map.get("cate") == null){
            return "";
        }
        String str = (String) map.getOrDefault("cate","");
        return str.replace("|",",");
    }

    protected static String[] getCondition(Map map) {
        if (map.get("must") == null || String.valueOf(map.get("must")).isEmpty()){
            return null;
        }
        String str = (String) map.getOrDefault("must","");
        return str.split("[|]");
    }

    //createFile use this filePath
    public String filePath(String pkg){
        return dirPath + "java/" + pkg.replace('.', '/') + "/";
    }

}
