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


import api.common.pojo.common.ResponseBodyVO;
import api.common.pojo.po.scene.SceneGeneralDataPO;
import api.common.pojo.po.scene.SceneGeneralExamplePO;
import api.common.pojo.po.scene.SceneGeneralTemplatePO;
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.util.AuthUtil;
import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneGeneralDataMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneGeneralExampleMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneGeneralTemplateMapper;
import com.css.simulation.resource.server.infra.util.SceneUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class SceneGeneralExampleService {
    @Value("${general.url}")
    private String generalUrl;
    @Resource
    private SceneGeneralExampleMapper exampleMapper;
    @Resource
    private SceneGeneralTemplateMapper templateMapper;
    @Resource
    private SceneGeneralDataMapper dataMapper;
    @Resource
    private SceneGeneralTemplateService sceneGeneralTemplateService;
    @Resource
    private SceneUtil sceneUtil;


    @SneakyThrows
    public ResponseBodyVO<SceneGeneralTemplateVO> querySceneGeneralExampleById(String id) {

        SceneGeneralExamplePO examplePo = exampleMapper.querySceneGeneralExampleById(id);
        if (ObjectUtil.isNotNull(examplePo)) {
            SceneGeneralTemplatePO templatePO = templateMapper.querySceneGeneralTemplateById(examplePo.getTemplateId());
            if (ObjectUtil.isNotNull(templatePO) && templatePO.getIsDeleted().equals("1")) {
                examplePo.setIsTure("1");
            }
        }
        String generalizationType = JsonUtil.stringToJson(examplePo.getGeneralizationType());
        examplePo.setGeneralizationType(generalizationType);

        //转换为vo
        SceneGeneralTemplatePO po = new SceneGeneralTemplatePO();
        BeanUtils.copyProperties(examplePo, po);
        SceneGeneralTemplateVO vo = new SceneGeneralTemplateVO();
        BeanUtils.copyProperties(po, vo);
        List<SceneGeneralTemplateMbVO> listMb = new ArrayList<>();
        if (po.getObsStartX().contains(";")) {
            listMb = sceneGeneralTemplateService.spliceVo(po);
        } else {
            SceneGeneralTemplateMbVO mbVO = new SceneGeneralTemplateMbVO();
            BeanUtils.copyProperties(po, mbVO);
            mbVO.setGeneralizationType(po.getGeneralizationType());
            listMb.add(mbVO);
        }
        vo.setListMb(listMb);
        vo.setTemplateId(examplePo.getTemplateId());
        vo.setIsTure(examplePo.getIsTure());


        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, vo);

    }

    public ResponseBodyVO<List<String>> queryType() {
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, templateMapper.queryType());
    }

    @SneakyThrows
    public ResponseBodyVO saveSceneGeneralExample(SceneGeneralTemplateVO vo) {

        //查询泛化标志位并赋值
        SceneGeneralTemplatePO poV = templateMapper.querySceneGeneralTemplateById(vo.getTemplateId());
        SceneGeneralExamplePO po = new SceneGeneralExamplePO();
        //转换为vo
        BeanUtils.copyProperties(vo, po);
        po.setGeneralizationType(poV.getGeneralizationType());
        po.setEgoVelocityStatus(poV.getEgoVelocityStatus());
        po.setEgoTrajectory(poV.getEgoTrajectory());
        po.setObsVelocityStatus(poV.getObsVelocityStatus());
        po.setObsTrajectory(poV.getObsTrajectory());
        //加个唯一值，确定文件夹唯一
        po.setUuId(StringUtil.getRandomUUID());

        //合并目标物
        List<SceneGeneralTemplateMbVO> listMb = vo.getListMb();

        String obsStartX = "";
        String obsStartY = "";
        String obsStartVelocity = "";
        String obsLateralAcceleration = "";
        String obsLongitudinalAcceleration = "";
        String obsHeadingAngleRel = "";
        String obsDurationTime = "";
        String obsVelocityTime = "";
        String obsTrailTime = "";
        String obsType = "";


        int a = 0;
        for (SceneGeneralTemplateMbVO mbVo : listMb) {
            if (a < 1) {
                obsStartX = mbVo.getObsStartX();
                obsStartY = mbVo.getObsStartY();
                obsStartVelocity = mbVo.getObsStartVelocity();
                obsLateralAcceleration = mbVo.getObsLateralAcceleration();
                obsLongitudinalAcceleration = mbVo.getObsLongitudinalAcceleration();
                obsHeadingAngleRel = mbVo.getObsHeadingAngleRel();
                obsDurationTime = mbVo.getObsDurationTime();
                obsVelocityTime = mbVo.getObsVelocityTime();
                obsTrailTime = mbVo.getObsTrailTime();
                obsType = mbVo.getObsType();
            } else {
                obsStartX = obsStartX + ";" + mbVo.getObsStartX();
                obsStartY = obsStartY + ";" + mbVo.getObsStartY();
                obsStartVelocity = obsStartVelocity + ";" + mbVo.getObsStartVelocity();
                obsLateralAcceleration = obsLateralAcceleration + ";" + mbVo.getObsLateralAcceleration();
                obsLongitudinalAcceleration = obsLongitudinalAcceleration + ";" + mbVo.getObsLongitudinalAcceleration();
                obsHeadingAngleRel = obsHeadingAngleRel + ";" + mbVo.getObsHeadingAngleRel();
                obsDurationTime = obsDurationTime + ";" + mbVo.getObsDurationTime();
                obsVelocityTime = obsVelocityTime + ";" + mbVo.getObsVelocityTime();
                obsTrailTime = obsTrailTime + ";" + mbVo.getObsTrailTime();
                obsType = obsType + ";" + mbVo.getObsType();
            }
            a++;
        }

        po.setObsStartX(obsStartX);
        po.setObsStartY(obsStartY);
        po.setObsStartVelocity(obsStartVelocity);
        po.setObsLateralAcceleration(obsLateralAcceleration);
        po.setObsLongitudinalAcceleration(obsLongitudinalAcceleration);
        po.setObsHeadingAngleRel(obsHeadingAngleRel);
        po.setObsDurationTime(obsDurationTime);
        po.setObsVelocityTime(obsVelocityTime);
        po.setObsTrailTime(obsTrailTime);
        po.setObsType(obsType);
        //远程调用接口
        Map map = beanToMap(po);
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(2 * 60 * 1000)
                .setConnectTimeout(2 * 60 * 1000)
                .setConnectionRequestTimeout(2 * 6 * 10 * 1000)
                .setRedirectsEnabled(false)
                .setExpectContinueEnabled(false)
                .build();
        log.info("调用泛化接口：" + generalUrl + "请求参数为：" + map);

        final String generalResult = sceneUtil.callGeneralService(requestConfig, generalUrl, map);
        JsonNode params = JsonUtil.readTree(generalResult).get("params");

        // 实例化 ObjectMapper 对象
        ObjectMapper objectMapper = new ObjectMapper();
        String newjson = objectMapper.writeValueAsString(params);

        List<SceneGeneralDataPO> list = JsonUtil.jsonToList(newjson, SceneGeneralDataPO.class);
        //测试是否调用成功
        String sceneGeneralizationIds = null;
        //生成指标id
        String sublistId = StringUtil.getRandomUUID();
        //生成实例主键id
        String exampleId = StringUtil.getRandomUUID();
        for (SceneGeneralDataPO datePo : list) {
            //生成主键id
            String dataId = StringUtil.getRandomUUID();
            datePo.setId(dataId);
            datePo.setCreateTime(TimeUtil.getNowForMysql());
            datePo.setCreateUserId(AuthUtil.getCurrentUserId());
            datePo.setModifyTime(TimeUtil.getNowForMysql());
            datePo.setIsDeleted("0");
            datePo.setSceneId(po.getSceneId());
            datePo.setTemplateId(po.getId());
            datePo.setExampleId(exampleId);
            datePo.setSublistId(sublistId);
            if (ObjectUtil.isNotNull(sceneGeneralizationIds)) {
                sceneGeneralizationIds = sceneGeneralizationIds + "," + dataId;
            } else {
                sceneGeneralizationIds = dataId;
            }
        }
        dataMapper.saveSceneGeneralDataAll(list);
        po.setId(exampleId);
        po.setSublistId(sublistId);
        po.setCreateTime(TimeUtil.getNowForMysql());
        po.setSceneId(po.getSceneId());
        po.setCreateUserId(AuthUtil.getCurrentUserId());
        po.setModifyTime(TimeUtil.getNowForMysql());
        po.setIsDeleted("0");
        // po.setGeneralizationType(generalizationType);
        exampleMapper.saveSceneGeneralExample(po);
        // 暂时不要泛型，前端会报错
        Map map1 = new HashMap();
        map1.put("exampleId", exampleId);//实例id
        map1.put("sceneNum", list.size());//场景数量
        map1.put("templateId", po.getTemplateId()); //模板id
        map1.put("sceneGeneralizationIds", sceneGeneralizationIds);//泛化场景数组
        map1.put("sublistId", sublistId); //指标id

        log.info("测试是否调用成功---555555--" + map1);
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, map1);

    }

    /**
     * 对象转Map
     *
     */
    public Map beanToMap(Object object) throws IllegalAccessException {
        Map<String, Object> map = new HashMap<>();
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            map.put(field.getName(), field.get(object));
        }
        return map;
    }

}
