package com.nantian.cloud.jljc.tools;

import com.nantian.sc.cloud.common.minio.service.MinioTemplate;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class InspectUtil {
    private static final Integer FIR_LINE_TOTAL = 18;
    private static final Integer SEN_LINE_TOTAL = 20;
    private static final Integer THR_LINE_TOTAL = 21;
    private static final String BLANK_BELOW = "    （以下空白）";

    @Autowired
    private MinioTemplate minio;

    private static InspectUtil minioTemplate;

    @PostConstruct
    public void init() {
        minioTemplate = this;
        minioTemplate.minio = this.minio;
    }

    public static XWPFDocument inspectWord(InputStream homePage, InputStream continuationSheet, InputStream inputStream, Map<String, Object> map, HttpServletResponse response) throws Exception {

        int total = 0;
        int representativel = 0;
        int dutyl = 0;
        int telphonel = 0;
        int sitel = 0;
        int timel = 0;
        int count = 0; //第三页循环次数
        XWPFDocument home = new XWPFDocument(OPCPackage.open(homePage));
        List<String> question = (List<String>) map.get("question");
        map.remove("question");
        XWPFDocument document = new XWPFDocument();
        response.reset();
        response.setHeader("Content-Disposition", "attachment; filename="  + URLEncoder.encode(map.get("name") +   "现场检查笔录.docx", "UTF-8"));
        ServletOutputStream outputStream = response.getOutputStream();
        List<String> materials = (List<String>) map.get("materials");

        if (question.size() > 0){
            List<XWPFTable> tables = home.getTables();
            a:for (XWPFTable table : tables) {
                List<XWPFTableRow> rows = table.getRows();
                for (XWPFTableRow row : rows) {
                    List<XWPFTableCell> cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        if (cell.getText().equals("${name}")){
                            if (String.valueOf(map.get("name")).length() > 0){
                                cell.removeParagraph(0);
                                List<String> nameSize = CutStringUtil.getCharLength(String.valueOf(map.get("name")), 400);
                                total += nameSize.size();
                                for (int i = 0; i < nameSize.size(); i++) {
                                    XWPFRun run = cell.addParagraph().createRun();
                                    run.setText(nameSize.get(i));
                                    cell.getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);
                                    cell.getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
                                }
                                map.remove("name");
                            } else {
                                log.warn("${name}数据为空，请检查数据！");
                            }
                        }
                        if (cell.getText().equals("${address}")) {
                            if (String.valueOf(map.get("address")).length() > 0) {
                                cell.removeParagraph(0);
                                List<String> addressSize = CutStringUtil.getCharLength(String.valueOf(map.get("address")), 400);
                                total += addressSize.size();
                                for (int i = 0; i < addressSize.size(); i++) {
                                    XWPFRun run = cell.addParagraph().createRun();
                                    run.setText(addressSize.get(i));
                                    cell.getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);
                                    cell.getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
                                }
                                map.remove("address");
                            } else {
                                log.warn("${address}数据为空，请检查数据！");
                            }
                        }
                        if (cell.getText().equals("${representative}")) {
                            if (String.valueOf(map.get("representative")).length() > 0) {
                                cell.removeParagraph(0);
                                List<String> representative = CutStringUtil.getCharLength(String.valueOf(map.get("representative")), 64);
                                representativel += representative.size();
                                for (int i = 0; i < representative.size(); i++) {
                                    cell.addParagraph().createRun().setText(representative.get(i));
                                    cell.getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);
                                    cell.getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
                                }
                                map.remove("representative");
                            } else {
                                log.warn("${representative}数据为空，请检查数据！");
                            }
                        }
                        if (cell.getText().equals("${duty}")) {
                            if (String.valueOf(map.get("duty")).length() > 0) {
                                cell.removeParagraph(0);
                                List<String> representative = CutStringUtil.getCharLength(String.valueOf(map.get("duty")), 64);
                                dutyl += representative.size();
                                for (int i = 0; i < representative.size(); i++) {
                                    cell.addParagraph().createRun().setText(representative.get(i));
                                    cell.getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);
                                    cell.getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
                                }
                                map.remove("duty");
                            } else {
                                log.warn("${duty}数据为空，请检查数据！");
                            }
                        }
                        if (cell.getText().equals("${telphone}")) {
                            if (String.valueOf(map.get("telphone")).length() > 0) {
                                cell.removeParagraph(0);
                                List<String> representative = CutStringUtil.getCharLength(String.valueOf(map.get("telphone")), 104);
                                telphonel += representative.size();
                                for (int i = 0; i < representative.size(); i++) {
                                    cell.addParagraph().createRun().setText(representative.get(i));
                                    cell.getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);
                                    cell.getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
                                }
                                map.remove("telphone");
                            } else {
                                log.warn("${telphone}数据为空，请检查数据！");
                            }
                        }
                        if (cell.getText().equals("${site}")) {
                            if (String.valueOf(map.get("site")).length() > 0) {
                                cell.removeParagraph(0);
                                List<String> representative = CutStringUtil.getCharLength(String.valueOf(map.get("site")), 144);
                                sitel += representative.size();
                                for (int i = 0; i < representative.size(); i++) {
                                    cell.addParagraph().createRun().setText(representative.get(i));
                                    //设置表格内容垂直居中
                                    cell.getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);
                                    cell.getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
                                }
                                map.remove("site");
                            } else {
                                log.warn("${site}数据为空，请检查数据！");
                            }
                        }
                        if (cell.getText().equals("${time}")) {
                            if (String.valueOf(map.get("time")).length() > 0) {
                                cell.removeParagraph(0);
                                List<String> representative = CutStringUtil.getCharLength(String.valueOf(map.get("time")), 184);
                                timel += representative.size();
                                for (int i = 0; i < representative.size(); i++) {
                                    cell.addParagraph().createRun().setText(representative.get(i));
                                }
                                map.remove("time");
                            } else {
                                log.warn("${time}数据为空，请检查数据！");
                            }
                        }
                        if (cell.getText().contains("${question}")) {
                            total += getMax(representativel, dutyl, telphonel);
                            total += getMax(sitel, timel);
                            //填充完上面参数后还剩下的首页行数
                            int surplusLine = FIR_LINE_TOTAL - total;
                            List<XWPFParagraph> paragraphs = cell.getParagraphs();
                            XWPFParagraph paragraph = paragraphs.get(1);
                            paragraph.removeRun(0);
                            paragraph.removeRun(0);
                            List<List<String>> dataList = TestUtil.dataCut(question, surplusLine, SEN_LINE_TOTAL);
                            if (dataList.size() == 1) {
                                map.replace("total", 1);  //设置总页数为1
                                EditWordZZUtil.setUnderLine(home, map); //设置下划线
                                for (int i = 0; i < dataList.get(0).size(); i++) {
                                    String str = dataList.get(0).get(i);
                                    XWPFRun run = paragraph.createRun();
                                    run.setText(str);
                                    run.addBreak();
                                }
                                XWPFRun run = paragraph.createRun();//添加（以下空白）
                                run.setText(BLANK_BELOW);
                                run.addBreak();
                                EditWordZZUtil.readWriteWord(home,map);
//                                home.write(outputStream);
                                document = home;
//                                return null;
                            } else {
                                BigDecimal thrLineTotal = new BigDecimal(THR_LINE_TOTAL);
                                BigDecimal material = new BigDecimal(materials.size());
                                //向下取整 ，计算总页数
                                int pages = dataList.size();
                                int thrNum = (int) Math.floor(material.divide(thrLineTotal, 2, BigDecimal.ROUND_DOWN).doubleValue());
                                if (material.divide(thrLineTotal, 2).doubleValue() == thrNum) {
                                    count += thrNum;
                                    map.replace("total", thrNum + pages);
                                } else {
                                    count += thrNum;
                                    map.replace("total", thrNum + pages + 1);
                                }
                                for (int i = 0; i < dataList.size(); i++) {
                                    if (i == 0) {
                                        EditWordZZUtil.setUnderLine(home, map);
                                        for (int j = 0; j < dataList.get(0).size(); j++) {
                                            XWPFRun run = paragraph.createRun();
                                            run.setText(dataList.get(0).get(j));
                                            run.addBreak();
                                        }
                                        XWPFRun run = paragraph.createRun();
                                        run.setText(BLANK_BELOW);
//                                        run.addBreak();
                                        EditWordZZUtil.readWriteWord(home, map);
                                    } else {
                                        continuationSheet = minioTemplate.minio.getObject("jljc", "Inspect2.docx");
                                        XWPFDocument continuation = new XWPFDocument(OPCPackage.open(continuationSheet));
                                        map.replace("index", i + 1);
                                        EditWordZZUtil.setUnderLine(continuation, map);
                                        List<XWPFTable> xwpfTables = continuation.getTables();
                                        for (XWPFTable xwpfTable : xwpfTables) {
                                            List<XWPFTableRow> tableRows = xwpfTable.getRows();
                                            for (XWPFTableRow tableRow : tableRows) {
                                                List<XWPFTableCell> xwpfTableCells = tableRow.getTableCells();
                                                for (XWPFTableCell xwpfTableCell : xwpfTableCells) {
                                                    if (xwpfTableCell.getText().contains("question")) {
                                                        List<XWPFParagraph> paragraphs1 = xwpfTableCell.getParagraphs();
                                                        XWPFParagraph paragraph1 = paragraphs1.get(0);
                                                        paragraph1.removeRun(0);
                                                        for (int j = 0; j < dataList.get(i).size(); j++) {
                                                            if (j + 1 < dataList.get(i).size() && dataList.get(i).get(j + 1).contains("笔录完毕")) {
                                                                XWPFRun run1 = paragraph1.createRun();
                                                                run1.setText(dataList.get(i).get(j));
                                                                run1.addBreak();
                                                                XWPFRun run2 = paragraph1.createRun();
                                                                run2.setText(BLANK_BELOW);
                                                                run2.addBreak();
                                                                run2.addBreak();
                                                            } else if (dataList.get(i).get(j).contains("笔录完毕")) {
                                                                XWPFRun run1 = paragraph1.createRun();
                                                                run1.setText(dataList.get(i).get(j));
                                                                run1.addBreak();
                                                                run1.addBreak();
                                                            } else {
                                                                XWPFRun run = paragraph1.createRun();
                                                                run.setText(dataList.get(i).get(j));
                                                                run.addBreak();
                                                            }
                                                        }
                                                        XWPFRun run = paragraph1.createRun();
                                                        run.setText(BLANK_BELOW);
//                                                        run.addBreak();
                                                        int lineFlag = 0;
                                                        if (i + 1 == dataList.size()){
                                                            List<String> stringList = dataList.get(i);
                                                            for (int k = 0; k < stringList.size(); k++) {
                                                                String s = stringList.get(k);
                                                                lineFlag += TestUtil.getLineTotal(s, 544);
                                                            }
                                                            for (int j = 0; j < SEN_LINE_TOTAL - lineFlag - 1; j++) {
                                                                run.addBreak();
                                                            }
                                                        }
                                                        EditWordZZUtil.readWriteWord(continuation, map);
                                                    }
                                                }
                                            }
                                        }
                                        MergeDocx mergeDocx = new MergeDocx();
                                        if (i == 1) {
                                            document = mergeDocx.mergeWord(home, continuation);
                                        } else {
                                            document = mergeDocx.mergeDocx(document, continuation);
                                        }
                                        if (continuationSheet != null) {
                                            continuationSheet.close();
                                        }
                                    }
                                }
                            }
                            break a;
                        }
                    }
                }
            }
        } else {
            log.warn("传入的数据为空，请检查数据!");
        }
        if (materials.size() > 0) {
            if (THR_LINE_TOTAL >= materials.size()) {
                //填充第三页
                XWPFDocument xwpfDocument = new XWPFDocument(OPCPackage.open(inputStream));
                List<XWPFTable> tables = xwpfDocument.getTables();
                for (XWPFTable table : tables) {
                    List<XWPFTableRow> rows = table.getRows();
                    for (XWPFTableRow row : rows) {
                        List<XWPFTableCell> cells = row.getTableCells();
                        for (XWPFTableCell cell : cells) {
                            if (cell.getText().contains("${materials}")) {
                                List<XWPFParagraph> paragraphs = cell.getParagraphs();
                                XWPFParagraph paragraph = paragraphs.get(1);
                                paragraph.removeRun(0);
                                paragraph.removeRun(0);
                                paragraph.removeRun(0);
                                paragraph.removeRun(0);
                                map.replace("index", map.get("total"));
                                int breakCount = THR_LINE_TOTAL - materials.size();
                                EditWordZZUtil.setUnderLine(xwpfDocument, map); //设置下划线
                                for (int i = 0; i < materials.size(); i++) {
                                    XWPFRun run = paragraph.createRun();
                                    run.setText(materials.get(i));
                                    run.addBreak();
                                }
                                XWPFRun run = paragraph.createRun();//添加（以下空白）
                                run.setText(BLANK_BELOW);
                                run.addBreak();
                                for (int i = 0; i < breakCount; i++) {
                                    XWPFRun run2 = paragraph.createRun();
                                    run2.addBreak();
                                }
                            }
                        }
                    }
                }
                EditWordZZUtil.readWriteWord(xwpfDocument, map);
                MergeDocx mergeDocx = new MergeDocx();
                document = mergeDocx.mergeWord(document, xwpfDocument);
                if (inputStream != null) {
                    inputStream.close();
                }
            } else {
                int total1 = (int) map.get("total");
                int breakCount = 0;
                for (int i = 0; i < count; i++) {
                    inputStream = minioTemplate.minio.getObject("jljc", "Inspect3.docx");
                    XWPFDocument xwpfDocument = new XWPFDocument(OPCPackage.open(inputStream));
                    map.replace("index", total1 - count + i);
                    EditWordZZUtil.readWriteWord(xwpfDocument, map);
                    EditWordZZUtil.setUnderLine(xwpfDocument, map);
//                    EditWordZZUtil.setBold(xwpfDocument);
                    List<XWPFTable> tables = xwpfDocument.getTables();
                    for (XWPFTable table : tables) {
                        List<XWPFTableRow> rows = table.getRows();
                        for (XWPFTableRow row : rows) {
                            List<XWPFTableCell> cells = row.getTableCells();
                            for (XWPFTableCell cell : cells) {
                                if (cell.getText().contains("${materials}")) {
                                    List<XWPFParagraph> paragraphs = cell.getParagraphs();
                                    XWPFParagraph paragraph = paragraphs.get(1);
                                    paragraph.removeRun(0);
                                    paragraph.removeRun(0);
                                    List<String> newList = new ArrayList<>();
                                    List<String> mList = new ArrayList<>();
                                    mList.addAll(materials);
                                    for (Integer integer = 0; integer < THR_LINE_TOTAL; integer++) {
                                        newList.add(mList.get(i));
                                        materials.remove(0);
                                    }
                                    for (int j = 0; j < newList.size(); j++) {
                                        XWPFRun run = paragraph.createRun();
                                        run.setText(newList.get(j));
                                        run.addBreak();
                                    }
                                    XWPFRun run = paragraph.createRun();
                                    run.setText(BLANK_BELOW);
                                    run.addBreak();
                                    if (i + 1 == count) {
                                        breakCount = THR_LINE_TOTAL - newList.size();
                                        for (int l = 0; l < breakCount; l++) {
                                            XWPFRun run2 = paragraph.createRun();
                                            run2.addBreak();
                                        }
                                    }
                                }
                            }
                        }
                    }
                    MergeDocx mergeDocx = new MergeDocx();
                    document = mergeDocx.mergeWord(document, xwpfDocument);
                    if (null != inputStream) {
                        inputStream.close();
                    }
                }
            }
        } else {
            log.warn("传入的数据为空，请检查数据!");
        }
        document.write(outputStream);
        if (null != homePage) {
            homePage.close();
        }
        if (null != outputStream) {
            outputStream.close();
            outputStream.flush();
        }
        return null;
    }

    private static int getMax(int... ints) {
        int max = 0;
        Arrays.sort(ints);
        max = ints[ints.length - 1];
        return max;
    }

}
