package org.jeecg.word;

import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.jeecg.common.util.oConvertUtils;

import java.io.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ReadWordTest {
    /**
     * Word中的大纲级别，可以通过getPPr().getOutlineLvl()直接提取，但需要注意，Word中段落级别，通过如下三种方式定义：
     * 1、直接对段落进行定义；
     * 2、对段落的样式进行定义；
     * 3、对段落样式的基础样式进行定义。
     * 因此，在通过“getPPr().getOutlineLvl()”提取时，需要依次在如上三处读取。
     *
     * @param doc
     * @param para
     * @return
     */
    private static String getTitleLvl(XWPFDocument doc, XWPFParagraph para) {
        String titleLvl = "";
        try {
            //判断该段落是否设置了大纲级别
            if (para.getCTP().getPPr().getOutlineLvl() != null) {
                return String.valueOf(para.getCTP().getPPr().getOutlineLvl().getVal());
            }
        } catch (Exception e) {
        }
        try {
            //判断该段落的样式是否设置了大纲级别
            if (doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl() != null) {
                return String.valueOf(doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl().getVal());
            }
        } catch (Exception e) {
        }
        try {
            //判断该段落的样式的基础样式是否设置了大纲级别
            if (doc.getStyles().getStyle(doc.getStyles().getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal())
                    .getCTStyle().getPPr().getOutlineLvl() != null) {
                String styleName = doc.getStyles().getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal();
                return String.valueOf(doc.getStyles().getStyle(styleName).getCTStyle().getPPr().getOutlineLvl().getVal());
            }
        } catch (Exception e) {

        }
        try {
            if (para.getStyleID() != null) {
                return para.getStyleID();
            }
        } catch (Exception e) {

        }

        return titleLvl;
    }


    public static void main(String[] args) throws Exception {
        File file = new File("C:\\Users\\admin\\Desktop\\开放平台接口文档.docx");
        FileInputStream fis = new FileInputStream(file);
        XWPFDocument xdoc = new XWPFDocument(fis);

        //表格列表的index
        int tableIndex = 3;
        //段落列表的index
        int paragraphIndex = 185;
//        List<XWPFTable> tables = xdoc.getTables();
//        for (int i = 0; i < tables.size(); i++) {
//            System.out.println(i);
//            System.out.println(tables.get(i).getText());
//            System.out.println("-------------------------");
//        }
        List<IBodyElement> bodyElements = xdoc.getBodyElements();
        String curKey = "";
        List<Jiekou> jkList = new ArrayList<>();
        for (int i = 188; i < bodyElements.size(); i++) {
            IBodyElement bodyElement = bodyElements.get(i);
            if(bodyElement.getElementType() == BodyElementType.PARAGRAPH) {
                XWPFParagraph paragraph = (XWPFParagraph) bodyElement;

                String titleLvl = getTitleLvl(xdoc, paragraph);
                String text = paragraph.getText();
                if (StringUtils.isNotEmpty(titleLvl)) {
                    int level = Integer.valueOf(titleLvl);
                    if (level == 1) {
                        jkList.add(new Jiekou(text));
                    }
                    if (level == 3) {
                        if (StringUtils.contains(text, "接口URL")) {
                            curKey = "url";
                        }
                        if (StringUtils.contains(text, "请求方式")) {
                            curKey = "method";
                        }
                        if (StringUtils.contains(text, "Content-Type")) {
                            curKey = "contentType";
                        }
                        if (StringUtils.containsAny(text, "请求参数","请求Body参数")) {
                            curKey = "1";
                        }
                        if (StringUtils.contains(text, "请求Header参数")) {
                            curKey = "1";
                            jkList.get(jkList.size() - 1).setIsHeader("1");
                        }
                        if (StringUtils.containsAny(text, "返回参数","响应参数","响应Header参数")) {
                            curKey = "2";
                        }

                        if (StringUtils.containsAny(text, "成功响应示例","失败响应示例")) {
                            curKey = "2";
                        }
                        if (StringUtils.containsAny(text, "响应成功示例","响应失败示例")) {
                            curKey = "2";
                        }

                    }
                }else{
                    if(!curKey.isEmpty() && !StringUtils.equalsAny(curKey,"1","2")){
                        Jiekou jiekou = jkList.get(jkList.size() - 1);
                        ReflectUtil.setFieldValue(jiekou,curKey,text);
                    }
                }

//                if(paragraph.getText().trim().contains("https://open.gateway.newtimeai.com/gateway/genToken/obtainToken")){
//                    System.out.println(i);
//                }
            }
            if(bodyElement.getElementType() == BodyElementType.TABLE) {
                XWPFTable table = (XWPFTable)bodyElement;
                Jiekou jiekou = jkList.get(jkList.size() - 1);
                if(curKey.equals("1")){
                    List<Jkzd> jkzd = getJkzd(table);
                    if(!jkzd.isEmpty()){
                        curKey = "";
                        jiekou.setRequest(jkzd);
                    }
                }
                if(curKey.equals("2")){
                    List<Jkzd> jkzd = getJkzd(table);
                    if(!jkzd.isEmpty()){
                        curKey = "";
                        jiekou.setResponse(jkzd);
                    }
                }
//                curKey = "";
            }
        }
//        for (Jiekou jiekou : jkList) {
//            if(jiekou.getRequest() == null || jiekou.getRequest().isEmpty()){
//                System.out.println(jiekou.getName());
//                System.out.println("---------request--------");
//            }
//            if(jiekou.getResponse() == null || jiekou.getResponse().isEmpty()){
//                System.out.println(jiekou.getName());
//                System.out.println("---------response--------");
//            }
//        }

//        System.out.println(jkList);

//        Jiekou jiekou = findJiekou(jkList, "31.专电普开票");
//        gencode(jiekou,"tax_xx_fp","tax_xx_fpmx");

//        3.商品编码查询（开具）
        System.out.println(jkList);
        Jiekou jiekou = findJiekou(jkList, "44.获取服务器基本信息");
        gencode(jiekou,"tax_xx_fwqxx");
    }

    public static List<Jkzd> getJkzd(XWPFTable table){
//        System.out.println(table.getText());
        List<XWPFTableRow> rows = Lists.newArrayList(table.getRows());
        List<Jkzd> list = new ArrayList<>();

        for (int i = rows.size() - 1; i >= 0; i--) {
            XWPFTableRow row = rows.get(i);
            String text = row.getCell(0).getText();
            if(text.trim().isEmpty() || text.trim().startsWith("{")){
                rows.remove(i);
                continue;
            }
            if(StringUtils.equalsAny(text.trim(),"名称","参数","参数名")){
                rows.remove(i);
            }
        }

        for (XWPFTableRow row : rows) {
            String text = row.getCell(0).getText();


//        for (XWPFTableRow row : rows) {
            Jkzd jkzd = new Jkzd();
            jkzd.setKey(text);

            jkzd.setType(row.getCell(1).getText());
            jkzd.setMust(StringUtils.equals(row.getCell(2).getText(),"是"));
            jkzd.setRemark(row.getCell(3).getText());
            list.add(jkzd);
        }
        return list;
    }

//    public static Jiekou getJiekou(XWPFDocument xdoc,IBody body,int index){
//        Jiekou jiekou = null;
//
//        int titleIndex = 0;
//
//        for (int i = 0; i < 10; i++) {
//            XWPFParagraph paragraph = body.getParagraphArray(index - i);
//            String titleLvl = getTitleLvl(xdoc, paragraph);
//            if (StringUtils.isNotEmpty(titleLvl)) {
//                int level = Integer.valueOf(titleLvl);
//                if(level == 1){
//                    jiekou = new Jiekou(paragraph.getText());
//                    titleIndex = i;
//                    break;
//                }
//            }
//        }
//
//        set(body,titleIndex,index,jiekou,"url","接口地址");
//        set(body,titleIndex,index,jiekou,"method","请求方式");
//        set(body,titleIndex,index,jiekou,"url","Content-Type");
//    }
//
//    public static void set(IBody body,int titleIndex,int index,Jiekou jiekou,String field,String key){
//        for (int i = 0; i < titleIndex; i++) {
//            XWPFParagraph paragraph = body.getParagraphArray(index - i);
//            if(paragraph.getText().trim().contains(key)){
//                ReflectUtil.setFieldValue(jiekou,field,body.getParagraphArray(index - i + 1).getText());
//                break;
//            }
//        }
//    }

    public static Jiekou findJiekou(List<Jiekou> jkList,String name) throws Exception  {
        return jkList.stream().filter(jk->StringUtils.contains(jk.getName(),name)).findFirst().get();
    }

    public static void setColumnOptions(Jiekou jiekou) throws Exception  {
        String pattern = "[\u4E00-\u9FA5]+";
        Pattern r = Pattern.compile(pattern);
        for (Jkzd jkzd : jiekou.getRequest()) {
            jkzd.setColumn(oConvertUtils.camelToUnderline(jkzd.getKey()));

            Matcher m = r.matcher(jkzd.getRemark());
            jkzd.setRemark(m.find()?m.group(0).trim():jkzd.getRemark().trim());
        }

        for (Jkzd jkzd : jiekou.getResponse()) {
            jkzd.setColumn(oConvertUtils.camelToUnderline(jkzd.getKey()));

            Matcher m = r.matcher(jkzd.getRemark());

            jkzd.setRemark(m.find()?m.group(0).trim():jkzd.getRemark().trim());
        }

    }

    public static List<Jkzd> comper(String flag,List<Jkzd> request,List<Jkzd> response) throws Exception  {
        List<Jkzd> list = new ArrayList<>();
        for (Jkzd jkzd : request) {
            boolean find = false;
            for (Jkzd res : response) {
                if(jkzd.getKey().equals(res.getKey())){
                    find = true;
                    break;
                }
            }
            if(!find){
                list.add(jkzd);
                System.out.println(flag+":"+jkzd.getKey());
            }
        }
        return list;
    }

//    public static String getColumnType(String javaType) throws Exception  {
//        if(StringUtils.equalsIgnoreCase(javaType,"String")){
//            return "varchar(255)";
//        }
//        BigDecimal
//        if(StringUtils.equalsIgnoreCase(javaType,"Array")){
//            return "varchar(255)";
//        }
//    }

    public static void gencode(Jiekou jiekou,String... tableNames) throws Exception  {
        setColumnOptions(jiekou);

        List<Jkzd> request = jiekou.getRequest();
        List<Jkzd> response = jiekou.getResponse();
//        comper("request",request,response);
        List<Jkzd> reslist = comper("response", response, request);
        for (Jkzd jkzd : reslist) {
            if(!StringUtils.equalsAny(jkzd.getKey(),"code","msg","data")){
                request.add(jkzd);
            }
        }

        List<List<Jkzd>> jkList = new ArrayList<>();
        jkList.add(new ArrayList<>());
        int index = 0;
        for (Jkzd jkzd : request) {
            if(StringUtils.equalsIgnoreCase(jkzd.getType(),"Array")){
                index++;
                List<Jkzd> l = new ArrayList<>();
                Jkzd zd = new Jkzd();
                String tableName;
                try{
                    tableName = tableNames[index];
                }catch (Exception e){
                    throw new RuntimeException("出现多个表");
                }
                String key = tableName.substring(tableName.lastIndexOf("_")+1);
                zd.setKey(key+"Id");
                zd.setColumn(key+"_id");
                l.add(zd);
                jkList.add(l);
                continue;
            }
            jkList.get(index).add(jkzd);
        }
//        request.addAll(reslist);

        String outDir = "C:\\Users\\admin\\Desktop\\代码生成";

        //1.创建freemarker的配置对象
        Configuration configuration = new Configuration(Configuration.getVersion());
        //2.设置模板文件所在目录
        configuration.setDirectoryForTemplateLoading(new File("D:\\tax-sharing\\jeecg-module-system\\jeecg-system-start\\src\\test\\resources\\"));
        //3.设置字符集
        configuration.setDefaultEncoding("utf-8");

        for (int i = 0; i < jkList.size(); i++) {
            List<Jkzd> jkzds = jkList.get(i);
            for (Jkzd jkzd : jkzds) {
                jkzd.setKey(StringUtils.trim(jkzd.getKey()));
                jkzd.setColumn(StringUtils.trim(jkzd.getColumn()));
                jkzd.setRemark(StringUtils.trim(jkzd.getRemark()));
            }
            String tableName = tableNames[i];
            jiekou.setTableName(tableName);
            genFile(jiekou,jkzds,outDir,configuration,"sql","sql");
        }

//        genFile(jiekou,outDir,configuration,"api","java");


    }

    public static void genFile(Jiekou jiekou,List<Jkzd> zdList,String outDir,Configuration configuration,String templateName,String subfix) throws Exception {

        //4.加载模板
        Template template = configuration.getTemplate(templateName+".ftl");

        //6.创建Writer对象,用于输出静态文件
        Writer out = new FileWriter(new File(outDir+"\\"+jiekou.getTableName()+"."+subfix));
        //7.输出文件
        Map<String,Object> map = new HashMap<>();
        map.put("jiekou",jiekou);
        map.put("zdList",zdList);
        template.process(map,out);
        //8.关闭流
        out.close();
    }
}