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

import api.common.pojo.common.ResponseBodyVO;
import api.common.pojo.constants.DictConstants;
import api.common.pojo.constants.LogConstants;
import api.common.pojo.param.MinioParameter;
import api.common.pojo.param.scene.*;
import api.common.pojo.po.scene.*;
import api.common.pojo.po.system.SceneImportPO;
import api.common.util.*;
import com.alibaba.druid.util.StringUtils;
import com.css.simulation.resource.server.infra.util.AuthUtil;
import com.css.simulation.resource.server.infra.feign.service.FileDownService;
import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneNaturalMapper;
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.SystemScenePackageMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.SystemScenePackageSublistMapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.util.StringUtil;
import feign.Response;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;


@Slf4j
@Service
public class SceneNaturalService {

    @Resource
    private SceneNaturalMapper sceneNaturalMapper;
    @Resource
    private ScenePackageSublistMapper scenePackageSublistMapper;
    @Resource
    private ScenePackageMapper scenePackageMapper;
    @Resource
    private SystemScenePackageMapper systemScenePackageMapper;
    @Resource
    private SystemScenePackageSublistMapper systemScenePackageSublistMapper;

    @Resource
    private LogService logService;
    @Resource
    private FileDownService fileDownService;

    @Resource
    private SceneEvaluationRuleService sceneEvaluationRuleService;

    /**
     * 获取自然驾驶场景数据：包括切分数据和标注数据
     */
    @SneakyThrows
    public ResponseBodyVO<String> importZrjsSceneCicv(SceneNaturalParam param) {
        MinioParameter MI = new MinioParameter();
        MI.setObjectName(param.getJsonAddress());
        int idx = param.getJsonAddress().lastIndexOf("/");
        int end = param.getJsonAddress().lastIndexOf(".");
        String fileName = param.getJsonAddress().substring(idx + 1, end);
        param.setNaturalName(fileName);
        SceneNaturalPO sceneNaturalPO = new SceneNaturalPO();
        sceneNaturalPO.setShare("0");
        sceneNaturalPO.setNaturalName(fileName);
        SceneNaturalPO sceneNaturalPOByName = sceneNaturalMapper.querySceneNaturaByName(sceneNaturalPO);
        Response download = fileDownService.download(MI);
        String json = download.body().toString();
        ObjectMapper objMap = new ObjectMapper();
        JsonNode root = objMap.readTree(json);
        // -------------------------------- 自然环境 --------------------------------
        JsonNode naturalEnvironment = root.path("自然环境");
        // -------------------------------- 道路 --------------------------------
        JsonNode road = root.path("道路");
        // -------------------------------- 基础设施 --------------------------------
        JsonNode infrastructure = root.path("基础设施");
        // -------------------------------- 临时性操纵 --------------------------------
        JsonNode temporaryManipulation = root.path("临时性操纵");
        // -------------------------------- 交通状况 --------------------------------
        JsonNode traffic = root.path("交通状况");
        // -------------------------------- 自车行为 --------------------------------
        JsonNode selfDrivingBehavior = root.path("自车行为");
        // -------------------------------- 目标行为 --------------------------------
        JsonNode targetBehavior = root.path("目标行为");

        sceneNaturalPO = sceneNaturalPO.builder()
                .naturalId(api.common.util.StringUtil.getRandomUUID())
                .naturalName(fileName)
                .weather(getSequenceNew(naturalEnvironment, "天气情况"))
                .backlight(getSequenceNew(naturalEnvironment, "逆光"))
                .lightChange(getSequenceNew(naturalEnvironment, "隧道光线变化"))
                .roadType(getSequenceNew(road, "道路类型"))
                .roadMatrrial(getSequenceNew(road, "路面材质"))
                .drivewayNum(getSequenceNew(road, "车道数量"))
                .drivewayType(getSequenceNew(road, "车道类型"))
                .roadFlatness(getSequenceNew(road, "道路平坦程度"))
                .roadCurvature(getSequenceNew(road, "道路弯曲度"))
                .ramp(getSequenceNew(road, "匝道"))
                .intersectionType(getSequenceNew(road, "路口类型"))
                .planeIntersection(getSequenceNew(road, "道路与铁路平面交叉"))
                .bridge(getSequenceNew(road, "桥梁"))
                .tunnel(getSequenceNew(road, "隧道"))
                .speedLimit(getSequenceNew(infrastructure, "限速标志"))
                .minSpeedLimit(getSequenceNew(infrastructure, "最低限速标志"))
                .noEntry(getSequenceNew(infrastructure, "禁止通行"))
                .noStopping(getSequenceNew(infrastructure, "禁止停车"))
                .leftLaneLine(getSequenceNew(infrastructure, "左侧车道线"))
                .rightLaneLine(getSequenceNew(infrastructure, "右侧车道线"))
                .conductorMarking(getSequenceNew(infrastructure, "导线标线及标志"))
                .pedestrianCrossing(getSequenceNew(infrastructure, "人行横道"))
                .trafficLight(getSequenceNew(infrastructure, "交通信号灯"))
                .decelerationMarking(getSequenceNew(infrastructure, "减速标线"))
                .pavementCondition(getSequenceNew(temporaryManipulation, "路面状况"))
                .naturalDisaster(getSequenceNew(temporaryManipulation, "自然灾害"))
                .roadSafetySigns(getSequenceNew(temporaryManipulation, "道路施工安全标识"))
                .safetyWarningBoard(getSequenceNew(temporaryManipulation, "三角安全警示牌"))
                .trafficAccident(getSequenceNew(traffic, "交通事故"))
                .violation(getSequenceNew(traffic, "违规"))
                .specialVehicleYield(getSequenceNew(traffic, "特种车辆让行"))
                .patency(getSequenceNew(traffic, "通畅情况"))
                .doubleFlashingCar(getSequenceNew(traffic, "双闪车辆"))
                .selfBehavior(getSequenceNew(selfDrivingBehavior))
                .targetBehavior(getSequenceNew(targetBehavior))
                .maxTime(root.path("max_time").asText())
                .isDeleted("0")
                .build();
        if (null != param.getJsonAddress() && !param.getJsonAddress().equals("")) {
            sceneNaturalPO.setJsonAddress(param.getJsonAddress());
        }
        if (null != param.getXoscAddress() && !param.getXoscAddress().equals("")) {
            sceneNaturalPO.setXoscAddress(param.getXoscAddress());
        }
        if (null != param.getXodrAddress() && !param.getXodrAddress().equals("")) {
            sceneNaturalPO.setXodrAddress(param.getXodrAddress());
        }
        if (null != param.getOsgbAddress() && !param.getOsgbAddress().equals("")) {
            sceneNaturalPO.setOsgbAddress(param.getOsgbAddress());
        }
        if (null != param.getVideoAddress() && !param.getVideoAddress().equals("")) {
            sceneNaturalPO.setVideoAddress(param.getVideoAddress());
        }
        if (null != param.getVideoPreview() && !param.getVideoPreview().equals("")) {
            sceneNaturalPO.setVideoPreview(param.getVideoPreview());
        }

        if (ObjectUtil.isNull(sceneNaturalPOByName)) {
            // -------------------------------- 保存数据到 mysql --------------------------------
            sceneNaturalPO.setCreateTime(TimeUtil.getNowForMysql());
            sceneNaturalPO.setCreateUserId(AuthUtil.getCurrentUserId());
            sceneNaturalPO.setModifyTime(TimeUtil.getNowForMysql());
            sceneNaturalMapper.saveSceneNatural(sceneNaturalPO);
            //  return new ResponseBodyVO(ResponseBodyVO.Response.CLIENT_FAILURE, "该场景编号" + fileName + "已存在，请检查");
        } else {
            // -------------------------------- 修改数据到 mysql --------------------------------
            sceneNaturalPO.setModifyUserId(AuthUtil.getCurrentUserId());
            sceneNaturalPO.setModifyTime(TimeUtil.getNowForMysql());
            sceneNaturalPO.setNaturalId(sceneNaturalPOByName.getNaturalId());
            sceneNaturalMapper.updateSceneNatural(sceneNaturalPO);
        }
        return new ResponseBodyVO(ResponseBodyVO.Response.SUCCESS);
    }

