package com.zzsn.common.poi;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.zzsn.common.util.DateUtils;
import com.zzsn.common.util.SpringContextUtils;
import com.zzsn.modules.kgj.entity.BaseDataImage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.util.Units;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.stereotype.Repository;
import org.springframework.util.ResourceUtils;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 导出工具
 * @author YJL
 */
@Repository
@Slf4j
public class DownloadFileUtil {


	/**
	 * 导出word文件，POI方式，定义数据源

	 * @param mapEntity
	 * @param fileAbsolutePath
	 * @throws Exception
	 * 敏感信息简报-2023050501
	 */

	public static String exportArticleWordByPoi(final Map<String, String> mapEntity, final String fileAbsolutePath) throws Exception {
		String fileName= fileAbsolutePath;
		OPCPackage tmpPackage=null;
		FileOutputStream out=null;
		try {
			//创建文档对象
//			tmpPackage = POIXMLDocument.openPackage(fileName);
			XWPFDocument doc = new XWPFDocument();
			// 2.创建标题
			XWPFParagraph title = doc.createParagraph();
			DownLoadSupport.getParagraph(title, mapEntity.get("title"), ParagraphAlignment.CENTER, "宋体", 15, true);
			//资讯来源
			XWPFParagraph publishMsg = doc.createParagraph();
			String msg="  发布时间："+mapEntity.get("time")+"  来源："+mapEntity.get("source");
			DownLoadSupport.getParagraph(publishMsg, msg, ParagraphAlignment.RIGHT, "宋体", 8, false);


			XWPFParagraph p2 = doc.createParagraph();
			DownLoadSupport.getParagraph(p2, "正文：", ParagraphAlignment.LEFT, "宋体", 10, true);

			String text = "  " + mapEntity.get("content");
			String[] tt = text.split("(?<=[。])");
			if (tt.length>1 && text.length()>50) {
				String ms="";
				for (int i = 0; i < tt.length; i++) {
					ms+=tt[i];
					if(ms.length()>50||i==tt.length-1) {
						XWPFParagraph textP = doc.createParagraph();
						textP.setIndentationHanging(-540);
						DownLoadSupport.getParagraph(textP, ms, ParagraphAlignment.LEFT, "宋体", 12, false);
						ms="";
					}
					if (i == 1 && StringUtils.isNotEmpty(mapEntity.get("picPath"))) {
						//图片：
						XWPFParagraph p6 = doc.createParagraph();
						p6.setAlignment(ParagraphAlignment.CENTER);
						InputStream sm = new FileInputStream(mapEntity.get("picPath"));
						XWPFRun r6 = p6.createRun();
						r6.addPicture(sm, XWPFDocument.PICTURE_TYPE_PNG, "Generated", Units.toEMU(300), Units.toEMU(200));
					}
				}
			}else{
				XWPFParagraph textP = doc.createParagraph();
				textP.setIndentationHanging(-360);
				DownLoadSupport.getParagraph(textP, text, ParagraphAlignment.LEFT, "宋体", 12, false);
				if (StringUtils.isNotEmpty(mapEntity.get("picPath"))) {
					XWPFParagraph p6 = doc.createParagraph();
					p6.setAlignment(ParagraphAlignment.CENTER);
					InputStream sm = new FileInputStream(mapEntity.get("picPath"));
					XWPFRun r6 = p6.createRun();
					r6.addPicture(sm, XWPFDocument.PICTURE_TYPE_PNG, "Generated", Units.toEMU(300), Units.toEMU(200));
				}
			}
//			XWPFParagraph contentMsg = doc.createParagraph();
//			String content = "【正文】 " + mapEntity.get("content");
//			DownLoadSupport.getParagraph(contentMsg, content, ParagraphAlignment.LEFT, "宋体", 12, false);
			XWPFParagraph p1 = doc.createParagraph();
			DownLoadSupport.getParagraph(p1, "关键词：", ParagraphAlignment.LEFT, "宋体", 10, true);
			XWPFParagraph keywordMsg = doc.createParagraph();
			String keyword = mapEntity.get("keywords").replace(";","    ");
			DownLoadSupport.getParagraph(keywordMsg, keyword, ParagraphAlignment.LEFT, "宋体", 12, false);

			XWPFParagraph p3 = doc.createParagraph();
			DownLoadSupport.getParagraph(p3, "备注：", ParagraphAlignment.LEFT, "宋体", 10, true);
			XWPFParagraph beizhuMsg = doc.createParagraph();
			String beizhu = "   " + mapEntity.get("beizhu");
			DownLoadSupport.getParagraph(beizhuMsg, beizhu, ParagraphAlignment.LEFT, "宋体", 12, false);

			//项目风险：
			XWPFParagraph p7 = doc.createParagraph();
			DownLoadSupport.getParagraph(p7, "敏感信息得分：", ParagraphAlignment.LEFT, "宋体", 10, true);

			XWPFTable table3 = doc.createTable(4, 2);
			DownLoadSupport.setTableWidthAndHeight(table3, 9 * 1000, 500);
			DownLoadSupport.getCellParagraph(table3.getRow(0).getCell(0), "关键词得分", "宋体", 10, false);
			DownLoadSupport.getCellParagraph(table3.getRow(0).getCell(1),mapEntity.get("score4key"), "宋体", 10, false);
			DownLoadSupport.getCellParagraph(table3.getRow(1).getCell(0),"句子得分", "宋体", 10, false);
			DownLoadSupport.getCellParagraph(table3.getRow(1).getCell(1),mapEntity.get("score4sentence"), "宋体", 10, false);
			DownLoadSupport.getCellParagraph(table3.getRow(2).getCell(0),"图谱得分", "宋体", 10, false);
			DownLoadSupport.getCellParagraph(table3.getRow(2).getCell(1),mapEntity.get("score4graph"), "宋体", 10, false);
			DownLoadSupport.getCellParagraph(table3.getRow(3).getCell(0),"总得分", "宋体", 10, false);
			DownLoadSupport.getCellParagraph(table3.getRow(3).getCell(1),mapEntity.get("totalscore"), "宋体", 10, false);

			XWPFParagraph sAddr = doc.createParagraph();
			String sourceAddr = "来源链接： " + mapEntity.get("sourceAddress");
			DownLoadSupport.getParagraph(sAddr, sourceAddr, ParagraphAlignment.RIGHT, "宋体", 10, false);

			File file = new File(fileAbsolutePath);
			file.createNewFile();
			out = new FileOutputStream(file);
			doc.write(out);
			out.close();
			doc.close();
		}catch (Exception e){
			e.printStackTrace();
			log.error(e.getMessage(),e);
			return fileAbsolutePath;
		}finally {
			if (tmpPackage != null) {
				try {
					tmpPackage.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (out != null) {
				try {
					out.close();
				}catch(IOException e){
					log.error(e.getMessage(),e);
					e.printStackTrace();
				}
			}
		}
		System.out.println(fileAbsolutePath);
		return fileAbsolutePath;
	}

	/**
	 *
	 * @param mapEntity
	 * @param fileAbsolutePath
	 * @return
	 * @throws Exception
	 *
	 *
	 *
	 */
	public static String exportArticleWordByPoiNew(final Map<String, String> mapEntity, final String fileAbsolutePath,
												   List<BaseDataImage> baseDataImages) throws Exception {
		String fileName= fileAbsolutePath;
		FileOutputStream out=null;
		try {
			Date date=new Date();
			String tdate = DateUtil.format(date, "yyyyMMddHHmm");
			String cdate = DateUtil.format(date, "yyyy年MM月dd日");
			//创建文档对象
			XWPFDocument doc = new XWPFDocument();
			// 2.创建标题
			XWPFParagraph title = doc.createParagraph();
			String tte="敏感信息简报-"+tdate;
			DownLoadSupport.getParagraph(title, tte, ParagraphAlignment.CENTER, "宋体", 16, false);
			//资讯来源
			XWPFParagraph publishMsg = doc.createParagraph();
			publishMsg.setIndentationHanging(-540);
			String msg=""+cdate+"【简报生成日期】，监测人员发现"+mapEntity.get("source")+"【来源】于"+mapEntity.get("time")+
					"发布的一篇名为《"+mapEntity.get("title")+"》的文章包含敏感信息。该文章相关研判信息如下：";
			DownLoadSupport.getParagraph(publishMsg, msg, ParagraphAlignment.LEFT, "宋体", 14, false);

			XWPFParagraph keywordMsg = doc.createParagraph();
			keywordMsg.setIndentationHanging(-540);
			String keyword = "文章关键词："+mapEntity.get("keywords").replace(";","	");
			DownLoadSupport.getParagraph(keywordMsg, keyword, ParagraphAlignment.LEFT, "宋体", 14, false);

			XWPFParagraph summaryMsg = doc.createParagraph();
			summaryMsg.setIndentationHanging(-540);
			String content = "摘要：" + mapEntity.get("summary").replace(" ","");
			DownLoadSupport.getParagraph(summaryMsg, content, ParagraphAlignment.LEFT, "宋体", 14, false);

			XWPFParagraph p7 = doc.createParagraph();
			p7.setIndentationHanging(-540);
			DownLoadSupport.getParagraph(p7, "敏感信息得分：", ParagraphAlignment.LEFT, "宋体", 14, false);
			XWPFTable table3 = doc.createTable(4, 2);

			DownLoadSupport.setTableWidthAndHeight(table3, 5000, 500);
			DownLoadSupport.getCellParagraph(table3.getRow(0).getCell(0), "关键词得分", "宋体", 14, false);
			DownLoadSupport.getCellParagraph(table3.getRow(0).getCell(1),mapEntity.get("score4key"), "宋体", 14, false);
			DownLoadSupport.getCellParagraph(table3.getRow(1).getCell(0),"句子得分", "宋体", 14, false);
			DownLoadSupport.getCellParagraph(table3.getRow(1).getCell(1),mapEntity.get("score4sentence"), "宋体", 14, false);
			DownLoadSupport.getCellParagraph(table3.getRow(2).getCell(0),"图谱得分", "宋体", 14, false);
			DownLoadSupport.getCellParagraph(table3.getRow(2).getCell(1),mapEntity.get("score4graph"), "宋体", 14, false);
			DownLoadSupport.getCellParagraph(table3.getRow(3).getCell(0),"总得分", "宋体", 14, false);
			DownLoadSupport.getCellParagraph(table3.getRow(3).getCell(1),mapEntity.get("totalscore"), "宋体", 14, false);
			setTableLocation(table3,"center");
//			setCellLocation(table3,"CENTER","center");

			XWPFParagraph p3 = doc.createParagraph();
			p3.setIndentationHanging(-540);
			DownLoadSupport.getParagraph(p3, "是否命中密点库："+mapEntity.get("isScret"), ParagraphAlignment.LEFT, "宋体", 14, false);

			XWPFParagraph sAddrtext = doc.createParagraph();
			sAddrtext.setIndentationHanging(-540);
			DownLoadSupport.getParagraph(sAddrtext, "来源链接： ", ParagraphAlignment.LEFT, "宋体", 14, false);
			XWPFParagraph sAddr = doc.createParagraph();
			DownLoadSupport.getParagraph(sAddr, mapEntity.get("sourceAddress"), ParagraphAlignment.LEFT, "宋体", 14, false);

			XWPFParagraph beizhuMsg = doc.createParagraph();
			beizhuMsg.setIndentationHanging(-540);
			String beizhu = "研判意见：" + mapEntity.get("beizhu");
			DownLoadSupport.getParagraph(beizhuMsg, beizhu, ParagraphAlignment.LEFT, "宋体", 14, false);

			XWPFParagraph fujianMsg = doc.createParagraph();
			fujianMsg.setPageBreak(true);
			DownLoadSupport.getParagraph(fujianMsg, "附件：", ParagraphAlignment.LEFT, "宋体", 14, false);

			XWPFParagraph titlePh = doc.createParagraph();
			String titlet= mapEntity.get("title");
			DownLoadSupport.getParagraph(titlePh, titlet, ParagraphAlignment.CENTER, "宋体", 14, false);
			XWPFParagraph sourcePh = doc.createParagraph();
			String sourcet= mapEntity.get("time")+"  "+mapEntity.get("source");
			DownLoadSupport.getParagraph(sourcePh, sourcet, ParagraphAlignment.RIGHT, "宋体", 14, false);


//			XWPFParagraph contentMsg = doc.createParagraph();
//			contentMsg.setIndentationHanging(-540);
			String ctent= mapEntity.get("content");
//			DownLoadSupport.getParagraph(contentMsg, ctent, ParagraphAlignment.LEFT, "宋体", 14, false);

			String[] tt = ctent.split("(?<=[。])");
			if (tt.length>1 && ctent.length()>50) {
				String ms="";
				for (int k = 0; k < tt.length; k++) {
					ms+=tt[k];
					if(ms.length()>50||k==tt.length-1) {
						XWPFParagraph textP = doc.createParagraph();
						textP.setIndentationHanging(-540);
						DownLoadSupport.getParagraph(textP, ms, ParagraphAlignment.LEFT, "宋体", 12, false);
						ms="";
					}
					if (baseDataImages.size()>0 ) {
						if( k < baseDataImages.size()){
							//图片：
							XWPFParagraph p6 = doc.createParagraph();
							p6.setAlignment(ParagraphAlignment.CENTER);
							BaseDataImage base64 = baseDataImages.get(k);
							InputStream input=null;
							if(base64!=null) {
								byte[] bytes = new BASE64Decoder().decodeBuffer(base64.getDataImage());
								input = new ByteArrayInputStream(bytes);
							}
							XWPFRun r6 = p6.createRun();
							r6.addPicture(input, XWPFDocument.PICTURE_TYPE_PNG, "Generated", Units.toEMU(300), Units.toEMU(200));
						}

					}
				}
			}else{
				XWPFParagraph textP = doc.createParagraph();
				textP.setIndentationHanging(-540);
				DownLoadSupport.getParagraph(textP, ctent, ParagraphAlignment.LEFT, "宋体", 12, false);

				if (baseDataImages.size()>0) {
					for (int i = 0; i < baseDataImages.size(); i++) {
						//图片：
						XWPFParagraph p6 = doc.createParagraph();
						p6.setAlignment(ParagraphAlignment.CENTER);
						BaseDataImage base64 = baseDataImages.get(i);
						InputStream input=null;
						if(base64!=null) {
							byte[] bytes = new BASE64Decoder().decodeBuffer(base64.getDataImage());
							input = new ByteArrayInputStream(bytes);
						}
//					InputStream sm = new FileInputStream(mapEntity.get("picPath"));
						XWPFRun r6 = p6.createRun();
						r6.addPicture(input, XWPFDocument.PICTURE_TYPE_PNG, "Generated", Units.toEMU(300), Units.toEMU(200));

					}
				}
			}

			XWPFParagraph linkPh = doc.createParagraph();
			String link= mapEntity.get("sourceAddress");
			DownLoadSupport.getParagraph(linkPh, link, ParagraphAlignment.RIGHT, "宋体", 14, false);


			File file = new File(fileAbsolutePath);
			file.createNewFile();
			out = new FileOutputStream(file);
			doc.write(out);
			out.close();
			doc.close();
		}catch (Exception e){
			e.printStackTrace();
			log.error(e.getMessage(),e);
			return fileAbsolutePath;
		}finally {
			if (out != null) {
				try {
					out.close();
				}catch(IOException e){
					log.error(e.getMessage(),e);
					e.printStackTrace();
				}
			}
		}
		System.out.println(fileAbsolutePath);
		return fileAbsolutePath;
	}

	/**
	 * 设置单元格水平位置和垂直位置
	 *
	 * @param xwpfTable
	 * @param verticalLoction 单元格中内容垂直上TOP，下BOTTOM，居中CENTER，BOTH两端对齐
	 * @param horizontalLocation 单元格中内容水平居中center,left居左，right居右，both两端对齐
	 */
	public static void setCellLocation(XWPFTable xwpfTable, String verticalLoction, String horizontalLocation) {
		List<XWPFTableRow> rows = xwpfTable.getRows();
		for (XWPFTableRow row : rows) {
			List<XWPFTableCell> cells = row.getTableCells();
			for (XWPFTableCell cell : cells) {
				CTTc cttc = cell.getCTTc();
				CTP ctp = cttc.getPList().get(0);
				CTPPr ctppr = ctp.getPPr();
				if (ctppr == null) {
					ctppr = ctp.addNewPPr();
				}
				CTJc ctjc = ctppr.getJc();
				if (ctjc == null) {
					ctjc = ctppr.addNewJc();
				}
				ctjc.setVal(STJc.Enum.forString(horizontalLocation)); //水平居中
				cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.valueOf(verticalLoction));//垂直居中
			}
		}
	}

	/**
	 * 设置表格位置
	 *
	 * @param xwpfTable
	 * @param location 整个表格居中center,left居左，right居右，both两端对齐
	 */
	public static void setTableLocation(XWPFTable xwpfTable, String location) {
		CTTbl cttbl = xwpfTable.getCTTbl();
		CTTblPr tblpr = cttbl.getTblPr() == null ? cttbl.addNewTblPr() : cttbl.getTblPr();
		CTJc cTJc = tblpr.addNewJc();
		cTJc.setVal(STJc.Enum.forString(location));
	}

	public static <T> List<T> objToList(Object obj, Class<T> cla) throws Exception{
		List<T> list = new ArrayList<T>();
		if (obj instanceof ArrayList<?>) {
			for (Object o : (List<?>) obj) {
				list.add(cla.cast(o));
			}
			return list;
		}
		return null;
	}

	/**
	 * 判断是否全为数字
	 * @param str
	 * @return
	 */
	private static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("[0-9]*");
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) {
			return false;
		}
		return true;
	}


	/**
	 * 导出excel文件类
	 * @param response
	 * @param fileAbsolutePath
	 * @throws Exception
	 */
	public static void exportExcel(HttpServletResponse response,String fileAbsolutePath) throws Exception {
		File file = new File(fileAbsolutePath);
		String strFileName = file.getName();
 		response.reset();
 		response.setCharacterEncoding("UTF-8");
		response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization");
		response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
 		response.setContentType("application/x-download");//不同类型的文件对应不同的MIME类型x-download  vnd.ms-excel
 		response.setHeader("Content-Disposition","attachment; filename=" + new String(strFileName.getBytes(), "ISO-8859-1") );
		//response.setHeader("Access-Control-Allow-Origin","*");
		HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
		response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
		//System.out.println(request.getHeader("Origin"));
		response.addHeader("Access-Control-Allow-Credentials","true");
		if(file.exists()){
 		  	try{
 		  		OutputStream os = response.getOutputStream();
 		  		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));

 		  		long size = file.length();//获取文件总大小
 		  		byte[] buffer = null;
 		  		if(size < 10*1024*1024 ){//< 10M (10*1024*1024)
 		  			buffer = new byte[bis.available()];
 		  			while(bis.read(buffer) > 0){
 	 		  			os.write(buffer);
 	 		  		}
 		  		} else { //文件大于10M的采用 每次读取4M的方式进行处理
 		  			buffer = new byte[ (int) (4 * 10*1024*1024) ]; //4 * 1024 * 1024
 		  			int i = -1;
 		  			while ((i = bis.read(buffer)) != -1) {
 		  				os.write(buffer, 0, i);
 		  			}
 		  		}
 		  		os.flush();
 		  		bis.close();
 		  		os.close();
 		  	}catch(Exception e){
 		  		System.out.println(e.toString());
 		  		log.info("下载数据时发生异常:"+e.getMessage());
 		  	}finally{
 		  		//删除文件 并且 删除文件的前一级目录
				FileUtils.forceDelete(file);//删除文件

//	  			FileUtils.deleteDirectory(file.getParentFile());//删除文件的前一个目录
 		  	}
		}
	}



}
