package com.ruoyi.common.utils;
import cn.hutool.core.convert.NumberChineseFormatter;
import org.apache.pdfbox.text.PDFTextStripper;
import org.springframework.web.multipart.MultipartFile;
import technology.tabula.*;
import technology.tabula.extractors.SpreadsheetExtractionAlgorithm;
import org.apache.pdfbox.pdmodel.PDDocument;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.stream.Collectors;

public class PdfParseUtil {
    public static Map<String, Object> extractPdfContent(MultipartFile multipartFile) throws IOException {
        // 1. 转换MultipartFile为临时File
        File pdfFile = convertMultipartToFile(multipartFile);

        // 2. 执行提取
        try (PDDocument document = PDDocument.load(pdfFile)) {
            Map<String, Object> result = new LinkedHashMap<>();

            // 提取第一页表单数据
            Map<String, String> formData =  extractFormData(document);
            Map<String, String> tableData = new LinkedHashMap<>();
            // 提取第二页表格数据（如果存在）
            if (document.getNumberOfPages() >= 2) {
                tableData =  extractTableData(document, 2);
            }

            // 合并
            result.putAll(formData);
            result.putAll(tableData);
            return result;
        } finally {
            // 3. 删除临时文件
            Files.deleteIfExists(pdfFile.toPath());
        }
    }
    private static File convertMultipartToFile(MultipartFile multipartFile) throws IOException {
        File tempFile = Files.createTempFile("pdf-", ".pdf").toFile();
        try (InputStream inputStream = multipartFile.getInputStream()) {
            Files.copy(inputStream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
        }
        return tempFile;
    }

    private static Map<String, String> extractFormData(PDDocument document) throws IOException {
        PDFTextStripper stripper = new PDFTextStripper();
        stripper.setStartPage(1);
        stripper.setEndPage(1);
        String text = stripper.getText(document);
        return parseFormText(text);
    }


    public static Map<String, String> extractTableData(PDDocument document, int pageNumber) throws IOException {
        Map<String, String> tableData = new LinkedHashMap<>();
        ObjectExtractor extractor = new ObjectExtractor(document);
        SpreadsheetExtractionAlgorithm algorithm = new SpreadsheetExtractionAlgorithm();
//        Page page = extractor.extract(pageNumber);
//        return algorithm.extract(page);
        List<Table> tables = new ArrayList<>();
        PageIterator pages = extractor.extract();

        while (pages.hasNext()) {
            Page page = pages.next();
            tables.addAll(algorithm.extract(page));
        }
        List<List<List<String>>> parseData =  tables.stream()
                .map(PdfParseUtil::convertTableToData)
                .collect(Collectors.toList());
        String animalCertNo = "";
        String animalEartags = "";
        if (parseData.size()>0){
            animalCertNo = Optional.ofNullable(parseData)
                    .filter(list -> list.size() > 0)
                    .map(list -> list.get(0))
                    .filter(list -> list.size() > 0)
                    .map(list -> list.get(0))
                    .filter(list -> list.size() > 1)
                    .map(list -> list.get(1)).orElse("");
        }
         for (int i = 0; i < parseData.size(); i++) {
             int finalI = i;
             animalEartags += Optional.ofNullable(parseData)
                     .filter(list -> list.size() > finalI)
                     .map(list -> list.get(finalI))
                     .filter(list -> list.size() > 2)
                     .map(list -> list.get(2))
                     .filter(list -> list.size() > 0)
                     .map(list -> list.get(0)).orElse("");
         }

        animalEartags = animalEartags.replaceAll("[\\n\\r]", "");
        if (!parseData.isEmpty() && parseData.get(0).size() > 1) {
            tableData.put("animalCertNo", animalCertNo);
            tableData.put("animalEartags", animalEartags);
        }
        return tableData;
    }
    private static Map<String, String> parseFormText(String text) {
        Map<String, String> formData = new LinkedHashMap<>();
        text = text.replaceAll("\r\n|\n", "\n"); //windows识别是\r\n分割的，linux识别是\n分割 统一替换兼容使用 \n
        String[] lines = text.split("\n");
        if (lines.length < 11) {
            return formData;//少于这个长度说明PDF解析内容不够
        }
        formData.put("animalCertNo",lines[0].replaceAll("No.", ""));//备用动物检疫证号
        formData.put("cargoOwner",lines[1]);//货主
        formData.put("companyNo",lines[2]);//主体识别号
        formData.put("cargoOwnerPhone",lines[3]);//货主联系方式
        formData.put("animalCategory",lines[4]);//动物种类
        formData.put("amount", String.valueOf(lines[5].isEmpty() ?0: NumberChineseFormatter.chineseToNumber(lines[5].substring(0,lines[5].length() - 1))));//数量
        formData.put("units", lines[5].isEmpty() ?"":lines[5].substring(lines[5].length() - 1));//单位
        //第二步
        String[] newLines = Arrays.copyOfRange(lines, 6, lines.length);
        if (newLines.length == 0) {
            return formData;
        }
        int index = FindUtil.findFirstPhoneNumberIndex(newLines);//根据第二个手机号码的位置为参照点
        if (index == -1) {
            return formData;
        }
        formData.put("carrierPhone",index>0 ? newLines[index] : "");//承运人联系方式
        formData.put("carrier",index-2>0 ? newLines[index-2] : "");//承运人
        formData.put("useto",index-1>0 ? newLines[index-1] : "");//用途
        StringBuilder animalEartags = new StringBuilder();//备用耳标号
        for(int i = index+1;i<newLines.length;i++) {
            //从第二个手机号码的位置往后读取
            if(newLines[i] != null && newLines[i].matches("^[0-9]+(,[0-9]+)*$")){
                animalEartags.append(newLines[i]);
            }

        }
        formData.put("animalEartags",animalEartags.toString());//备用耳标号,防止没有第二页的情况读不到耳标号，比如头数很少的情况

        //formData.put("remark",newLines.length>index+2?newLines[index+2] : "");//备注  备注经常没有，不容易获取
        //第三步,启运地址和到达地址
        String[] newAddrLines = Arrays.copyOfRange(newLines, 0, index-2);
        if (newAddrLines.length == 0) {
            return formData;
        }
        List<String> addrArr = FindUtil.extractAddresses(newAddrLines);
        formData.put("fromPlace",addrArr.size()==2 ? addrArr.get(0) : "");//启运地点
        formData.put("toPlace",addrArr.size()==2 ? addrArr.get(1) : "");//到达地点
        return formData;
    }
    public static List<List<String>> convertTableToData(Table table) {
        return table.getRows()
                .stream()
                .map(row -> row.stream()
                        .map(RectangularTextContainer::getText)
                        .collect(Collectors.toList()))
                .collect(Collectors.toList());
    }
}