    public String getSequenceNew(JsonNode jsonObject, String field) {
        if (jsonObject == null) {
            return "无法确定";
        }
        JsonNode jsonArray = jsonObject.path(field);
        StringBuilder sequence = new StringBuilder();
        for (int i = 0; i < jsonArray.size(); i++) {
            String type_ = jsonArray.path(i).path("type_").asText();
            if (StringUtil.isNotEmpty(type_)) {
                if (i == 0) {
                    sequence.append(type_);
                    continue;
                }
                if (!sequence.toString().contains(type_))
                    sequence.append(",").append(type_);
            }
        }
        String s = sequence.toString();
        if (StringUtil.isEmpty(s))
            return "无法确定";
        else
            return s;
    }

    public String getSequenceNew(JsonNode jsonArray) {
        if (jsonArray == null) {
            return "无法确定";
        }
        StringBuilder sequence = new StringBuilder();
        for (int i = 0; i < jsonArray.size(); i++) {
            String type_ = jsonArray.path(i).path("type_").asText();
            if (StringUtil.isNotEmpty(type_)) {
                if (i == 0) {
                    sequence.append(type_);
                    continue;
                }
                if (!sequence.toString().contains(type_))
                    sequence.append(",").append(type_);
            }
        }
        String s = sequence.toString();
        if (StringUtil.isEmpty(s))
            return "无法确定";
        else
            return s;
    }

    private void copyEvaluationParams(SceneNaturalNewParam params, SceneNaturalParam po) {
        po.setComplexityLevel(params.getComplexityLevel());
        po.setMinComplexity(params.getMinComplexity());
        po.setMaxComplexity(params.getMaxComplexity());
        po.setRiskLevel(params.getRiskLevel());
        po.setMinRisk(params.getMinRisk());
        po.setMaxRisk(params.getMaxRisk());
        if (StringUtil.isNotEmpty(params.getComplexityLevel()) || StringUtil.isNotEmpty(params.getMinComplexity()) || StringUtil.isNotEmpty(params.getMaxComplexity())) {
            po.setNeedComplexity("1");
        }
        if (StringUtil.isNotEmpty(params.getRiskLevel()) || StringUtil.isNotEmpty(params.getMinRisk()) || StringUtil.isNotEmpty(params.getMaxRisk())) {
            po.setNeedRisk("1");
        }
    }

