package cn.wise.sc.energy.power.plant.business.utils.poi;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.wise.sc.energy.power.plant.business.domain.AutoInspection;
import cn.wise.sc.energy.power.plant.business.domain.vo.DeviceInfoVo;
import cn.wise.sc.energy.power.plant.business.repository.AutoInspectionRepository;
import cn.wise.sc.energy.power.plant.business.repository.DeviceInfoRepository;
import cn.wise.sc.energy.power.plant.business.repository.PlantInfoRepository;
import cn.wise.sc.energy.power.plant.common.core.exception.ResponseEnum;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFHeader;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author shulidong
 * @since 2020/9/21 14:04
 */
@Service
@Slf4j
public class DocxService {


    @Autowired
    AutoInspectionRepository autoInspectionRepository;
    @Autowired
    ReportParamProcessor reportParamProcessor;

    @Autowired
    DeviceInfoRepository deviceInfoRepository;
    @Autowired
    PlantInfoRepository plantInfoRepository;

    private static final Logger LOGGER = LoggerFactory.getLogger(DocxService.class);

    public static void main(String[] args) {
        //"C0A001 - 1 - 1600756452620";
        String a = "C0A001 - 1 - 1600756452620";

        String[] c = a.trim().split("- ");
        LocalDateTime localDateTime = LocalDateTime.parse("2020-10-05T14:02:51");
        long time = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        System.out.println(time);
    }

    public byte[] fillDocx(String id) throws Exception {

        List<AutoInspection> list = autoInspectionRepository.findAllById(id);
        if (CollectionUtil.isEmpty(list)) {
            ResponseEnum.BUSINESS_ERROR.newException("未找到相应的报告项");
        }
        JSONObject allin = new JSONObject();
        log.error("-------------" + id);
        reportParamProcessor.paramJson(allin, list, list.get(0).getBtreetime().toInstant(ZoneOffset.of("+8")).toEpochMilli() + "");

        final InputStream inputStream = new ClassPathResource("templates/" + "demo1.docx").getStream();
        XWPFDocument document = new XWPFDocument(inputStream);
        //添加页眉 需要固定的文字(中文标点)在模板上->{{:text:date:date:}}
        List<XWPFHeader> pageHeaders = document.getHeaderList();
        JSONObject original = new JSONObject();
        JSONObject date = new JSONObject();
        date.put("date", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        original.put("date", date);
        for (int i = 0; i < pageHeaders.size(); i++) {
            XWPFHeader pageHeader = pageHeaders.get(i);
            List<XWPFParagraph> headerPara = pageHeader.getParagraphs();
            XWPFParagraph headerParagraph = headerPara.get(0);
            if (headerParagraph.getRuns().size() > 1) {
                PoiiUtiil.parseThisParagraph(headerParagraph, original);
            }
        }
        //获取所有的段落
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        //把文档groupby
        List<XWPFParagraph> texts = new ArrayList<>();
        List<XWPFTable> tables = new ArrayList<>();
        List<XWPFTable> iterable_tables = new ArrayList<>();
        for (XWPFParagraph paragraph : paragraphs) {
            String text = paragraph.getText();
            //只有这三种标签能够混用
            if (text.contains("{{:text") || text.contains("{{:for") || text.contains("{{:desc")) {
                texts.add(paragraph);
            }
        }
        for (XWPFTable table : document.getTables()) {
            if (table == null) {
                LOGGER.error("table is null, please stop!");
            }
            if (table.getText().contains("{{:table") || table.getText().contains("{{:text")) {
                tables.add(table);
            }
            if (table.getText().contains("{{$fe:")) {
                iterable_tables.add(table);
            }
        }

        JSONObject reportInfo = new JSONObject();
        //DeviceInfo deviceInfo = deviceInfoRepository.findFirstByDeviceId(list.get(0).getDeviceid());
        DeviceInfoVo deviceInfo = deviceInfoRepository.queryOnedeviceInfo(list.get(0).getDeviceid());
        //PlantInfo plantInfo = plantInfoRepository.findFirstByPlantId(deviceInfo.getPlantId());
        reportInfo.put("plantName", deviceInfo.getPlangName());
        reportInfo.put("deviceName", deviceInfo.getDeviceName());
        reportInfo.put("score", allin.get("grade"));
        allin.put("reportInfo", reportInfo);
        log.error("------------数据组装完毕");

        try {
            PoiiUtiil.paragraph(texts, allin);
            PoiiUtiil.table(tables, allin);
            HashMap<String, Object> map = new HashMap<>(1);
            List<Map<String, String>> plistMap = new ArrayList<>();
            if (allin.get("plist") != null) {
                plistMap = (List<Map<String, String>>) allin.get("plist");
            } else {
                //仿真数据
                plistMap.add(new HashMap<String, String>() {{
                    put("unitname", "无");
                    put("result", "无");
                    put("diagnosis", "无");
                }});
            }
            map.put("plist", plistMap);
            PoiiUtiil.parseThisTable(iterable_tables,map );

            //要求word在打开时提示更新域
            //document.enforceUpdateFields();
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            //FileOutputStream fos = new FileOutputStream("D:/"+ "生成文件.docx");
            document.write(byteArrayOutputStream);
            //fos.flush();
            //fos.close();
            return byteArrayOutputStream.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
