package com.yeejoin.equipmanage.service.impl;

import com.yeejoin.equipmanage.common.entity.Equipment;
import com.yeejoin.equipmanage.common.entity.EquipmentCategory;
import com.yeejoin.equipmanage.common.entity.Unit;
import com.yeejoin.equipmanage.common.utils.ArrayUtil;
import com.yeejoin.equipmanage.common.utils.DateUtils;
import com.yeejoin.equipmanage.common.utils.StringUtil;
import com.yeejoin.equipmanage.common.utils.UploadException;
import com.yeejoin.equipmanage.common.vo.EquipmentForm;
import com.yeejoin.equipmanage.mapper.EquipmentCategoryMapper;
import com.yeejoin.equipmanage.mapper.EquipmentMapper;
import com.yeejoin.equipmanage.mapper.UnitMapper;
import com.yeejoin.equipmanage.service.IEquipmentDefUpload;
import com.yeejoin.equipmanage.service.IEquipmentService;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("iEquipmentDefUpload")
@Transactional
public class EquipmentDefUpload implements IEquipmentDefUpload {

	@Autowired
	private EquipmentMapper equipmentMapper;
	@Lazy
	@Autowired
	private IEquipmentService equipmentService;

	@Autowired
	private EquipmentCategoryMapper equipmentCategoryMapper;

	@Autowired
	private UnitMapper unitMapper;

	@Autowired
	private GenerateEquipmentCode generateEquipmentCode;
	private List<EquipmentCategory> equipmentCategoryList = new ArrayList<>();
	private List<Equipment> equipmentList = new ArrayList<>();
	private List<Unit> unitList = new ArrayList<>();

	@Override
	public long importFile(Workbook book) throws UploadException {

		equipmentCategoryList = equipmentCategoryMapper.selectList(null);
		equipmentList = equipmentMapper.selectList(null);
		unitList = unitMapper.selectList(null);

		Sheet activeSheet = book.getSheetAt(0);

		// 判断计量装备名称是否有重复数据
		duplicateCellCheck(activeSheet, 0, 1);

		Row rowOne = activeSheet.getRow(activeSheet.getFirstRowNum());
		if (rowOne == null) {
			throw new UploadException("请使用正确的模板！");
		} else {

			String[] str = new String[rowOne.getLastCellNum()];

			List<Equipment> list = new ArrayList<>();
			for (int i = activeSheet.getFirstRowNum(); i <= activeSheet.getLastRowNum(); i++) {

				Row row = activeSheet.getRow(i);
				// 取第一列的标题头
				if (i == activeSheet.getFirstRowNum()) {

					for (int z = rowOne.getFirstCellNum(); z < rowOne.getLastCellNum(); z++) {
						if (rowOne.getCell(z) != null) {
							str[z] = rowOne.getCell(z).getStringCellValue();
							if (  "".equals(str[z])) {
								throw new UploadException("请使用正确的模板！");
							}
						}
					}
				}
				//
				else {

					Equipment equipment = new Equipment();
					for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {

						if (j < rowOne.getLastCellNum()) {
							ObtainEquipment(equipment, str, row, j);
						}

					}
					EquipmentCategory category = equipmentCategoryMapper.selectById(equipment.getCategoryId());

					if (category != null) {

						String code = generateEquipmentCode.generateEquipCode(equipment.getCategoryId());
						equipment.setCode(code);
					}

					list.add(equipment);
					equipmentList.add(equipment);
				}

			}
			Long count = EquipmentSaveThread(list);
			return count;
		}
	}