    public SceneEvaluationOperatePO getSceneEvaluationFirst(SceneNaturalNewParam params, List<String> sceneIdList) {
        // 添加复杂度 危险度数据
        SceneEvaluationForListParam sceneEvaluationForListParam = new SceneEvaluationForListParam();
        BeanUtils.copyProperties(params, sceneEvaluationForListParam);
        sceneEvaluationForListParam.setSceneIdList(sceneIdList);
        return sceneEvaluationRuleService.getSceneEvaluationFirst(sceneEvaluationForListParam);
    }

    public List<SceneNaturalPO> querySceneNaturalList(SceneNaturalNewParam params) {
        SceneNaturalParam po = new SceneNaturalParam();
        copyEvaluationParams(params, po);
        po.setShare(params.getShare());
        String naturalName = params.getNaturalName();      // 场景编号
        String[][] naturalEnvironment = params.getNaturalEnvironment(); //自然环境
        String[][] road = params.getRoad(); //道路
        String[][] infrastructure = params.getInfrastructure(); //基础设施
        String[][] temporaryOperation = params.getTemporaryOperation(); //临时性操作
        String[][] trafficCondition = params.getTrafficCondition(); //交通状况
        String[][] selfBehavior = params.getSelfBehavior();//自车行为
        String[][] targetBehavior = params.getTargetBehavior(); //目标行为
        //判断下拉选项是否为空
        if (ObjectUtil.isNotNull(params.getIds())) {
            po.setIds(params.getIds());
        }
        if (ObjectUtil.isNotNull(params.getAllSceneNames())) {
            po.setAllSceneNames(params.getAllSceneNames());
        }
        if (ObjectUtil.isNotNull(naturalName)) {
            po.setNaturalName(naturalName);
        }
        if (naturalEnvironment != null && naturalEnvironment.length > 0) {
            ParamUtil.arrConvertObj(naturalEnvironment, po);
        }
        if (road != null && road.length > 0) {
            ParamUtil.arrConvertObj(road, po);
        }
        if (infrastructure != null && infrastructure.length > 0) {
            ParamUtil.arrConvertObj(infrastructure, po);
        }
        if (temporaryOperation != null && temporaryOperation.length > 0) {
            ParamUtil.arrConvertObj(temporaryOperation, po);
        }
        if (trafficCondition != null && trafficCondition.length > 0) {
            ParamUtil.arrConvertObj(trafficCondition, po);
        }
        if (selfBehavior != null && selfBehavior.length > 0) {
            ParamUtil.arrConvertObj(selfBehavior, po);
            for (String[] arr : selfBehavior) {
                if (arr != null && arr.length == 1) {
                    List<String> list = po.getSelfBehavior();
                    if (list == null) {
                        List<String> newList = new ArrayList<>();
                        newList.add(arr[0]);
                        po.setSelfBehavior(newList);
                    } else {
                        list.add(arr[0]);
                        po.setSelfBehavior(list);
                    }
                }
            }
        }
        if (targetBehavior != null && targetBehavior.length > 0) {
            ParamUtil.arrConvertObj(targetBehavior, po);
        }

        //获取权限并赋值
        List<SceneNaturalPO> list = new ArrayList<>();

        //添加权限
        String roleCode = AuthUtil.getCurrentUserRoleCode();
        String userId = AuthUtil.getCurrentUserId();
        if (DictConstants.ROLE_CODE_ADMIN.equals(roleCode) || DictConstants.ROLE_CODE_SYSADMIN.equals(roleCode)) { //管理员账户

            list = sceneNaturalMapper.querySceneNaturalList(po);
            System.out.println(" //添加权限------" + list.size() + "------" + po);

        } else if (DictConstants.ROLE_CODE_SUBUESR.equals(roleCode)) {
            //查询父账户
            userId = AuthUtil.getCreateUserId();
            po.setUserId(userId);
            // poBq.setUserId(userId);
            //if((po.getXlk().equals("0")&&po.getBq().equals("0"))||(po.getXlk().equals("1")&&po.getBq().equals("0"))){
            if (po.getShare().equals("0")) {
                list = sceneNaturalMapper.querySceneNaturalList(po);
            } else {
                list = sceneNaturalMapper.querySceneNaturalListByQx(po);
            }

        } else if (DictConstants.ROLE_CODE_UESR.equals(roleCode)) {
            //查询普通账户
            po.setUserId(userId);
            if (po.getShare().equals("0")) {
                list = sceneNaturalMapper.querySceneNaturalList(po);
            } else {
                list = sceneNaturalMapper.querySceneNaturalListByQx(po);
            }
        }

        for (SceneNaturalPO vo : list) {
            // 赋值复杂度
            // 赋值复杂度
            if (vo.getRoadType().equals("高速")) {
                if (ObjectUtil.isNull(vo.getLabel())) {
                    vo.setLabel("高速");
                } else {
                    vo.setLabel(vo.getLabel() + ",高速");
                }
            }
            if (vo.getRamp().equals("是")) {
                if (ObjectUtil.isNull(vo.getLabel())) {
                    vo.setLabel("匝道");
                } else {
                    vo.setLabel(vo.getLabel() + ",匝道");
                }
            }
            if (vo.getTunnel().equals("是")) {
                if (ObjectUtil.isNull(vo.getLabel())) {
                    vo.setLabel("隧道");
                } else {
                    vo.setLabel(vo.getLabel() + ",隧道");
                }
            }
            if (vo.getTargetBehavior().contains("机动车从左侧切入成功") || vo.getTargetBehavior().contains("机动车从右侧切入成功")) {
                if (ObjectUtil.isNull(vo.getLabel())) {
                    vo.setLabel("切入");
                } else {
                    vo.setLabel(vo.getLabel() + ",切入");
                }
            }
            if (vo.getTargetBehavior().equals("机动车向左侧切出成功") || vo.getTargetBehavior().equals("机动车向右侧切出成功")) {
                if (ObjectUtil.isNull(vo.getLabel())) {
                    vo.setLabel("切出");
                } else {
                    vo.setLabel(vo.getLabel() + ",切出");
                }
            }
            if (vo.getSelfBehavior().contains("直路掉头") || vo.getSelfBehavior().contains("路口掉头")) {
                if (ObjectUtil.isNull(vo.getLabel())) {
                    vo.setLabel("掉头");
                } else {
                    vo.setLabel(vo.getLabel() + ",掉头");
                }
            }
            if (vo.getSelfBehavior().contains("向左变道成功") || vo.getSelfBehavior().equals("向右变道成功") || vo.getSelfBehavior().contains("向左连续变道") || vo.getSelfBehavior().indexOf("向右连续变道") > -1 || vo.getSelfBehavior().indexOf("向左变道超车") > -1 || vo.getSelfBehavior().indexOf("向右变道超车") > -1) {
                if (ObjectUtil.isNull(vo.getLabel())) {
                    vo.setLabel("变道");
                } else {
                    vo.setLabel(vo.getLabel() + ",变道");
                }
            }
        }
        return list;
    }


