package org.jeecg.modules.stm.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;




/**
 * @Author: yzh
 * @Date 2023/3/7 22:13
 * @Description:
 */
@Slf4j
public class ParseDocUtil {
//    public static void main(String[] args) {
//        ParseDocUtil paserDoc = new ParseDocUtil();
//        String strPath = "D:/opt/upFiles/temp/电子签名法.pdf";
//        try {
//
//            String strText = paserDoc.pdfParserText(strPath);
//            //String article = "这是一篇包含1、2、3、一、二、三、第一、第二、第三等内容的文章。\n第一段。\n第二段。\n第三段。";
//            int k = paserDoc.getFileContentTp(strText);
//            if(k==1) {
//                paserDoc.pdfParserToList(strPath);
//            } else if(k==2) {
//                paserDoc.handleText(strText);
//            } else {
//                paserDoc.splitText(strText);
//            }
//
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//    }

    /**
     * 有章 条的 那种 比如法律法规
     * @param filePath
     * @return
     */
    public static List<String[]> docxParser(String filePath){
        try {

            File file = new File(filePath);
            if(!file.exists()||file.length()==0) {
                System.out.println(filePath);
                return null;
            }
            InputStream inputStream = new FileInputStream(file);
            XWPFDocument document = new XWPFDocument(inputStream);
            Pattern pattern = Pattern.compile("^第(\\d{1,5}|[一二三十四五六七八九]{1,4})(条|章)\\s*.{1,}",Pattern.MULTILINE);
            List<String[]> tList = new ArrayList<String[]>();
            String s0="";

            for (XWPFParagraph paragraph : document.getParagraphs()) {
                String s1="";
                String[] tmpAry = new String[3];
                String strTxt = paragraph.getText();
                Matcher matcher = pattern.matcher(strTxt);
                int findTp = -1;
                while (matcher.find()) {
                    String strRult = matcher.group();
                    if(strRult.substring(0,5).indexOf("章")>-1) {
                        s0 = strRult;
                        findTp =0;
                        s1="";
                        break;
                    } else {
                        s1 = strRult;
                        findTp =1;
                    }
                }
                if(findTp==-1) {
                    if(tList.size()>0) {
                        String[] lastData =  tList.get(tList.size()-1);
                        lastData[2]= lastData[2]!=null?lastData[2]+strTxt:strTxt;
                    } else {
                       //System.out.println(strTxt);
                    }
                } else if(findTp==1) {
                    tmpAry[0]=s0;
                    tmpAry[1]=s1;
                    tList.add(tmpAry);
                }

            }
            document.close();
            return tList;
        } catch (Exception e) {
            //e.printStackTrace();
            System.out.println(filePath);
            log.info("解析文件失败："+ filePath);
        }
        return null;

    }

    public static List<String[]> pdfParserToList(String filePath){
        try {
            String strTxt=  pdfParserText(filePath);
            List<Map<String,String>> retList = new ArrayList<Map<String,String>>();
            String[] arr = strTxt.split("\r?\n");
            List<String> list = new ArrayList<>();
            StringBuffer itemSb = new StringBuffer();
            String  pattern = "^第(\\d{1,5}|[一二三十四五六七八九]{1,4})(条|章)\\s*.{1,}";
            for (String s : arr) {
                if (s.matches(pattern)) {
                    if (itemSb.length()>0) {
                        list.add(itemSb.toString());
                    }
                    itemSb = new StringBuffer();
                }
                itemSb.append(s);
            }
            List<String[]> tList = new ArrayList<String[]>();
            String str1="";
            for(int i=0;i<list.size();i++) {
                String[] tmpAry = new String[3];
                String strTmp = list.get(i);
                int p1 = strTmp.indexOf("第");
                int p2 = strTmp.indexOf("章");
                if(p2-p1<5){
                    str1 = strTmp;
                    continue;
                }
                tmpAry[0] = "<b>"+str1+"</b>";
                int k = strTmp.indexOf("条");
                tmpAry[1] = "<b>"+strTmp.substring(0,k+1)+"</b>" + strTmp.substring(k+1);
                tList.add(tmpAry);
                //System.out.println(tmpAry[0]+ "--" +tmpAry[1]);
            }
            return tList;
        } catch (Exception e) {
            //e.printStackTrace();
            log.info("解析文件失败："+ filePath);
        }
        return null;

    }

