package com.css.simulation.resource.server.app.service;


import api.common.pojo.constants.DictConstants;
import api.common.pojo.constants.LogConstants;
import api.common.pojo.param.scene.SceneDeleteParam;
import api.common.pojo.param.scene.SceneGeneralTemplateParam;
import api.common.pojo.po.scene.SceneGeneralTemplatePO;
import api.common.pojo.po.scene.ScenePackagePO;
import api.common.pojo.po.scene.ScenePackageSublistPO;
import api.common.pojo.po.scene.SystemScenePackageSublistPO;
import api.common.pojo.po.system.SceneImportPO;
import api.common.pojo.vo.scene.SceneGeneralTemplateMbVO;
import api.common.pojo.vo.scene.SceneGeneralTemplateVO;
import api.common.util.*;
import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneGeneralTemplateMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.ScenePackageMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.ScenePackageSublistMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.SystemScenePackageSublistMapper;
import com.css.simulation.resource.server.infra.util.AuthUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

@Slf4j
@Service
public class SceneGeneralTemplateService {

    @Resource
    SceneGeneralTemplateMapper mapper;
    @Resource
    SystemScenePackageSublistMapper systemScenePackageSublistMapper;
    @Resource
    ScenePackageSublistMapper scenePackageSublistMapper;
    @Resource
    ScenePackageMapper scenePackageMapper;
    @Resource
    DictService dictService;
    @Resource
    LogService logService;