    @Transactional
    public void batchDeleteSceneNatural(List<String> sceneNames) {
        deleteSceneNatural(sceneNames);
    }

    @Transactional
    @SneakyThrows
    public void deleteSceneNatural(List<String> sceneNames) {
        Map<String, String> map = new HashMap<>();
        try {
            //* -------------------------------- 场景表 --------------------------------
            //1 根据场景名称查询出同名的所有场景id，包括公有和私有
            List<String> sceneIds = sceneNaturalMapper.selectIdsByNames(sceneNames);
            if (CollectionUtil.isEmpty(sceneIds)) {
                return;
            }
            //2 删除场景数据
            SceneDeleteParam sceneDeleteParam = SceneDeleteParam.builder()
                    .sceneNames(sceneNames)
                    .modifyTime(TimeUtil.getNowForMysql())
                    .modifyUserId(AuthUtil.getCreateUserId())
                    .build();
            sceneNaturalMapper.deleteBySceneNames(sceneDeleteParam);
            //* -------------------------------- 场景测试包指标表 & 场景测试包表 --------------------------------
            //1 根据自然驾驶场景ID查询场景测试包指标
            List<ScenePackageSublistPO> indexes = scenePackageSublistMapper.selectBySceneIds(ScenePackageSublistParam.builder()
                    .sceneIds(sceneIds)
                    .sceneType(DictConstants.SCENE_NATURAL)
                    .build());
            if (CollectionUtil.isEmpty(indexes)) {
                return;
            }
            //2 根据指标ID查询场景测试包
            List<ScenePackagePO> testPackages = scenePackageMapper.selectByIndexIds(ScenePackageParam.builder()
                    .indexIds(indexes.stream().map(ScenePackageSublistPO::getSublistId).collect(Collectors.toList()))
                    .build());
            //3 设置包为已禁用
            testPackages.forEach(testPackage -> testPackage.setIsUnavailable(DictConstants.IS_UNAVAILABLE));
            //4 遍历删除场景
            AtomicInteger deleteNum = new AtomicInteger();
            indexes.forEach(index -> {
                final String sceneNaturalIdsString = index.getSceneNaturalIds();
                List<String> sceneNaturalIds = new ArrayList<>();
                if (api.common.util.StringUtil.isNotEmpty(sceneNaturalIdsString)) {
                    sceneNaturalIds = CollectionUtil.sequenceStringToList(sceneNaturalIdsString, ",");
                }
                final String sceneTrafficIdsString = index.getSceneTrafficIds();
                List<String> sceneTrafficIds = new ArrayList<>();
                if (api.common.util.StringUtil.isNotEmpty(sceneTrafficIdsString)) {
                    sceneTrafficIds = CollectionUtil.sequenceStringToList(sceneTrafficIdsString, ",");
                }
                final String sceneStatueIdsString = index.getSceneStatueIds();
                List<String> sceneStatueIds = new ArrayList<>();
                if (api.common.util.StringUtil.isNotEmpty(sceneStatueIdsString)) {
                    sceneStatueIds = CollectionUtil.sequenceStringToList(sceneStatueIdsString, ",");
                }
                final String sceneGeneralizationIdsString = index.getSceneGeneralizationIds();
                List<String> sceneGeneralizationIds = new ArrayList<>();
                if (api.common.util.StringUtil.isNotEmpty(sceneGeneralizationIdsString)) {
                    sceneGeneralizationIds = CollectionUtil.sequenceStringToList(sceneGeneralizationIdsString, ",");
                }
                final String sceneReferenceLibIds = index.getSceneReferenceLibIds();
                List<String> sceneReferenceLibIdList = new ArrayList<>();
                if (api.common.util.StringUtil.isNotEmpty(sceneReferenceLibIds)) {
                    sceneReferenceLibIdList = CollectionUtil.sequenceStringToList(sceneReferenceLibIds, ",");
                }

                final Iterator<String> iterator = sceneNaturalIds.iterator();
                while (iterator.hasNext()) {
                    final String sceneId = iterator.next();
                    if (sceneIds.contains(sceneId)) {
                        iterator.remove();
                        deleteNum.getAndIncrement();
                        testPackages.forEach(testPackage -> {
                            testPackage.setSceneNum(testPackage.getSceneNum() - 1);
                        });
                    }
                }
                index.setSceneNum(sceneNaturalIds.size() + sceneTrafficIds.size() + sceneStatueIds.size() + sceneGeneralizationIds.size() + sceneReferenceLibIdList.size());
//                index.setSceneNum(index.getSceneNum() - deleteNum.get());
                index.setSceneNaturalIds(CollectionUtil.listToSequence(sceneNaturalIds));
                index.setModifyTime(TimeUtil.getNowForMysql());
                index.setModifyUserId(AuthUtil.getCurrentUserId());
            });
            //5 更新指标
            scenePackageSublistMapper.update(indexes);
            //6 更新包
            scenePackageMapper.update(testPackages);

            //* -------------------------------- 场景包表 --------------------------------
            //1 将所有场景包中的该场景删除
            systemScenePackageSublistMapper.deleteBySceneNames(SystemScenePackageParam.builder()
                    .sceneNames(sceneNames)
                    .modifyTime(TimeUtil.getNowForMysql())
                    .modifyUserId(AuthUtil.getCurrentUserId())
                    .build());
        } finally {
            //* -------------------------------- 日志表 --------------------------------
            map.put("sceneNames", JsonUtil.listToJson(sceneNames));
            map.put("type", DictConstants.SCENE_NATURAL);
            logService.logSceneDelete(LogConstants.SYS_LOG_SCENE_DELETE, map);
        }
    }