	public void ObtainEquipment(Equipment equipment, String[] str, Row row, int j) throws UploadException {
		if (row.getCell(j) != null) {
			row.getCell(j).setCellType(CellType.STRING);
		}

		final String cellstr = row.getCell(j) == null ? "" : row.getCell(j).getStringCellValue();
		if (!str[j].equals("装备名称") && !str[j].equals("装备分类") && !str[j].equals("计量单位") && !str[j].equals("备注")) {
			throw new UploadException("请使用正确的模板！");
		}
		if (str[j].equals("装备名称")) {
			if (!StringUtil.isNotEmpty(cellstr)) {
				throw new UploadException("装备名称不能为空！");
			}
			// 装备名称已存在，抛出异常
			if (equipmentList.stream().anyMatch(e -> e.getName().equals(cellstr))) {
				throw new UploadException("装备名称【" + cellstr + "】已存在！");
			}
			equipment.setName(cellstr);
		}

		if (str[j].equals("装备分类")) {
			if (!StringUtil.isNotEmpty(cellstr)) {
				throw new UploadException("装备分类不能为空！");
			}
			// 装备分类不存在，抛出异常
			if (equipmentCategoryList.stream().noneMatch(c -> c.getName().equals(cellstr))) {
				throw new UploadException("装备分类【" + cellstr + "】不存在！");
			}
			EquipmentCategory category = ArrayUtil.any(equipmentCategoryList, c -> c.getName().equals(cellstr));
			equipment.setCategoryId(category.getId());
		}

		if (str[j].equals("计量单位")) {
			if (!StringUtil.isNotEmpty(cellstr)) {
				throw new UploadException("计量单位不能为空！");
			}
			// 计量单位名称不存在，抛出异常
			if (unitList.stream().noneMatch(u -> u.getName().equals(cellstr))) {
				throw new UploadException("计量单位【" + cellstr + "】不存在！");
			}
			Unit unit = unitList.stream().filter(c -> c.getName().equals(cellstr)).findAny().get();
			equipment.setUnitId(unit.getId());
		}

		if (str[j].equals("备注") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setRemark(cellstr);
		}

	}

	public void mergeEquipment(Equipment equipment, String[] str, Row row, int j) {
		if (row.getCell(j) != null) {
			row.getCell(j).setCellType(CellType.STRING);
		}

		String cellstr = null;
		if (StringUtil.isNotEmpty(row.getCell(j))) {
			cellstr = row.getCell(j).getStringCellValue();
		}

		setValue(equipment, str[j], cellstr);

		if (str[j].equals("categoryId") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setCategoryId(Long.valueOf(cellstr));
		}

		if (str[j].equals("checkCycle") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setCheckCycle(Short.valueOf(cellstr));
		}

		if (str[j].equals("code") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setCode(cellstr);
		}

		if (str[j].equals("country") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setCountry(cellstr);
		}

		if (str[j].equals("createrId") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setCreaterId(Long.valueOf(cellstr));
		}

		if (str[j].equals("CreateDate") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setCreateDate(DateUtils.longStr2Date(cellstr));
		}

		if (str[j].equals("dateUpdated") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setDateUpdated(DateUtils.longStr2Date(cellstr));
		}

		if (str[j].equals("id") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setId(Long.valueOf(cellstr));
		}

		if (str[j].equals("img") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setImg(cellstr);
		}

		if (str[j].equals("madeIn") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setMadeIn(cellstr);
		}

		if (str[j].equals("maintenanceCycle") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setMaintenanceCycle(Short.valueOf(cellstr));
		}

		if (str[j].equals("managementStyle") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setManagementStyle(Long.valueOf(cellstr));
		}

		if (str[j].equals("manufacturer") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setManufacturer(cellstr);
		}

		if (str[j].equals("markSpecification") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setMarkSpecification(cellstr);
		}

		if (str[j].equals("name") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setName(cellstr);
		}

		if (str[j].equals("remark") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setRemark(cellstr);
		}
		if (str[j].equals("reviserId") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setReviserId(Long.valueOf(cellstr));
		}

		if (str[j].equals("supplierId") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setSupplierId(Long.valueOf(cellstr));
		}

		if (str[j].equals("unitId") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setUnitId(Long.valueOf(cellstr));
		}

		if (str[j].equals("video") && StringUtil.isNotEmpty(cellstr)) {
			equipment.setVideo(cellstr);
		}

	}

