package com.zjrs.appcomm.template.excel.builder;

import com.zjrs.appcomm.template.excel.mapper.*;
import com.zjrs.appcomm.template.excel.util.ExcelUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

public class ImportBuilder<D, L> {
	
	private ImportDefinition<D, L> importDefinition;
	public ImportBuilder(Class<D> discreteClass, Class<L> listClass) {
		this.importDefinition = new ImportDefinition<>(discreteClass, listClass);
		this.importDefinition.setHeaderRowIndex(0);
		this.importDefinition.setHeaderRowCount(1);
		this.importDefinition.setDataRowIndex(1);
		this.importDefinition.setCalculateMergedCell(false);
	}
	
	public ImportDefinition<D, L> build() {
		return importDefinition;
	}
	
	/* Excel中Sheet */
	public ImportBuilder<D, L> sheet(Sheet sheet) {
		importDefinition.setSheet(sheet);
		return this;
	}
	public ImportBuilder<D, L> sheet(Workbook workbook, String sheetName) {
		Sheet sheet = ExcelUtils.getSheet(workbook, sheetName, false);
		return sheet(sheet);
	}
	public ImportBuilder<D, L> sheet(InputStream is, String sheetName) throws IOException, InvalidFormatException {
		Workbook workbook = WorkbookFactory.create(is);
		return sheet(workbook, sheetName);
	}
	public ImportBuilder<D, L> sheet(byte[] content, String sheetName) throws IOException, InvalidFormatException {
		try (InputStream is = new ByteArrayInputStream(content)) {
			return sheet(is, sheetName);
		}
	}
	
	/* 离散数据坐标 */
	public ImportBuilder<D, L> discreteFieldCoordinates(Map<String, SheetCoordinate> discreteFieldCoordinates) {
		importDefinition.setDiscreteFieldCoordinates(discreteFieldCoordinates);
		return this;
	}
	public ImportBuilder<D, L> putDiscreteFieldCoordinate(String fieldName, SheetCoordinate discreteFieldCoordinate) {
		if (importDefinition.getDiscreteFieldCoordinates() == null) {
			importDefinition.setDiscreteFieldCoordinates(new HashMap<>());
		}
		importDefinition.getDiscreteFieldCoordinates().put(fieldName, discreteFieldCoordinate);
		return this;
	}
	public ImportBuilder<D, L> putDiscreteFieldCoordinate(String fieldName, int row, int col) {
		putDiscreteFieldCoordinate(fieldName, new SheetCoordinate(row, col));
		return this;
	}
	public ImportBuilder<D, L> putDiscreteFieldCoordinate(String fieldName, int row, int col, CellStyler styler) {
		putDiscreteFieldCoordinate(fieldName, new SheetCoordinate(row, col, styler));
		return this;
	}
	
	/* 处理离散数据的Mapper */
	public ImportBuilder<D, L> discreteMapper(DiscreteMapper<D> discreteMapper) {
		importDefinition.setDiscreteMapper(discreteMapper);
		return this;
	}
	
	/* 导入数据的表头所在行下标（比如第一行就是表头，则传入0） */
	public ImportBuilder<D, L> headerRowIndex(int headerRowIndex) {
		importDefinition.setHeaderRowIndex(headerRowIndex);
		return this;
	}
	
	/* 导入数据的表头一共有几行（比如只有一行表头，则传入1，若是两行构成的多行表头，则传入2） */
	public ImportBuilder<D, L> headerRowCount(int headerRowCount) {
		importDefinition.setHeaderRowCount(headerRowCount);
		return this;
	}
	
	/* 定义表头转换用的映射（主要针对动态表头而使用，对于静态表头可以直接传入固定值）（一般静态表头可使用StaticHeaderMapper、一般动态表头可使用DynamicHeaderMapper） */
	public ImportBuilder<D, L> headerMapper(HeaderMapper headerMapper) {
		importDefinition.setHeaderMapper(headerMapper);
		return this;
	}
	
	/* 是否进行合并单元格修正 */
	public ImportBuilder<D, L> calculateMergedCell(boolean calculateMergedCell) {
		importDefinition.setCalculateMergedCell(calculateMergedCell);
		return this;
	}
	
	/* 需要导入的数据所在行的起始下标（比如第二行就是数据，则传入1） */
	public ImportBuilder<D, L> dataRowIndex(int dataRowIndex) {
		importDefinition.setDataRowIndex(dataRowIndex);
		return this;
	}
	
	/* 行数据过滤器 */
	public ImportBuilder<D, L> listFilter(RowJudge listFilter) {
		importDefinition.setListFilter(listFilter);
		return this;
	}
	
	/* 行数据终止器 */
	public ImportBuilder<D, L> listfinishedJudge(RowJudge listfinishedJudge) {
		importDefinition.setListfinishedJudge(listfinishedJudge);
		return this;
	}
	
	/* 处理每行数据的Mapper */
	public ImportBuilder<D, L> rowMapper(RowMapper<L> rowMapper) {
		importDefinition.setRowMapper(rowMapper);
		return this;
	}
}