    public Integer querySceneNumBySy() {
        SceneNaturalParam params = new SceneNaturalParam();
        String roleCode = AuthUtil.getCurrentUserRoleCode();
        String userId = AuthUtil.getCurrentUserId();
        if (DictConstants.ROLE_CODE_ADMIN.equals(roleCode) || DictConstants.ROLE_CODE_SYSADMIN.equals(roleCode)) {
            //管理员账户
            return sceneNaturalMapper.querySceneNumBySy(params);
        } else if (DictConstants.ROLE_CODE_SUBUESR.equals(roleCode)) {
            //根据普通子账户查询父账户
            userId = AuthUtil.getCreateUserId();
            params.setCreateUserId(userId);
            return sceneNaturalMapper.querySceneNumBySy(params);
        } else if (DictConstants.ROLE_CODE_UESR.equals(roleCode)) {
            //查询普通账户
            params.setCreateUserId(userId);
            return sceneNaturalMapper.querySceneNumBySy(params);
        }
        return 0;
    }

    public Integer querySceneNumByGy() {
        SceneNaturalParam params = new SceneNaturalParam();
        String roleCode = AuthUtil.getCurrentUserRoleCode();
        String userId = AuthUtil.getCurrentUserId();
        if (DictConstants.ROLE_CODE_ADMIN.equals(roleCode) || DictConstants.ROLE_CODE_SYSADMIN.equals(roleCode)) {
            //管理员账户
            return systemScenePackageMapper.querySceneNum("");
        } else if (DictConstants.ROLE_CODE_SUBUESR.equals(roleCode)) {
            //根据普通子账户查询父账户
            userId = AuthUtil.getCreateUserId();
            return systemScenePackageMapper.querySceneNum(userId);
        } else if (DictConstants.ROLE_CODE_UESR.equals(roleCode)) {
            //查询普通账户
            return systemScenePackageMapper.querySceneNum(userId);
        }
        return 0;
    }