    /**
     * 泛化模板导入：
     */
    public void saveSceneGeneralTemplate(File excelFile, String version) {
        try {
            FileInputStream is = new FileInputStream(excelFile);    //文件流
            Workbook workbook = WorkbookFactory.create(is);         //这种方式 Excel 2003/2007/2010 都是可以处理的
            int sheetCount = workbook.getNumberOfSheets();          //Sheet的数量
            List<SceneGeneralTemplatePO> list = new ArrayList<>();
            List<String> fileNameAll = new ArrayList<>();
            //遍历每个Sheet
            for (int s = 0; s < sheetCount; s++) {
                Sheet sheet = workbook.getSheetAt(s);
                String sheetName = sheet.getSheetName();  //文件Sheet的名称
                //验证模板名称是否正确  filrName为字典中的类别名
           /* Map<String, String> map = dictService.getDictMapByType("fileName");
            String fileName = map.get(sheetName);
            if (ObjectUtil.isNotNull(fileName)) {*/
                int rowCount = sheet.getPhysicalNumberOfRows(); //获取总行数
                // 效验sheet页是否符合标准
                Cell ce00 = sheet.getRow(0).getCell(0);
                String c00Value = ce00.getStringCellValue();
                if (c00Value != null && c00Value.equals("场景编号")) {
                    //遍历每一行
                    for (int r = 1; r < rowCount; r++) {
                        Row row = sheet.getRow(r);
                        int cellCount = row.getPhysicalNumberOfCells(); //获取总列数
                        SceneGeneralTemplatePO po = new SceneGeneralTemplatePO();
                        Field[] field = po.getClass().getDeclaredFields();
                        //遍历每一个单元格
                        for (int c = 0; c < cellCount; c++) {
                            int a = c + 1;
                            Cell cell = row.getCell(c);
                            String cellValue = null;
                            if (r > 0 && c == 3) {
                                Date aaa = cell.getDateCellValue();
                                cellValue = TimeUtil.getToStringDate(aaa, 4);
                            } else if (cell != null) {
                                //在读取单元格内容前,设置所有单元格中内容都是字符串类型
                                cell.setCellType(CellType.STRING);
                                //按照字符串类型读取单元格内数据
                                cellValue = cell.getStringCellValue();
                            }
                            /*在这里可以对每个单元格中的值进行二次操作转化*/
                            //    System.out.print(cellValue + "    ");
                            if (r > 0) {
                                //获取属性的名字
                                String name = field[a].getName();
                                //将属性名的第一位字母大写
                                name = name.substring(0, 1).toUpperCase() + name.substring(1);
                                //调用setter方法设属性值
                                Class[] parameterTypes = new Class[1];
                                parameterTypes[0] = field[a].getType();
                                Method getOrSet = po.getClass().getDeclaredMethod("set" + name, parameterTypes);
                                getOrSet.invoke(po, cellValue);

                                if ("BSD".equals(sheetName) && "BSD_3-3".equals(cellValue)) {
                                    System.out.println(
                                            "111"
                                    );
                                }
                                System.out.println(name + "---测试--" + sheetName + "---" + cellValue);
                            }
                        }
                        System.out.println("--------999-----------");
                        if (r > 0) {
                            po.setCreateTime(TimeUtil.getNowForMysql());
                            po.setCreateUserId(AuthUtil.getCurrentUserId());
                            po.setModifyUserId(AuthUtil.getCurrentUserId());
                            po.setModifyTime(TimeUtil.getNowForMysql());
                            po.setIsDeleted("0");
                            po.setId(StringUtil.getRandomUUID());
                            po.setFileName(sheetName);
                            po.setVersion(version);
                            fileNameAll.add(sheetName);
                            list.add(po);
                        }
                    }
                }
                //}
            }
            System.out.println("--------888---------");
            if (ObjectUtil.isNotNull(list)) {
                SceneGeneralTemplatePO po = list.get(0);
                po.setFileNameAll(fileNameAll);
                mapper.deleteSceneGeneralTemplateAll(po);
                mapper.saveSceneGeneralTemplateAll(list);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 泛化模板导入：
     */
    public SceneImportPO saveSceneGeneralTemplateNew(File excelFile, String version, SceneImportPO sceneImportPO) {
        try {
            FileInputStream is = new FileInputStream(excelFile);    //文件流
            Workbook workbook = WorkbookFactory.create(is);         //这种方式 Excel 2003/2007/2010 都是可以处理的
            int sheetCount = workbook.getNumberOfSheets();          //Sheet的数量
            List<SceneGeneralTemplatePO> list = new ArrayList<>();
            List<String> fileNameAll = new ArrayList<>();
            //遍历每个Sheet
            List<String> sceneNames = new ArrayList<>();
            for (int s = 0; s < sheetCount; s++) {
                Sheet sheet = workbook.getSheetAt(s);
                String sheetName = sheet.getSheetName();  //文件Sheet的名称
                //验证模板名称是否正确  filrName为字典中的类别名
           /* Map<String, String> map = dictService.getDictMapByType("fileName");
            String fileName = map.get(sheetName);
            if (ObjectUtil.isNotNull(fileName)) {*/
                int rowCount = sheet.getPhysicalNumberOfRows(); //获取总行数
                //效验sheet页是否符合标准
                Cell ce00 = sheet.getRow(0).getCell(0);
                //ce00.setCellType(CellType.STRING);
                String c00Value = ce00.getStringCellValue();
                if (c00Value != null && c00Value.equals("场景编号")) {
                    //遍历每一行
                    for (int r = 1; r < rowCount; r++) {
                        Row row = sheet.getRow(r);
                        int cellCount = row.getPhysicalNumberOfCells(); //获取总列数
                        SceneGeneralTemplatePO po = new SceneGeneralTemplatePO();
                        Field[] field = po.getClass().getDeclaredFields();
                        //遍历每一个单元格
                        for (int c = 0; c < cellCount; c++) {
                            int a = c + 1;
                            Cell cell = row.getCell(c);
                            String cellValue = null;
                            if (c == 3) {
                                Date aaa = cell.getDateCellValue();
                                cellValue = TimeUtil.getToStringDate(aaa, 4);
                            } else if (cell != null) {
                                //在读取单元格内容前,设置所有单元格中内容都是字符串类型
                                cell.setCellType(CellType.STRING);
                                //按照字符串类型读取单元格内数据
                                cellValue = cell.getStringCellValue();
                            }
                            /*在这里可以对每个单元格中的值进行二次操作转化*/
                            //    System.out.print(cellValue + "    ");
                            //获取属性的名字
                            String name = field[a].getName();
                            //将属性名的第一位字母大写
                            name = name.substring(0, 1).toUpperCase() + name.substring(1);
                            //调用setter方法设属性值
                            Class<?>[] parameterTypes = new Class[1];
                            parameterTypes[0] = field[a].getType();
                            Method getOrSet = po.getClass().getDeclaredMethod("set" + name, parameterTypes);
                            getOrSet.invoke(po, cellValue);
                        }
                        System.out.println();
                        po.setCreateTime(TimeUtil.getNowForMysql());
                        po.setCreateUserId(AuthUtil.getCurrentUserId());
                        po.setModifyUserId(AuthUtil.getCurrentUserId());
                        po.setModifyTime(TimeUtil.getNowForMysql());
                        po.setIsDeleted("0");
                        po.setShare("0");
                        po.setId(StringUtil.getRandomUUID());
                        po.setFileName(sheetName);
                        po.setVersion(version);
                        fileNameAll.add(sheetName);
                        sceneNames.add(po.getSceneId());
                        list.add(po);
                    }
                }
                //}
            }
            if (ObjectUtil.isNotNull(list)) {
                SceneGeneralTemplatePO po = list.get(0);
                po.setFileNameAll(fileNameAll);
                mapper.deleteSceneGeneralTemplateAll(po);
                mapper.saveSceneGeneralTemplateAll(list);
                sceneImportPO.setStatus(DictConstants.SCENE_IMPORT_STATUS_4);
                sceneImportPO.setSuccessNum(list.size());
                sceneImportPO.setSceneNames(CollectionUtil.listToSequence(sceneNames));
                return sceneImportPO;
            }
            sceneImportPO.setStatus(DictConstants.SCENE_IMPORT_STATUS_2);
            return sceneImportPO;
        } catch (Exception e) {
            sceneImportPO.setErrorMessage("该文件解析失败，请检查");
            sceneImportPO.setStatus(DictConstants.SCENE_IMPORT_STATUS_2);
            return sceneImportPO;
        }
    }


    public List<SceneGeneralTemplatePO> querySceneGeneralTemplateList(SceneGeneralTemplateParam po) {
        List<SceneGeneralTemplatePO> list = new ArrayList<>();
        //添加权限
        String roleCode = AuthUtil.getCurrentUserRoleCode();
        log.info("泛华------" + roleCode);
        String userId = AuthUtil.getCurrentUserId();
        if (DictConstants.ROLE_CODE_ADMIN.equals(roleCode) || DictConstants.ROLE_CODE_SYSADMIN.equals(roleCode)) { //管理员账户
            list = mapper.querySceneGeneralTemplateList(po);
            log.info("泛华----list--" + list.size() + "----------" + po);
        } else if (DictConstants.ROLE_CODE_SUBUESR.equals(roleCode)) {
            //查询父账户
            userId = AuthUtil.getCreateUserId();
            po.setUserId(userId);
            if (po.getShare().equals("0")) {
                list = mapper.querySceneGeneralTemplateList(po);
            } else {
                list = mapper.querySceneGeneralTemplateListByQx(po);
            }
        } else if (DictConstants.ROLE_CODE_UESR.equals(roleCode)) {
            //查询普通账户
            po.setUserId(userId);
            if (po.getShare().equals("0")) {
                list = mapper.querySceneGeneralTemplateList(po);
            } else {
                list = mapper.querySceneGeneralTemplateListByQx(po);
            }
        }
        Map<String, String> scenarioRoadTypeMap = dictService.getDictMapByType("scenarioRoadType");
        Map<String, String> scenarioWeatherMap = dictService.getDictMapByType("scenarioWeather");
        for (SceneGeneralTemplatePO vo : list) {
            vo.setScenarioRoadType(scenarioRoadTypeMap.get(vo.getScenarioRoadType()));
            vo.setScenarioWeather(scenarioWeatherMap.get(vo.getScenarioWeather()));
        }
        return list;
    }

    @SneakyThrows
    public SceneGeneralTemplateVO querySceneGeneralTemplateById(String id) {
        SceneGeneralTemplatePO po = mapper.querySceneGeneralTemplateById(id);
        String generalizationType = JsonUtil.stringToJson(po.getGeneralizationType());
        po.setGeneralizationType(generalizationType);
        SceneGeneralTemplateVO vo = new SceneGeneralTemplateVO();
        //转换为vo
        BeanUtils.copyProperties(po, vo);
        List<SceneGeneralTemplateMbVO> listMb = new ArrayList<>();
        if (po.getObsStartX().contains(";")) {
            listMb = spliceVo(po);
        } else {
            SceneGeneralTemplateMbVO mbVO = new SceneGeneralTemplateMbVO();
            BeanUtils.copyProperties(po, mbVO);
            if (ObjectUtil.isNotNull(mbVO.getObsStartX()) || ObjectUtil.isNotNull(mbVO.getObsStartY()) || ObjectUtil.isNotNull(mbVO.getObsLateralAcceleration()) || ObjectUtil.isNotNull(mbVO.getObsStartVelocity())) {
                mbVO.setGeneralizationType(po.getGeneralizationType());
                listMb.add(mbVO);
            }
        }
        vo.setListMb(listMb);
        vo.setTemplateId(vo.getId());
        return vo;
    }

    public List<SceneGeneralTemplateMbVO> spliceVo(SceneGeneralTemplatePO po) throws JsonProcessingException {
        List<SceneGeneralTemplateMbVO> listMb = new ArrayList<>();
        String[] obsStartX = po.getObsStartX().split(";");
        String[] obsStartY = po.getObsStartY().split(";");
        String[] obsStartVelocity = po.getObsStartVelocity().split(";");
        String[] obsLateralAcceleration = po.getObsLateralAcceleration().split(";");
        String[] obsLongitudinalAcceleration = po.getObsLongitudinalAcceleration().split(";");
        String[] obsHeadingAngleRel = po.getObsHeadingAngleRel().split(";");
        String[] obsVelocityStatus = po.getObsVelocityStatus().split(";");
        String[] obsTrajectory = po.getObsTrajectory().split(";");
        String[] obsDurationTime = po.getObsDurationTime().split(";");
        String[] obsVelocityTime = po.getObsVelocityTime().split(";");
        String[] obsTrailTime = po.getObsTrailTime().split(";");
        String[] obsType = po.getObsType().split(";");

        String generalizationType = po.getGeneralizationType();
        List<String> list = Arrays.asList(obsStartX);
        for (int i = 0; i < list.size(); i++) {
            SceneGeneralTemplateMbVO mbVO = new SceneGeneralTemplateMbVO();
            mbVO.setObsStartX(list.get(i));
            mbVO.setObsStartY(obsStartY[i]);
            mbVO.setObsStartVelocity(obsStartVelocity[i]);
            mbVO.setObsLateralAcceleration(obsLateralAcceleration[i]);
            mbVO.setObsLongitudinalAcceleration(obsLongitudinalAcceleration[i]);
            mbVO.setObsHeadingAngleRel(obsHeadingAngleRel[i]);
            mbVO.setObsVelocityStatus(obsVelocityStatus[i]);
            mbVO.setObsTrajectory(obsTrajectory[i]);
            mbVO.setObsDurationTime(obsDurationTime[i]);
            mbVO.setObsVelocityTime(obsVelocityTime[i]);
            mbVO.setObsTrailTime(obsTrailTime[i]);
            mbVO.setObsType(obsType[i]);
            Map<String, Integer> map = JsonUtil.jsonToMap(generalizationType);
            for (Map.Entry<String, Integer> entry : map.entrySet()) {
                String value = entry.getValue().toString();
                if (value.length() > 1) {
                    Integer values = Integer.parseInt(value.substring(i, i + 1));
                    map.put(entry.getKey(), values);
                }
            }
            mbVO.setGeneralizationType(JsonUtil.beanToJson(map));
            listMb.add(mbVO);
        }
        return listMb;
    }


    public void deleteSceneGeneralTemplateById(SceneGeneralTemplatePO po) {
        po.setModifyUserId(AuthUtil.getCurrentUserId());
        po.setModifyTime(TimeUtil.getNowForMysql());

        //根据名称查询所有共有及私有场景
        List<String> idS = mapper.queryIdBySceneId(po.getSceneId());
        mapper.deleteSceneGeneralTemplateByScendId(po);
        //删除场景包
        SystemScenePackageSublistPO systemScenePackageSublistPO = new SystemScenePackageSublistPO();
        systemScenePackageSublistPO.setModifyUserId(AuthUtil.getCurrentUserId());
        systemScenePackageSublistPO.setModifyTime(TimeUtil.getNowForMysql());
        systemScenePackageSublistPO.setSceneName(po.getSceneId());
        systemScenePackageSublistMapper.deleteSystemScenePackageSublistBySC(systemScenePackageSublistPO);
        //删除测试包中场景
        SceneDeleteParam parm = new SceneDeleteParam();
        parm.setModifyUserId(AuthUtil.getCurrentUserId());
        // Set<String> set = new HashSet<>();
        for (String id : idS) {
            parm.setModifyTime(TimeUtil.getNowForMysql());
            parm.setSceneFhId(id);

            // List<String> packageIdS = scenePackageSublistMapper.selectPackageIdById(parm);
            List<ScenePackageSublistPO> listPo = scenePackageSublistMapper.selectPackageFhById(parm);
            for (ScenePackageSublistPO scenePackageSublistPO : listPo) {
                ScenePackagePO scenePackagePO = new ScenePackagePO();
                scenePackagePO.setModifyUserId(AuthUtil.getCurrentUserId());
                scenePackagePO.setModifyTime(TimeUtil.getNowForMysql());
                scenePackagePO.setIsUnavailable("1");
                scenePackagePO.setSceneNum(scenePackageSublistPO.getSceneNum());
                scenePackagePO.setPackageId(scenePackageSublistPO.getRootId());
                //改变测试包状态及数量
                scenePackageMapper.updateIsUnavailable(scenePackagePO);
            }
            //set.addAll(packageIdS);
            //删除场景测试包
            scenePackageSublistMapper.updateScenePackageSublistById(parm);
            //改变场景包场景数量

        }
       /* //改变测试包状态
        List<String> listIds = new ArrayList<>(set);
        ScenePackagePO scenePackagePO = new ScenePackagePO();
        scenePackagePO.setModifyUserId(AuthUtil.getCurrentUserId());
        scenePackagePO.setModifyTime(TimeUtil.getNowForMysql());
        scenePackagePO.setIsUnavailable("1");
        scenePackagePO.setRootIds(listIds);
        scenePackageMapper.updateIsUnavailable(scenePackagePO);
*/

        Map map = new HashMap();
        map.put("sceneId", po.getId());
        map.put("sceneName", po.getSceneId());
        map.put("type", DictConstants.SCENE_GENERAL);
        logService.logSceneDelete(LogConstants.SYS_LOG_SCENE_DELETE, map);

    }

    /**
     * 分享
     */
    public void instShareSceneGeneralTemplate(SceneGeneralTemplatePO po) {
        SceneGeneralTemplatePO syPO = mapper.querySceneGeneralTemplateById(po.getId());
        syPO.setShare("1");
        SceneGeneralTemplatePO sceneGeneralTemplatePOByName = mapper.querySceneGeneralTemplateByName(syPO);
        if (ObjectUtil.isNull(sceneGeneralTemplatePOByName)) {
            // -------------------------------- 保存数据到 mysql --------------------------------
            syPO.setCreateTime(TimeUtil.getNowForMysql());
            syPO.setCreateUserId(AuthUtil.getCurrentUserId());
            syPO.setModifyTime(TimeUtil.getNowForMysql());
            syPO.setModifyUserId("");
            syPO.setId(StringUtil.getRandomUUID());
            mapper.saveSceneGeneralTemplate(syPO);
        } else {
            // -------------------------------- 修改数据到 mysql --------------------------------
            syPO.setModifyTime(TimeUtil.getNowForMysql());
            syPO.setModifyUserId(AuthUtil.getCurrentUserId());
            syPO.setId(sceneGeneralTemplatePOByName.getId());
            mapper.updateSceneGeneralTemplate(syPO);
        }

    }
}