	private void setValue(Equipment equipment, String field, String value) throws RuntimeException {
		try {
			Field equipmentField = Equipment.class.getDeclaredField(field);
			String firstLetter = equipmentField.getName().substring(0, 1).toUpperCase();
			String setter = "set" + firstLetter + equipmentField.getName().substring(1);
			Method method = equipment.getClass().getMethod(setter, equipmentField.getType());
			method.invoke(equipment, getValue(equipmentField.getType(), value));
		} catch (NoSuchFieldException e) {
			// TODO: handle exception
		} catch (NoSuchMethodException e) {
			// TODO: handle exception
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	private Object getValue(Class<?> clasz, Object value) {
		switch (clasz.getSimpleName()) {
		case "Double":
			return Double.valueOf(value.toString());
		case "Integer":
			return Integer.valueOf(value.toString());
		case "Long":
			return Long.valueOf(value.toString());
		case "Short":
			return Short.valueOf(value.toString());
		default:
			return value.toString();
		}
	}

	public Long EquipmentSaveThread(List<Equipment> list) {

		int number = list.size();
		List<Equipment> equipment = null;

		List<Equipment> list1 = null;
		Equipment equ = null;
		List<EquipmentForm> listt = new ArrayList<>();
		Map<String, Object> columnMap1 = new HashMap<String, Object>();

		for (int i = 0; i < list.size(); i++) {
			list1 = new ArrayList<>();
			if (StringUtil.isNotEmpty(list.get(i))) {
				columnMap1.clear();
				columnMap1.put("name", list.get(i).getName());
				columnMap1.put("code", list.get(i).getCode());
				list1 = equipmentMapper.selectByMap(columnMap1);

			}

			EquipmentForm ef = null;
			if (list1.size() != 0) {

				ef = new EquipmentForm();
				ef.setName(list1.get(0).getName());
				ef.setCode(list1.get(0).getCode());
				listt.add(ef);

			}

		}

		for (int i = 0; i < listt.size(); i++) {

			for (Equipment equipmentList : list) {

				if (listt.get(i).getName().equals(equipmentList.getName())
						|| !StringUtil.isNotEmpty(equipmentList.getName())) {
					list.remove(equipmentList);
					break;
				}

			}

		}
		Map<String, Object> columnMap = new HashMap<String, Object>();
		for (Equipment equipmentList : list) {

			columnMap.clear();
			columnMap.put("code", equipmentList.getCode());
			List<Equipment> equipments = equipmentMapper.selectByMap(columnMap);

			if (!StringUtil.isNotEmpty(equipmentList.getId()) && equipments.size() > 0) {
				list.remove(equipmentList);
				break;
			}
		}

		Boolean b = equipmentService.saveBatch(list);
		if(!b){
			throw new RuntimeException("批量导入失败");
		}
		return (long) list.size();
	}

	/**
	 * 下载上传文件模版
	 */
	@Override
	public Workbook downloadImportFile() {
		// 导出xls格式的excel
		Workbook wb = new HSSFWorkbook();

		// 创建一个SHEET
		Sheet sheet = wb.createSheet("装备定义");
		// 设置列的格式为文本格式
		CellStyle style = wb.createCellStyle();
		DataFormat format = wb.createDataFormat();
		style.setDataFormat(format.getFormat("@"));

		// 设置表头要显示的内容
		String[] title = { "装备名称", "装备分类", "计量单位", "备注" };
		int i = 0;

		// 创建一行
		Row row = sheet.createRow((short) 0);
		// 填充标题.将标题放入第一行各列
		for (String s : title) {
			Cell cell = row.createCell(i);
			cell.setCellValue(s);
			sheet.setDefaultColumnStyle(i, style);
			sheet.setColumnWidth(i, s.getBytes().length * 256);
			i++;
		}
		return wb;
	}
}