    public static List<String[]> docParser(String filePath){
        try {
            //filePath="D:/doc/商业银行科技风险案例63条.doc";
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file.getAbsolutePath());
            WordExtractor extractor = new WordExtractor(fis);
            String text = extractor.getText();
            String[] paras = extractor.getParagraphText();
            Pattern pattern = Pattern.compile("^第(\\d{1,5}|[一二三十四五六七八九]{1,4})(条|章)\\s*.{1,}",Pattern.MULTILINE);
            List<String[]> tList = new ArrayList<String[]>();
            String s0="";
            fis.close();

            for (String  strTxt: paras) {
                String s1="";
                String[] tmpAry = new String[3];
                Matcher matcher = pattern.matcher(strTxt);
                int findTp = -1;
                while (matcher.find()) {
                    String strRult = matcher.group();
                    if(strRult.substring(0,5).indexOf("章")>-1) {
                        s0 = strRult;
                        findTp =0;
                        s1="";
                        break;
                    } else {
                        s1 = strRult;
                        findTp =1;
                    }
                }
                if(findTp==-1) {
                    if(tList.size()>0) {
                        String[] lastData =  tList.get(tList.size()-1);
                        lastData[2]= lastData[2]!=null?lastData[2]+strTxt:strTxt;
                    } else {
                        //System.out.println(strTxt);
                    }
                } else if(findTp==1) {
                    tmpAry[0]=s0;
                    tmpAry[1]=s1;
                    tList.add(tmpAry);
                }
            }

            return tList;
        } catch (Exception e) {
            //e.printStackTrace();
            log.info("解析文件失败："+ filePath);
        }
        return null;
    }

    public static List<String[]> parseForItem(List<String[]> list) {
        List<String[]> newList = new ArrayList<String[]>();
        for(int i=0;i<list.size();i++) {
            String[] data = list.get(i);

            String[] newAry = new String[2];
            if(data[1]==null || data[1].trim().equals("")) continue;
            int p = data[1].indexOf("条");
            //System.out.println(data[1]);
            String strTmp = data[0].substring(0,data[0].indexOf("章")+1);
            String strTmp2 = "";
            if(p==-1) {
                strTmp +=data[1];
            } else {
                strTmp += " " + data[1].substring(0,p+1);
                strTmp2 =  data[1].substring(p+2);
            }

            newAry[0] = strTmp;
            if(data[2]!=null && !data[2].equals("")) {
                strTmp2 += "\n"+ data[2];
            }
            newAry[1] = strTmp2;
            newList.add(newAry);
        }

        return newList;

    }

    /**
     * 把文章分成单句子
     * @param text
     * @return
     */
    public static List<Map<String,String>> splitText(String text) {
        List<Map<String,String>> result = new ArrayList<Map<String,String>>();
        if (text == null || text.isEmpty()) {
            return result;
        }
        int length = text.length();
        int startIndex = 0;
        int endIndex;
        while (startIndex < length) {
            endIndex = startIndex + 500;
            if (endIndex >= length) {
                endIndex = length;
            } else {
                endIndex = findSentenceEnd(text, endIndex);
            }
            endIndex = endIndex+1>length?length:endIndex+1;
            String segment = text.substring(startIndex, endIndex);
            Map<String,String> tmpMap = new HashMap<String,String>();
            tmpMap.put("content",segment);
            result.add(tmpMap);
            startIndex = endIndex + 1;
        }
        return result;
    }

    /**
     * 根据标点符号取一个完整句子
     * @param text
     * @param startIndex
     * @return
     */
    private static int findSentenceEnd(String text, int startIndex) {
        int endIndex = startIndex;
        for (int i = startIndex; i < text.length(); i++) {
            char c = text.charAt(i);
            if (c == '。' || c == '！' || c == '？') {
                endIndex = i;
                break;
            }
        }
        return endIndex;
    }

    /**
     * doc文件，存储到 list
     * @param filePath
     * @return List<Map> 其中 map.key 是 content
     */
    public static List<Map<String,String>> docParserList(String filePath){
        try {
            List<Map<String,String>> retList = new ArrayList<Map<String,String>>();
            for (XWPFParagraph paragraph : docParserParagraph(filePath)) {
                Map<String,String> tmpMap = new HashMap<String,String>();
                String strTxt = paragraph.getText();
                if(strTxt!=null&&strTxt.trim().length()>0){
                    tmpMap.put("content",strTxt);
                } else {
                    tmpMap.put("content","");
                }
                retList.add(tmpMap);
            }
            return retList;
        } catch (Exception e) {
            log.info("解析文件失败："+ filePath);
        }
        return null;
    }

    /**
     * 解析docx
     * @param filePath
     * @return List<Map> 其中 map.key 是 content
     */
    public static List<Map<String,String>> docxParserList(String filePath){
        try {
            List<Map<String,String>> retList = new ArrayList<Map<String,String>>();
            for (XWPFParagraph paragraph : docxParserParagraph(filePath)) {
                Map<String,String> tmpMap = new HashMap<String,String>();
                String strTxt = paragraph.getText();
                if(strTxt!=null&&strTxt.trim().length()>0){
                    tmpMap.put("content",strTxt);
                }
                retList.add(tmpMap);
            }
            return retList;
        } catch (Exception e) {
            log.info("解析文件失败："+ filePath);
        }
        return null;
    }

    /**
     * 解析PDF文件
     * @param filePath
     * @return 文本格式的字符串
     */
    public static String pdfParserText(String filePath){
        try {
            File file = new File(filePath);
            PDDocument document = PDDocument.load(file);
            PDFTextStripper stripper = new PDFTextStripper();
            String str = stripper.getText(document);
            document.close();
            return str;
        } catch (Exception e) {
            log.info("解析文件失败："+ filePath);
        }
        return null;
    }

    /**
     * 解析doc文件
     * @return 文本格式对字符串
     * @throws IOException
     */
    public static String docParserText(String filePath){
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file.getAbsolutePath());
            WordExtractor extractor = new WordExtractor(fis);
            String text = extractor.getText();
            fis.close();
            return text;
        } catch (Exception e) {
            log.info("解析文件失败："+ filePath);
        }
        return null;
    }

    /**
     * 解析docx 文件
     * @return 段落
     * @throws IOException
     */
    public static List<XWPFParagraph> docxParserParagraph(String filePath){
        try {
            File file = new File(filePath);
            InputStream inputStream = new FileInputStream(file);
            XWPFDocument document = new XWPFDocument(inputStream);
            List<XWPFParagraph> list = document.getParagraphs();
            document.close();
            return list;
        } catch (Exception e) {
            log.info("解析文件失败："+ filePath);
        }
        return null;
    }

    /**
     * 解析doc文件
     * @return 段落
     * @throws IOException
     */
    public static List<XWPFParagraph> docParserParagraph(String filePath){
        try {
            File file = new File(filePath);
            InputStream inputStream = new FileInputStream(file);
            XWPFDocument document = new XWPFDocument(inputStream);
            List<XWPFParagraph>  list =  document.getParagraphs();
            document.close();
            return list;
        } catch (Exception e) {
            log.info("解析文件失败："+ filePath);
        }
        return null;
    }

    public static List<String> parsePgfParagraph(String filePath) throws IOException {
        // 读入 PDF 文件
        List<String> paragraphs = new ArrayList<>();
        try {
            PDDocument pdf = PDDocument.load(new File(filePath));
            // 定义自然段落开始标记
            String paragraphStart = "  ";
            // 设置 PDFTextStripper 对象的段落开始标记
            PDFTextStripper stripper = new PDFTextStripper();
            stripper.setParagraphStart(paragraphStart);
            stripper.setParagraphEnd("\r\n");
            // 获取 PDF 的文本内容
            String text = stripper.getText(pdf);
            String[] paragraphArray = text.split(paragraphStart);
            for (String p : paragraphArray) {
                paragraphs.add(p);
            }

            pdf.close();
        } catch (Exception e) {
            log.info("解析文件失败："+ filePath);
        }
        return paragraphs;
    }


    public static List<String> pdfParserTextPage(String filePath){
        try {
            File file = new File(filePath);
            String result = "";
            PDDocument document = PDDocument.load(file);
            PDFTextStripper stripper = new PDFTextStripper();
            int end = document.getNumberOfPages();
            List<String> list = new ArrayList<>();
            for (int i = 0; i <= end; i++) {
                // 设置起始页
                stripper.setStartPage(i);
                // 设置结束页
                stripper.setEndPage(i);
                // 从PDF文档对象中剥离文本
                String pageStr = stripper.getText(document);
                list.add(pageStr);
            }

            document.close();
            return list;

        } catch (Exception e) {
            log.info("解析文件失败："+ filePath);
        }
        return null;
    }


    public static  List<Map<String,String>> listToListMap(String strKey,List<String> list) {
        List<Map<String,String>> newList = new ArrayList<>();
        for(String str:list){
            Map<String,String> tmpMap = new HashMap<String,String>();
            tmpMap.put(strKey,str);
            newList.add(tmpMap);
        }
        return newList;
    }

    public static List<String>  handleText(String strText) {

        Pattern pattern = Pattern.compile("^(\\d{1,5}|[一二三十四五六七八九]{1,4})、",Pattern.MULTILINE);
        Matcher matcher = pattern.matcher(strText);
        List<String> list = new ArrayList<>();
        int start = 0;
        while (matcher.find()) {
            String match = matcher.group();
            int end = matcher.start();
            String paragraph = strText.substring(start, end).trim();
            StringBuilder sb = new StringBuilder();
            // 将匹配的字符串加粗
            sb.append("<b>").append(match).append("</b>").append(paragraph).append("\n");
            start = matcher.end();
            list.add(sb.toString());
            //System.out.println(sb.toString());

        }
        return list;
    }

    public static int getFileContentTp(String text) {

        int p = text.indexOf("第一章");
        int p2 = text.indexOf("第一条");
        if(p>-1&&p2>-1) {
            return 1;
        }
        int p3 = text.indexOf("一、");
        if(p3>-1) return 2;
        return 0;

    }
}


