package com.engine.organization.util.word;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.*;
import weaver.file.ImageFileManager;
import weaver.general.Util;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class WordUtil {

	/**
	 * 替换段落里面的变量
	 *
	 * @param doc    要替换的文档
	 * @param params 参数
	 * @throws FileNotFoundException
	 * @throws InvalidFormatException
	 */
	public void replaceInPara(CustomXWPFDocument doc, Map<String, Object> params) throws InvalidFormatException, FileNotFoundException {
		Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
		XWPFParagraph para;
		while (iterator.hasNext()) {
			para = iterator.next();
			this.replaceInPara(para, params,doc);
		}
	}

	/**
	 * 替换段落里面的变量
	 *
	 * @param para   要替换的段落
	 * @param params 参数
	 * @throws FileNotFoundException
	 * @throws InvalidFormatException
	 */
	public void replaceInPara(XWPFParagraph para, Map<String, Object> params, CustomXWPFDocument doc) throws InvalidFormatException, FileNotFoundException {
		List<XWPFRun> runs;
		Matcher matcher;
		if (this.matcher(para.getParagraphText()).find()) {
			runs = para.getRuns();

			int start = -1;
			int end = -1;
			String str = "";
			String text= "";
			for (int i = 0; i < runs.size(); i++) {
				text += runs.get(i).toString();
			}
			for (int i = 0; i < runs.size(); i++) {
				XWPFRun run = runs.get(i);
//				System.out.println("------>>>>>>>>>" + text);
				if (text.contains("$")) {
					start = text.indexOf("$");
				}
				if ((start != -1)) {
					str += text.substring(text.indexOf("$"), text.length()).trim();
					String paraList=runs.toString();
//					System.out.println("未删除前"+paraList);
					Object[] runArr = runs.toArray();
					int size=runs.size();
					int $Index=0;
					for (int j = 0; j < runArr.length; j++) {
						if (runArr[j].toString().contains("$")) {
							$Index=j;
							break;
						}
					}
					int startIn=$Index;
					while (startIn<runs.size()) {
						para.removeRun(startIn);
//						System.out.println("删除中"+para.getRuns());
					}
//					System.out.println("删除后"+para.getRuns());
				}
				if ('}' == text.charAt(text.length() - 1)) {
					if (start != -1) {
						end = text.length() - 1;
						break;
					}
				}
			}
//			System.out.println("start--->"+start);
//			System.out.println("end--->"+end);
//			System.out.println("str---->>>" + str);

			for (String key : params.keySet()) {
				if (str.equals(key)) {
					if(str.indexOf("@")==-1){
						String value= params.get(key).toString();
						para.createRun().setText(value);
						break;
					}else{
						String value= params.get(key).toString();
						if (StringUtils.isBlank(value)){
							break;
						}
						int length = para.getRuns().size();
						if (length > 0) {
							for (int i = (length - 1); i >= 0; i--) {
								para.removeRun(i);
							}
						}
						//网络图片取文件数据
						ImageFileManager manager = new ImageFileManager();
						manager.getImageFileInfoById(Util.getIntValue(value));
						InputStream inputStream = manager.getInputStream();

						byte[] buff = new byte[8000];
						int bytesRead = 0;
						ByteArrayOutputStream bao = new ByteArrayOutputStream();
						while(true) {
							try {
								if (!((bytesRead = inputStream.read(buff)) != -1)) break;
							} catch (IOException e) {
								e.printStackTrace();
							}
							bao.write(buff, 0, bytesRead);
						}
						byte[] data = bao.toByteArray();
						ByteArrayInputStream byteInputStream = new ByteArrayInputStream(data);

						String blipId = doc.addPictureData(byteInputStream, CustomXWPFDocument.PICTURE_TYPE_PNG);
						doc.createPicture(blipId,doc.getNextPicNameNumber(CustomXWPFDocument.PICTURE_TYPE_PNG), 120, 180,para);
						break;
					}
				}
			}


		}
	}

	/**
	 * 替换表格里面的变量
	 *
	 * @param doc    要替换的文档
	 * @param params 参数
	 * @throws FileNotFoundException
	 * @throws InvalidFormatException
	 */
	public void replaceInTable(CustomXWPFDocument doc, Map<String, Object> params) throws InvalidFormatException, FileNotFoundException {
		Iterator<XWPFTable> iterator = doc.getTablesIterator();
		XWPFTable table;
		List<XWPFTableRow> rows;
		List<XWPFTableCell> cells;
		List<XWPFParagraph> paras;
		while (iterator.hasNext()) {
			table = iterator.next();
			rows = table.getRows();
			for (XWPFTableRow row : rows) {
				cells = row.getTableCells();
				for (XWPFTableCell cell : cells) {
					paras = cell.getParagraphs();
					for (XWPFParagraph para : paras) {
						this.replaceInPara(para, params,doc);
					}
				}
			}
		}
	}

	/**
	 * 正则匹配字符串
	 *
	 * @param str
	 * @return
	 */
	private Matcher matcher(String str) {
		Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(str);
		return matcher;
	}

	/**
	 * 关闭输入流
	 *
	 * @param is
	 */
	public void close(InputStream is) {
		if (is != null) {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 关闭输出流
	 *
	 * @param os
	 */
	public void close(OutputStream os) {
		if (os != null) {
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 功能描述:读取线上图片文件流
	 *
	 * @param strUrl
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	public static byte[] getImageData(String strUrl) {
		InputStream inStream = null;
		try {
			// new一个URL对象
			URL url = new URL(strUrl);
			// 打开链接
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			// 设置请求方式为"GET"
			conn.setRequestMethod("GET");
			// 超时响应时间为5秒
			conn.setConnectTimeout(10 * 1000);
			// 通过输入流获取图片数据
			inStream = conn.getInputStream();
			byte[] data = readInputStream(inStream);
			return data;
		} catch (Exception e) {
			return null;
		} finally {
			if (inStream != null) {
				try {
					inStream.close();
				} catch (Exception e2) {
					System.out.println("关闭流失败");
				}
			}
		}

	}

	/**
	 * 功能描述:读取文件流
	 *
	 * @param inStream
	 * @return
	 * @throws Exception
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	public static byte[] readInputStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		// 创建一个Buffer字符串
		byte[] buffer = new byte[1024];
		// 每次读取的字符串长度，如果为-1，代表全部读取完毕
		int len = 0;
		// 使用一个输入流从buffer里把数据读取出来
		while ((len = inStream.read(buffer)) != -1) {
			// 用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
			outStream.write(buffer, 0, len);
		}
		// 关闭输入流
		inStream.close();
		// 把outStream里的数据写入内存
		return outStream.toByteArray();
	}
}