package com.ljh.excel.parser;

import com.ljh.excel.annotation.ColumnAnnotation;
import com.ljh.excel.bean.BaseBean;
import com.ljh.excel.bean.factory.ExcelFactory;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

//
public class BeanOperation {
	public void saveAll(List<? extends BaseBean> data) throws Exception {
		saveAll(data, data.get(0).getClass().getSimpleName());
	}

	public void saveAll(List<? extends BaseBean> data, String filename) throws Exception {
		// if (data.size() > 10000) {
		// boolean tag = true;
		// List data1 = new LinkedList<>();
		//
		// while (tag) {
		// int i = 0;
		// boolean tag2 = true;
		// while (tag2) {
		// if (data.size()>0) {
		// i++;
		// data1.add(data.get(0));
		// data.remove(0);
		// } else {
		// tag = false;
		// break;
		// }
		// if (i >= 5000) {
		// break;
		// }
		// }
		// addAll(data1, filename);
		// data1.clear();
		// }
		// data.clear();
		// } else {
		// saveData(data,filename);
		// }

		saveData(data, filename);

	}

	public void saveData(List data, String filename) throws Exception {
		System.out.println("saveAll:" + filename + " data:" + data.size());
		SXSSFWorkbook wb = new SXSSFWorkbook(10000);
		SXSSFSheet sheet = wb.createSheet("sheet1");
		createCell(data, sheet, 0);
		new File(new File(filename).getParent()).mkdirs();
		FileOutputStream fout = new FileOutputStream(filename);
		wb.write(fout);
		fout.close();
		wb.dispose();
		System.out.println("saveData-end" );
	}

	public void addAll(List<? extends BaseBean> data) throws Exception {
		addAll(data, data.get(0).getClass().getSimpleName());
	}

	public void addAll(List<? extends BaseBean> data, String filename) throws Exception {
		if (new File(ExcelFactory.PACTORYPATH + "/" + filename + ".xlsx").exists()
				&& new File(ExcelFactory.PACTORYPATH + "/" + filename + ".xlsx").isFile()) {
			System.out.println("addAll---");
		} else {
			saveData(new ArrayList<>(), filename);
		}
		 FileInputStream fs = new FileInputStream(ExcelFactory.PACTORYPATH +
		 "/" + filename + ".xlsx"); 
		 XSSFWorkbook wb = new XSSFWorkbook(fs);
//		 SXSSFWorkbook wb = new SXSSFWorkbook(wb1);
		 
		 XSSFSheet sheet = wb.getSheetAt(0); 
		 XSSFRow row = sheet.getRow(0); //
		
		 FileOutputStream out = new FileOutputStream(
		 ExcelFactory.PACTORYPATH + "/" + filename + ".xlsx"); //
		 createCell(data, sheet, sheet.getLastRowNum() + 1);
		 out.flush();
		 wb.write(out);
		 out.close();
		 

	}

	private void createCell(List<? extends BaseBean> data, SXSSFSheet sheet, int first) {
		SXSSFRow row;
		int i = first;
		String fname;
		String s1;
		ColumnAnnotation canno;
		String s2;
		Method m;
		boolean tag = false;
		if (data != null && data.size() > 0) {
			tag = true;
		}
		while (tag) {
			BaseBean bean = data.get(0);
			//System.out.println("createCell" + i);
			Class c = bean.getClass();
			Field[] filds = c.getDeclaredFields();
			row = sheet.createRow(i);
			i++;

			for (Field f : filds) {
				f.setAccessible(true);
				canno = f.getAnnotation(ColumnAnnotation.class);
				if (canno != null) {
					fname = "get" + f.getName().substring(0, 1).toUpperCase() + f.getName().substring(1);
					s1 = canno.value();
					try {
						m = c.getDeclaredMethod(fname, new Class[] {});
						m.setAccessible(true);
						s2 = (String) m.invoke(bean);

						char[] c1 = s1.toCharArray();
						int index = (int) c1[0] - 65;
						try {
							int index2= (int) c1[1] - 65;
							index=26+index2;
						} catch (Exception e) {
							// TODO: handle exception
						}
						//System.out.println("canno:"+s1+" index:"+index);
						row.createCell((short) index).setCellValue(s2);

					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
			data.remove(0);
			if (data.size() > 0) {
				tag = true;
			} else {
				tag = false;
			}
		}
	}
	private void createCell(List<? extends BaseBean> data, XSSFSheet sheet, int first) {
		XSSFRow row;
		int i = first;
		String fname;
		String s1;
		ColumnAnnotation canno;
		String s2;
		Method m;
		boolean tag = false;
		if (data != null && data.size() > 0) {
			tag = true;
		}
		while (tag) {
			BaseBean bean = data.get(0);
			System.out.println("createCell" + i);
			Class c = bean.getClass();
			Field[] filds = c.getDeclaredFields();
			row = sheet.createRow(i);
			i++;

			for (Field f : filds) {
				f.setAccessible(true);
				canno = f.getAnnotation(ColumnAnnotation.class);
				if (canno != null) {
					fname = "get" + f.getName().substring(0, 1).toUpperCase() + f.getName().substring(1);
					s1 = canno.value();
					try {
						m = c.getDeclaredMethod(fname, new Class[] {});
						m.setAccessible(true);
						s2 = (String) m.invoke(bean);

						char[] c1 = s1.toCharArray();
						int index = (int) c1[0] - 65;
						try {
							int index2= (int) c1[1] - 65;
							index=26+index2;
						} catch (Exception e) {
							// TODO: handle exception
						}
						System.out.println("canno:"+s1+" index:"+index);
						row.createCell((short) index).setCellValue(s2);

					} catch (Exception e) {
						e.printStackTrace();
					}
				
				}
			}
			data.remove(0);
			if (data.size() > 0) {
				tag = true;
			} else {
				tag = false;
			}
		}
	}

	public void deleteByIndex(int index, Class cls) {
		try {

			FileInputStream is = new FileInputStream(ExcelFactory.PACTORYPATH + "/" + cls.getSimpleName() + ".xlsx");

			XSSFWorkbook workbook = new XSSFWorkbook(is);

			XSSFSheet sheet = workbook.getSheetAt(0);

			removeRow(sheet, index);
			FileOutputStream os = new FileOutputStream(ExcelFactory.PACTORYPATH + "/" + cls.getSimpleName() + ".xlsx");

			workbook.write(os);

			is.close();

			os.close();

		} catch (Exception e) {

			e.printStackTrace();
		}
	}

	public void removeRow(XSSFSheet sheet, int rowIndex) {
		int lastRowNum = sheet.getLastRowNum();
		if (rowIndex >= 0 && rowIndex < lastRowNum)
			sheet.shiftRows(rowIndex + 1, lastRowNum, -1);
		if (rowIndex == lastRowNum) {
			XSSFRow removingRow = sheet.getRow(rowIndex);
			if (removingRow != null)
				sheet.removeRow(removingRow);
		}
	}
}
