package cn.superdesk.uniorder.common.excel.strategy.postil;

import cn.hutool.core.util.StrUtil;
import cn.superdesk.uniorder.common.mq.redis.service.RedisService;
import cn.superdesk.uniorder.common.excel.model.ExcelRow;
import cn.superdesk.uniorder.common.excel.validate.annotion.RelationIsEntry;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.common.spring.SpringContextHolder;
import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.write.handler.AbstractSheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddressList;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description: Java类作用描述
 * @Author: linjinyu
 * @CreateDate: 2021/8/30 下午5:31
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021/8/30 下午5:31
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Builder(toBuilder = true)
@NoArgsConstructor
public class ExcelImportExportAddPostilSheetWriteHandler<T extends ExcelRow> extends AbstractSheetWriteHandler {

	private Class<T> headClazz;
	private T        instance;


	// Declared fields
	// private Field[]  fields; // 弃用
	private Map<Integer, Field>  sortedAllFiledMap;
	private Map<Integer, Field>  indexFiledMap;
	private Map<String, Integer> filedIndexMap;

	/**
	 * Fields ignored
	 */
	private Map<String, Field> ignoreMap;

	private Boolean convertAllFiled;
	private Boolean needIgnore;

	private String batchId;

	/**
	 *
	 */
	private RedisService redisService;

	private LoginSysUser loginSysUser;

	public ExcelImportExportAddPostilSheetWriteHandler(Class<T> headClazz,
	                                                   T instance,
	                                                   Map<Integer, Field> sortedAllFiledMap,
	                                                   Map<Integer, Field> indexFiledMap,
	                                                   Map<String, Integer> filedIndexMap,
	                                                   Map<String, Field> ignoreMap,
	                                                   Boolean convertAllFiled,
	                                                   Boolean needIgnore,
	                                                   String batchId,
	                                                   RedisService redisService,
	                                                   LoginSysUser loginSysUser) {

		this.headClazz = headClazz;
		this.instance = instance;

		this.sortedAllFiledMap = sortedAllFiledMap;
		this.indexFiledMap = indexFiledMap;
		this.filedIndexMap = filedIndexMap;
//		this.sortedAllFiledMap = new TreeMap<Integer, Field>();
//		this.indexFiledMap = new TreeMap<Integer, Field>();
//		this.filedIndexMap = new HashMap<>();

//		this.ignoreMap = ignoreMap;
		this.ignoreMap = new HashMap<String, Field>(16);

		this.convertAllFiled = convertAllFiled;
		this.needIgnore = needIgnore;
//		this.convertAllFiled = false;
//		this.needIgnore = false;

		this.batchId = batchId;

//		this.redisService = redisService;
		this.redisService = SpringContextHolder.getBean(RedisService.class);
//		this.redisService.setDatabase(2);

		this.loginSysUser = loginSysUser;

		ClassUtils.declaredFields(headClazz, sortedAllFiledMap, indexFiledMap, ignoreMap, convertAllFiled, needIgnore, null);

		log.info("ExcelImportExportAddPostilRowWriteHandler\n{}\n{}", AnJsonUtils.toJson(sortedAllFiledMap), AnJsonUtils.toJson(indexFiledMap));

		for (Map.Entry<Integer, Field> entry : sortedAllFiledMap.entrySet()) {
			filedIndexMap.put(sortedAllFiledMap.get(entry.getKey()).getName(), entry.getKey());
		}
	}

	@Override
	public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

	}

	@Override
	public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

//		String[] ageArray = new String[ageList.size()];
//		for (int i = 0; i < ageList.size(); i++) {
//			ageArray[i] = ageList.get(i).getAge().toString();
//		}

		Map<Integer, String[]> mapDropDown = new HashMap<>();


		for (Map.Entry<Integer, Field> entry : indexFiledMap.entrySet()) {

			Field field = entry.getValue();

			RelationIsEntry relationIsEntry = field.getAnnotation(RelationIsEntry.class);

			if (null != relationIsEntry) {
				log.info("\nindex\n{}\nfield\n{}\nannotation\n{}", entry.getKey(), AnJsonUtils.toJson(entry.getValue()),
						StrUtil.format("isSuggest({}),cachePrefix({}),cacheKey({}),message({})", relationIsEntry.isSuggest(), relationIsEntry.cachePrefix(), relationIsEntry.cacheKey(), relationIsEntry.message()));

				mapDropDown.put(entry.getKey(), redisService.haskKeys(relationIsEntry.cachePrefix() + ":" + relationIsEntry.cacheKey()));
			}
		}

		Sheet sheet = writeSheetHolder.getSheet();
		// 开始设置下拉框
		DataValidationHelper helper = sheet.getDataValidationHelper();
		// 设置下拉框
		for (Map.Entry<Integer, String[]> entry : mapDropDown.entrySet()) {
			// 起始行、终止行、起始列、终止列
			CellRangeAddressList addressList = new CellRangeAddressList(1, 65535, entry.getKey(), entry.getKey());
			// 设置下拉框数据
			DataValidationConstraint constraint     = helper.createExplicitListConstraint(entry.getValue());
			DataValidation           dataValidation = helper.createValidation(constraint, addressList);
			sheet.addValidationData(dataValidation);
		}
	}
}
