package com.yeejoin.equipmanage.service.impl;

import com.yeejoin.equipmanage.common.entity.*;
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.*;
import com.yeejoin.equipmanage.service.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
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("iEquipmentPointUpload")
@Transactional
public class EquipmentPointUpload implements IEquipmentPointUpload {

    @Autowired
    private EquipmentMapper equipmentMapper;



    @Autowired
    private ISystemDicService iSystemDicService;
    @Autowired
    private UnitMapper unitMapper;

    @Autowired
    private IEquipmentCategoryService iCategoryService;

    @Autowired
    private IEquipmentPointService iPointService;

    @Autowired
    private GenerateEquipmentCode generateEquipmentCode;

    private List<SystemDic> dicList = new ArrayList<>();
    private List<Equipment> equipmentList = new ArrayList<>();
    private List<Unit> unitList = new ArrayList<>();
    private List<EquipmentPoint> equipmentPointsList = new ArrayList<>();
    private List<EquipmentCategory> categoryList = new ArrayList<>();

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

        categoryList = iCategoryService.list();
        equipmentPointsList = iPointService.list();
        dicList = iSystemDicService.findAllByType("EquipmentSwitch");
        equipmentList = equipmentMapper.selectList(null);
        unitList = unitMapper.selectList(null);

        Sheet activeSheet = book.getSheetAt(0);

        // 判断消防点位名称是否有重复数据
        duplicateCellCheck(activeSheet, 0, 1);

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

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

            List<EquipmentPoint> 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 (str[z] == "") {
                                throw new UploadException("请使用正确的模板！");
                            }
                        }
                    }
                }
                //
                else {

                    EquipmentPoint point = new EquipmentPoint();
                    for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {

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

                    }
                    list.add(point);
                    equipmentPointsList.add(point);
                }

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

    public void ObtainEquipment(EquipmentPoint point, 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("数据类型") && !str[j].equals("单位") && !str[j].equals("装备名称")) {
            throw new UploadException("请使用正确的模板！");
        }
        if (str[j].equals("编号")) {
            if (!StringUtil.isNotEmpty(cellstr)) {
                throw new UploadException("编号不能为空！");
            }
            // 消防点位已存在，抛出异常
            if (equipmentPointsList.stream().anyMatch(e -> e.getCode().equals(cellstr))) {
                throw new UploadException("编号【" + cellstr + "】已存在！");
            }
            point.setCode(cellstr);
        }

        if (str[j].equals("名称")) {
            if (!StringUtil.isNotEmpty(cellstr)) {
                throw new UploadException("名称不能为空！");
            }
            // 消防点位已存在，抛出异常
            if (equipmentPointsList.stream().noneMatch(c -> c.getName().equals(cellstr))) {
                throw new UploadException("消防点名称【" + cellstr + "】已存在！");
            }
//            EquipmentCategory category = ArrayUtil.any(dicList, c -> c.getName().equals(cellstr));
//            equipment.setCategoryId(category.getId());
            point.setName(cellstr);
        }

        if (str[j].equals("数据类型")) {
            if (!StringUtil.isNotEmpty(cellstr)) {
                throw new UploadException("数据类型不能为空！");
            }
            // 数据类型不存在，抛出异常
            if ("开关量".equals(cellstr) || "模拟量".equals(cellstr)) {
                if("开关量".equals(cellstr)){
                    point.setType("SWITCH");
                } else {
                    point.setType("ANALOGUE");
                }
            } else {
                throw new UploadException("数据类型【" + cellstr + "】输入有误！");
            }
        }

        if (str[j].equals("装备编号") && StringUtil.isNotEmpty(cellstr)) {
            Equipment equipment1 = equipmentList.stream().filter(i -> i.getCode().equals(cellstr)).findAny().get();
            point.setEquipmentId(equipment1.getId());
            point.setEquipmentCode(equipment1.getCode());
            point.setEquipmentName(equipment1.getName());
            EquipmentCategory category = categoryList.stream().filter(i -> i.getId().equals(equipment1.getCategoryId())).findAny().get();
            point.setEquipmentClass(category.getId()+"");
        }

        if (str[j].equals("单位") && StringUtil.isNotEmpty(cellstr)) {
            Unit unit = unitList.stream().filter(i -> i.getName().equals(cellstr)).findAny().get();
            point.setUnit(unit.getId());
            point.setUnitName(unit.getName());
        }

        if (str[j].equals("指标类型") && StringUtil.isNotEmpty(cellstr)) {
            SystemDic dic = dicList.stream().filter(i -> i.getName().equals(cellstr)).findAny().get();
            point.setAlarmType(dic.getId());
            point.setAlarmName(dic.getName());
        }

    }

    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 EquipmentPointSaveThread(List<EquipmentPoint> list) {

        int number = list.size();
        List<EquipmentPoint> point = null;

        List<EquipmentPoint> list1 = null;
        EquipmentPoint 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 (EquipmentPoint 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 (EquipmentPoint 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;
            }
        }

        new Thread(() -> {

            try {
                if (list.size() > 0) {
                    for (EquipmentPoint equipment1 : list) {
//                        equipmentMapper.insert(equipment1);
                    }

                }

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                throw new RuntimeException("添加失败");
            }

        }).start();
        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;
    }
}
