package com.jpsoft.shinestar.modules.common.utils;

import com.jpsoft.shinestar.config.OSSConfig;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.core.io.ClassPathResource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * word生成
 * @author sz
 */
public class NewWordUtils {
	/**
	 * 根据模板生成新word文档
	 * 判断表格是需要替换还是需要插入，判断逻辑有$为替换，表格无$为插入
	 * @param inputUrl 模板存放地址
	 * @param textMap 需要替换的信息集合
	 * @param tableList 需要插入的表格信息集合
	 * @return 成功返回true,失败返回false
	 */
	public static String changWord(String inputUrl, OSSConfig ossConfig, Map<String, String> textMap, List<String[]> tableList) {
		String downloadUrl = "";
		try {
			//获取docx解析对象
			ClassPathResource resource = new ClassPathResource(inputUrl);
			//XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
			XWPFDocument document = new XWPFDocument(resource.getInputStream());
			//解析替换文本段落对象
			changeText(document, textMap);
			//解析替换表格对象
			changeTable(document, textMap, tableList);

			//生成新的word
			ByteArrayOutputStream baos = new ByteArrayOutputStream();//二进制OutputStream
			document.write(baos);//文档写入流
			ByteArrayInputStream input = new ByteArrayInputStream(baos.toByteArray());

			Date dt = new Date();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
			String str = "外出申请单" + sdf.format(dt) + ".docx";

			downloadUrl = OSSUtil.upload(ossConfig,"import",str,input);
//            FileOutputStream stream = new FileOutputStream(file);
//            document.write(stream);
			//stream.close();

		} catch (IOException e) {
			e.printStackTrace();
		}

		return downloadUrl;

	}


	/**
	 * 替换段落文本
	 * @param document docx解析对象
	 * @param textMap 需要替换的信息集合
	 */
	public static void changeText(XWPFDocument document, Map<String, String> textMap){
		//获取段落集合
		List<XWPFParagraph> paragraphs = document.getParagraphs();

		for (XWPFParagraph paragraph : paragraphs) {
			//判断此段落时候需要进行替换
			String text = paragraph.getText();
			if(checkText(text)){
				List<XWPFRun> runs = paragraph.getRuns();
				for (XWPFRun run : runs) {
					//替换模板原来位置
					run.setText(changeValue(run.toString(), textMap), 0);
				}
			}
		}

	}

	/**
	 * 替换表格对象方法
	 * @param document docx解析对象
	 * @param textMap 需要替换的信息集合
	 * @param tableList 需要插入的表格信息集合
	 */
	public static void changeTable(XWPFDocument document, Map<String, String> textMap,
								   List<String[]> tableList){
		//获取表格对象集合
		List<XWPFTable> tables = document.getTables();
		for (int i = 0; i < tables.size(); i++) {
			//只处理行数大于等于2的表格，且不循环表头
			XWPFTable table = tables.get(i);
			if(table.getRows().size()>1){
				//判断表格是需要替换还是需要插入，判断逻辑有$为替换，表格无$为插入
				if(checkText(table.getText())){
					List<XWPFTableRow> rows = table.getRows();
					//遍历表格,并替换模板
					eachTable(rows, textMap);
				}else{
//                  System.out.println("插入"+table.getText());
					insertTable(table, tableList);
				}
			}
		}
	}





	/**
	 * 遍历表格
	 * @param rows 表格行对象
	 * @param textMap 需要替换的信息集合
	 */
	public static void eachTable(List<XWPFTableRow> rows ,Map<String, String> textMap){
		for (XWPFTableRow row : rows) {
			List<XWPFTableCell> cells = row.getTableCells();
			for (XWPFTableCell cell : cells) {
				//判断单元格是否需要替换
				if(checkText(cell.getText())){
					List<XWPFParagraph> paragraphs = cell.getParagraphs();
					for (XWPFParagraph paragraph : paragraphs) {
						List<XWPFRun> runs = paragraph.getRuns();
						for (XWPFRun run : runs) {
							run.setText(changeValue(run.toString(), textMap),0);
						}
					}
				}
			}
		}
	}

	/**
	 * 为表格插入数据，行数不够添加新行
	 * @param table 需要插入数据的表格
	 * @param tableList 插入数据集合
	 */
	public static void insertTable(XWPFTable table, List<String[]> tableList){
		//创建行,根据需要插入的数据添加新行，不处理表头
		for(int i = 1; i < tableList.size(); i++){
			XWPFTableRow row =table.createRow();
		}
		//遍历表格插入数据
		List<XWPFTableRow> rows = table.getRows();
		for(int i = 1; i < rows.size(); i++){
			XWPFTableRow newRow = table.getRow(i);
			List<XWPFTableCell> cells = newRow.getTableCells();
			for(int j = 0; j < cells.size(); j++){
				XWPFTableCell cell = cells.get(j);
				cell.setText(tableList.get(i-1)[j]);
			}
		}

	}



	/**
	 * 判断文本中时候包含$
	 * @param text 文本
	 * @return 包含返回true,不包含返回false
	 */
	public static boolean checkText(String text){
		boolean check  =  false;
		if(text.indexOf("$")!= -1){
			check = true;
		}
		return check;

	}

	/**
	 * 匹配传入信息集合与模板
	 * @param value 模板需要替换的区域
	 * @param textMap 传入信息集合
	 * @return 模板需要替换区域信息集合对应值
	 */
	public static String changeValue(String value, Map<String, String> textMap){
		Set<Map.Entry<String, String>> textSets = textMap.entrySet();
		for (Map.Entry<String, String> textSet : textSets) {
			//匹配模板与替换值 格式${key}
			String key = "${"+textSet.getKey()+"}";
			if(value!=null) {
				if (value.indexOf(key) != -1) {
					value = textSet.getValue();
				}
			}
		}
		//模板未匹配到区域替换为空
		if(value!=null) {
			if (checkText(value)) {
				value = "";
			}
		}
		return value;
	}
}