    /**
     * 获取自然场景数据：
     */
    public SceneImportPO importMiNio(SceneImportParam parms) {
        SceneImportPO sceneImportPO = new SceneImportPO();
        sceneImportPO.setId(parms.getId());
        try {
            MinioParameter MI = new MinioParameter();
            MI.setObjectName(parms.getMinioDirectory());
            List<String> list = fileDownService.listDeepOne(MI).getInfo();
            String OsgbPath = null;
            String XodrPath = null;
            int successNum = 0;
            int falseNum = 0;
            String errorMessage = "";
            for (String filePath : list) {
                if (filePath.contains("/OSGB")) {
                    OsgbPath = filePath;
                } else if (filePath.contains("/XODR")) {
                    XodrPath = filePath;
                }
            }
            List<String> sceneNames = new ArrayList<>();
            for (String filePath : list) {
                if (filePath.contains("/Scenarios")) {
                    MI.setObjectName(filePath);
                    List<String> listScene = fileDownService.listDeepOne(MI).getInfo();
                    log.info("共需要上传 " + listScene.size() + " 个自然驾驶场景");
                    String taskId = api.common.util.StringUtil.getRandomUUID();
                    SceneEvaluationComputeParam sceneComplexityEvaluationComputeParam = new SceneEvaluationComputeParam();
                    sceneComplexityEvaluationComputeParam.setSceneEvaluationComputeSubParam(new ArrayList<>());
                    HashSet<String> strings = new HashSet<>(listScene);
                    log.info("去重之后还剩 " + strings.size() + " 个自然驾驶场景");
                    int addNumber = 0;
                    int updateNumber = 0;
                    Map<String, String> checkFileName = new HashMap<>();
                    for (String scenePath : listScene) {
                        try {
                            MI.setObjectName(scenePath);
                            List<String> addressList = fileDownService.listDeepOne(MI).getInfo();
                            SceneNaturalPO sceneNaturalPO = new SceneNaturalPO();
                            sceneNaturalPO.setShare("0");
                            boolean update = false;
                            String sceneName;
                            List<SceneNaturalPO> scenes = new ArrayList<>();
                            for (String address : addressList) {
                                // 自然驾驶场景取json名称作为场景名称
                                if (address.contains(".json")) {
                                    log.info("解析自然驾驶场景 json 文件：" + address);
                                    MI.setObjectName(address);
                                    Response download = fileDownService.download(MI);
                                    // -------------------------------- label.json --------------------------------
                                    String json = download.body().toString();
                                    download.close();
                                    ObjectMapper objMap = new ObjectMapper();
                                    JsonNode root = objMap.readTree(json);
                                    //判断场景名称唯一
                                    int idx = address.lastIndexOf("/");
                                    int end = address.lastIndexOf(".");
                                    String fileName = address.substring(idx + 1, end);
                                    sceneName = fileName;
                                    sceneNames.add(sceneName);
                                    if (checkFileName.containsKey(fileName)) {
                                        log.warn("自然驾驶场景" + fileName + " 重名，路径1：" + checkFileName.get(fileName) + "，路径2：" + address);
                                    } else {
                                        checkFileName.put(fileName, address);
                                    }
                                    sceneNaturalPO.setNaturalName(fileName);
//                                    sceneNaturalPO.setShare("0");
                                    sceneNaturalPO.setShare(null); // 覆盖全部场景，包括share为0、1、2
                                    scenes = sceneNaturalMapper.selectAllByName(sceneNaturalPO);
                                    String osgbAdress = OsgbPath + "/" + root.path("osgb").asText();
                                    String xodrAdress = XodrPath + "/" + root.path("xodr").asText();
                                    // -------------------------------- 自然环境 --------------------------------
                                    JsonNode naturalEnvironment = root.path("自然环境");
                                    // -------------------------------- 道路 --------------------------------
                                    JsonNode road = root.path("道路");
                                    // -------------------------------- 基础设施 --------------------------------
                                    JsonNode infrastructure = root.path("基础设施");
                                    // -------------------------------- 临时性操纵 --------------------------------
                                    JsonNode temporaryManipulation = root.path("临时性操纵");
                                    // -------------------------------- 交通状况 --------------------------------
                                    JsonNode traffic = root.path("交通状况");
                                    // -------------------------------- 自车行为 --------------------------------
                                    JsonNode selfDrivingBehavior = root.path("自车行为");
                                    // -------------------------------- 目标行为 --------------------------------
                                    JsonNode targetBehavior = root.path("目标行为");

                                    if (naturalEnvironment == null || road == null || (selfDrivingBehavior == null && targetBehavior == null)) {
                                        sceneImportPO.setStatus(DictConstants.SCENE_IMPORT_STATUS_2);
                                        String em = "文件 " + address + " 内容不符合标准格式（自然环境和道路不为空且自车行为、冲突行为不同时为空）。";
                                        log.error(em);
                                        sceneImportPO.setErrorMessage(em);
                                        return sceneImportPO;
                                    }
                                    // 同名就会替换，不同名是新增
                                    update = CollectionUtil.isNotEmpty(scenes);
                                    sceneNaturalPO.setNaturalName(fileName);
                                    sceneNaturalPO.setWeather(getSequenceNew(naturalEnvironment, "天气情况"));
                                    sceneNaturalPO.setBacklight(getSequenceNew(naturalEnvironment, "逆光"));
                                    sceneNaturalPO.setLightChange(getSequenceNew(naturalEnvironment, "隧道光线变化"));
                                    sceneNaturalPO.setRoadType(getSequenceNew(road, "道路类型"));
                                    sceneNaturalPO.setRoadMatrrial(getSequenceNew(road, "路面材质"));
                                    sceneNaturalPO.setDrivewayNum(getSequenceNew(road, "车道数量"));
                                    sceneNaturalPO.setDrivewayType(getSequenceNew(road, "车道类型"));
                                    sceneNaturalPO.setRoadFlatness(getSequenceNew(road, "道路平坦程度"));
                                    sceneNaturalPO.setRoadCurvature(getSequenceNew(road, "道路弯曲度"));
                                    sceneNaturalPO.setRamp(getSequenceNew(road, "匝道"));
                                    sceneNaturalPO.setIntersectionType(getSequenceNew(road, "路口类型"));
                                    sceneNaturalPO.setPlaneIntersection(getSequenceNew(road, "道路与铁路平面交叉"));
                                    sceneNaturalPO.setBridge(getSequenceNew(road, "桥梁"));
                                    sceneNaturalPO.setTunnel(getSequenceNew(road, "隧道"));
                                    sceneNaturalPO.setSpeedLimit(getSequenceNew(infrastructure, "限速标志"));
                                    sceneNaturalPO.setMinSpeedLimit(getSequenceNew(infrastructure, "最低限速标志"));
                                    sceneNaturalPO.setNoEntry(getSequenceNew(infrastructure, "禁止通行"));
                                    sceneNaturalPO.setNoStopping(getSequenceNew(infrastructure, "禁止停车"));
                                    sceneNaturalPO.setLeftLaneLine(getSequenceNew(infrastructure, "左侧车道线"));
                                    sceneNaturalPO.setRightLaneLine(getSequenceNew(infrastructure, "右侧车道线"));
                                    sceneNaturalPO.setConductorMarking(getSequenceNew(infrastructure, "导线标线及标志"));
                                    sceneNaturalPO.setPedestrianCrossing(getSequenceNew(infrastructure, "人行横道"));
                                    sceneNaturalPO.setTrafficLight(getSequenceNew(infrastructure, "交通信号灯"));
                                    sceneNaturalPO.setDecelerationMarking(getSequenceNew(infrastructure, "减速标线"));
                                    sceneNaturalPO.setPavementCondition(getSequenceNew(temporaryManipulation, "路面状况"));
                                    sceneNaturalPO.setNaturalDisaster(getSequenceNew(temporaryManipulation, "自然灾害"));
                                    sceneNaturalPO.setRoadSafetySigns(getSequenceNew(temporaryManipulation, "道路施工安全标识"));
                                    sceneNaturalPO.setSafetyWarningBoard(getSequenceNew(temporaryManipulation, "三角安全警示牌"));
                                    sceneNaturalPO.setTrafficAccident(getSequenceNew(traffic, "交通事故"));
                                    sceneNaturalPO.setViolation(getSequenceNew(traffic, "违规"));
                                    sceneNaturalPO.setSpecialVehicleYield(getSequenceNew(traffic, "特种车辆让行"));
                                    sceneNaturalPO.setPatency(getSequenceNew(traffic, "通畅情况"));
                                    sceneNaturalPO.setDoubleFlashingCar(getSequenceNew(traffic, "双闪车辆"));
                                    sceneNaturalPO.setSelfBehavior(getSequenceNew(selfDrivingBehavior));
                                    sceneNaturalPO.setTargetBehavior(getSequenceNew(targetBehavior));
                                    sceneNaturalPO.setMaxTime(root.path("max_time").asText());
                                    sceneNaturalPO.setIsDeleted("0");
                                    sceneNaturalPO.setOsgbAddress(osgbAdress);
                                    sceneNaturalPO.setXodrAddress(xodrAdress);
                                    sceneNaturalPO.setJsonAddress(address);
                                } else if (address.contains(".xml") || address.contains(".xosc")) {
                                    sceneNaturalPO.setXoscAddress(address);
                                } else if (address.contains(".xodr")) {
                                    sceneNaturalPO.setXodrAddress(address);
                                } else if (address.contains(".osgb")) {
                                    sceneNaturalPO.setOsgbAddress(address);
                                } else if (address.contains("simulation.mp4")) {
                                    sceneNaturalPO.setVideoAddress(address);
                                } else if (address.contains(".mp4")) {
                                    sceneNaturalPO.setVideoPreview(address);
                                }
                            }
                            if (update) {
                                // -------------------------------- 修改数据到 mysql --------------------------------
                                updateNumber++;
                                if (api.common.util.StringUtil.isEmpty(sceneNaturalPO.getShare())) {
                                    sceneNaturalPO.setShare(DictConstants.IS_NOT_SHARED);
                                }
                                scenes.forEach(scene -> {
                                    sceneNaturalPO.setNaturalId(scene.getNaturalId());
                                    sceneNaturalPO.setModifyTime(TimeUtil.getNowForMysql());
                                    sceneNaturalPO.setModifyUserId(AuthUtil.getCurrentUserId());
                                    sceneNaturalMapper.updateSceneNatural(sceneNaturalPO);
                                });
                            } else {
                                // -------------------------------- 保存数据到 mysql --------------------------------
                                addNumber++;
                                sceneNaturalPO.setShare(DictConstants.IS_NOT_SHARED);
                                sceneNaturalPO.setNaturalId(api.common.util.StringUtil.getRandomUUID());
                                sceneNaturalPO.setCreateTime(TimeUtil.getNowForMysql());
                                sceneNaturalPO.setCreateUserId(AuthUtil.getCurrentUserId());
                                sceneNaturalPO.setModifyTime(TimeUtil.getNowForMysql());
                                sceneNaturalMapper.saveSceneNatural(sceneNaturalPO);
                            }
                            successNum = successNum + 1;

                            // 计算复杂度
                            if (!StringUtils.isEmpty(parms.getSceneEvaluationRuleId())) {
                                SceneEvaluationComputeSubParam sceneEvaluationComputeSubParam = new SceneEvaluationComputeSubParam();
                                sceneEvaluationComputeSubParam.setSceneId(update ? scenes.get(0).getNaturalId() : sceneNaturalPO.getNaturalId());
                                sceneEvaluationComputeSubParam.setSceneXOSCPath(sceneNaturalPO.getXoscAddress());
                                sceneEvaluationComputeSubParam.setSceneXODRPath(sceneNaturalPO.getXodrAddress());
                                sceneEvaluationComputeSubParam.setSceneType(DictConstants.SCENE_NATURAL);
                                if (update) {
                                    String tempSceneId = scenes.get(0).getNaturalId();
                                    sceneEvaluationComputeSubParam.setCopySceneId(scenes.stream().map(SceneNaturalPO::getNaturalId).filter(sceneId -> !StringUtils.equals(tempSceneId, sceneId)).collect(Collectors.toList()));
                                }
                                sceneComplexityEvaluationComputeParam.getSceneEvaluationComputeSubParam().add(sceneEvaluationComputeSubParam);
                                log.info("添加计算复杂度数据：" + sceneEvaluationComputeSubParam);
                            }
                        } catch (Exception e) {
                            errorMessage = e.getMessage();
                            e.printStackTrace();
                            falseNum = falseNum + 1;
                        }
                    }
                    log.info("共新增 " + addNumber + " 个自然驾驶场景，修改 " + updateNumber + "个场景。");
                    try {
                        if (CollectionUtil.isNotEmpty(sceneComplexityEvaluationComputeParam.getSceneEvaluationComputeSubParam())) {
                            sceneComplexityEvaluationComputeParam.setTaskId(taskId);
                            sceneComplexityEvaluationComputeParam.setSceneEvaluationRuleId(parms.getSceneEvaluationRuleId());
                            sceneComplexityEvaluationComputeParam.setComputeType(DictConstants.COMPLEXITY);
                            sceneComplexityEvaluationComputeParam.setCreateUserId(AuthUtil.getCurrentUserId());
                            sceneEvaluationRuleService.computeSceneEvaluation(sceneComplexityEvaluationComputeParam);
                        }
                    } catch (Exception e) {
                        log.error("计算复杂度失败", e);
                    }
                }
            }
            sceneImportPO.setStatus(DictConstants.SCENE_IMPORT_STATUS_4);
            sceneImportPO.setSuccessNum(successNum);
            sceneImportPO.setFalseNum(falseNum);
            sceneImportPO.setErrorMessage(errorMessage);
            sceneImportPO.setSceneNames(CollectionUtil.listToSequence(sceneNames));
            return sceneImportPO;
        } catch (Exception e) {
            sceneImportPO.setStatus(DictConstants.SCENE_IMPORT_STATUS_2);
            sceneImportPO.setErrorMessage("该文件地址：" + parms.getMinioDirectory() + "解析失败，请检查。");
            return sceneImportPO;
        }
    }


    /**
     * 分享
     */
    public void instShareSceneNatural(SceneNaturalPO parms) {
        SceneNaturalPO syPo = sceneNaturalMapper.querySceneNaturalById(parms.getNaturalId());
        syPo.setShare("1");
        SceneNaturalPO sceneNaturalPOByName = sceneNaturalMapper.querySceneNaturaByName(syPo);
        if (ObjectUtil.isNull(sceneNaturalPOByName)) {
            // -------------------------------- 保存数据到 mysql --------------------------------
            syPo.setCreateTime(TimeUtil.getNowForMysql());
            syPo.setCreateUserId(AuthUtil.getCurrentUserId());
            syPo.setModifyTime(TimeUtil.getNowForMysql());
            syPo.setModifyUserId("");
            syPo.setNaturalId(api.common.util.StringUtil.getRandomUUID());
            sceneNaturalMapper.saveSceneNatural(syPo);
        } else {
            // -------------------------------- 修改数据到 mysql --------------------------------
            syPo.setModifyTime(TimeUtil.getNowForMysql());
            syPo.setModifyUserId(AuthUtil.getCurrentUserId());
            syPo.setNaturalId(sceneNaturalPOByName.getNaturalId());
            sceneNaturalMapper.updateSceneNatural(syPo);
        }

    }


}
