package com.fdkankan.ucenter.httpClient.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.util.FileUtils;
import com.fdkankan.fyun.face.FYunFileServiceInterface;
import com.fdkankan.rabbitmq.util.RabbitMqProducer;
import com.fdkankan.ucenter.common.Result;
import com.fdkankan.ucenter.common.constants.ResultCodeMsg;
import com.fdkankan.ucenter.entity.Camera;
import com.fdkankan.ucenter.entity.CameraDetail;
import com.fdkankan.ucenter.entity.CameraType;
import com.fdkankan.ucenter.entity.User;
import com.fdkankan.ucenter.httpClient.client.LaserClient;
import com.fdkankan.ucenter.httpClient.param.SSDownSceneParam;
import com.fdkankan.ucenter.httpClient.param.SsBindParam;
import com.fdkankan.ucenter.httpClient.vo.LaserSceneParam;
import com.fdkankan.ucenter.httpClient.vo.SSDownSceneVo;
import com.fdkankan.ucenter.httpClient.vo.SceneStatusInfoDTO;
import com.fdkankan.ucenter.mq.common.MqQueueUtil;
import com.fdkankan.ucenter.service.ICameraService;
import com.fdkankan.ucenter.service.ICameraTypeService;
import com.fdkankan.ucenter.service.IUserService;
import com.fdkankan.ucenter.vo.SceneBySnCodeVo;
import com.fdkankan.ucenter.vo.response.SceneNumVo;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.*;

@Service
@Slf4j
public class LaserService {

    @Autowired
    private LaserClient laserClient;
    @Autowired
    private IUserService userService;
    @Autowired
    ICameraService cameraService;
    @Autowired
    ICameraTypeService cameraTypeService;
    /**
     * 根据用户获取激光相机数量
     * @param token
     */
    public SceneNumVo getLaserSceneNumByUser(String token,Integer sceneSource) {
        SceneNumVo sceneNumVo = new SceneNumVo();
        try {
            HashMap<String,Object> param = new HashMap<>();
            param.put("sceneSource",sceneSource);
            Result sceneNum = laserClient.getSceneNum(token,param);
            if(sceneNum != null && sceneNum.getCode() == 200){
                sceneNumVo = JSONObject.parseObject(JSONObject.toJSONString(sceneNum.getData()), SceneNumVo.class);
                sceneNumVo.setTotalNum(sceneNumVo.getSceneNum() + sceneNumVo.getCooperationSceneNum());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return sceneNumVo ;
    }

    public Integer getLaserSceneNum(Map<String, String> params){
        Result result = laserClient.getSceneNumByCamera(params);
        if(result.getCode() == 200 ){
            return (Integer) result.getData();
        }
        return 0;
    }


    public void disableCooperation(HashMap<Long, CameraDetail> detailMap, HashMap<Long, Camera> cameraMap ){
        this.disableCooperation(getCooperationdDisableParam(detailMap,cameraMap));
    }
    public void enableCameraCooperation(HashMap<Long,CameraDetail> detailMap,HashMap<Long,Camera> cameraMap ,String username){
        this.enableCameraCooperation(getCooperationSaveParam(detailMap,cameraMap,username));
    }

    public void disableCooperation(List<Map<String, String>> params) {
        if(params.size() <=0){
            return;
        }
        laserClient.cooperationDisable(params);
    }

    public  List<Map<String, String>> getCooperationdDisableParam(HashMap<Long,CameraDetail> detailMap,HashMap<Long,Camera> cameraMap ){
        List<Map<String, String>> laserParams = new ArrayList<>();
        List<Long> userIds = new ArrayList<>();
        for (Long aLong : detailMap.keySet()) {
            if(detailMap.get(aLong).getCooperationUser()!=null){
                userIds.add(detailMap.get(aLong).getCooperationUser());
            }
        }
        if(userIds.size() >0){
            HashMap<Long, User> userMap = userService.getByIds(userIds);
            for (Long cameraId : detailMap.keySet()) {
                CameraDetail cameraDetail = detailMap.get(cameraId);
                CameraType cameraType = cameraTypeService.getByCameraType(cameraDetail.getType());
                if (cameraType.getIsLaser() == 1) {
                    Camera cameraEntity = cameraMap.get(cameraId);
                    Map<String, String> param = new HashMap<>();
                    param.put("snCode", cameraEntity.getSnCode());
                    String name = userMap.get(cameraDetail.getCooperationUser()) == null ?null : userMap.get(cameraDetail.getCooperationUser()).getUserName();
                    param.put("cooperationUserName", name);
                    laserParams.add(param);
                }
            }
        }
        return laserParams;
    }
    public  List<Map<String, String>> getCooperationSaveParam(HashMap<Long,CameraDetail> detailMap,HashMap<Long,Camera> cameraMap ,String username){
        List<Map<String, String>> laserParams = new ArrayList<>();
            for (Long cameraId : detailMap.keySet()) {
                CameraDetail cameraDetail = detailMap.get(cameraId);
                CameraType cameraType = cameraTypeService.getByCameraType(cameraDetail.getType());
                if (cameraType.getIsLaser() == 1) {
                    Camera cameraEntity = cameraMap.get(cameraId);
                    Map<String, String> param = new HashMap<>();
                    param.put("snCode", cameraEntity.getSnCode());
                    param.put("cooperationUserName", username);
                    laserParams.add(param);
                }
            }
        return laserParams;
    }

    public void enableCameraCooperation(List<Map<String, String>> params) {
        if(params.size() <=0){
            return;
        }
        laserClient.cooperationCameraSave(params);
    }

    public JSONObject getSceneByNum(String num) {
        Result result = laserClient.getSceneByNum(num);
        if(result.getCode() != HttpStatus.OK.value()){
            log.error("获取激光转台场景失败!");
            return null;
        }
        return JSONObject.parseObject(JSONObject.toJSONString(result.getData()));
    }


    public String copyDataSource( String oldDataSource,String dataSource) {
        //计算成功  激光转台相机推送
        log.info("激光转台相机 同步 请求 ");
        try {
            //创建目录
            if(oldDataSource.lastIndexOf("/")!=-1){
                oldDataSource = oldDataSource + "_laserData";
            }else{
                oldDataSource = oldDataSource.substring(0,oldDataSource.length()-1) + "_laserData";
            }

            if(dataSource.lastIndexOf("/")!=-1){
                dataSource = dataSource + "_laserData";
            }else{
                dataSource = dataSource.substring(0,dataSource.length()-1) + "_laserData";
            }

            FileUtils.copyDirectiory(oldDataSource  ,dataSource);

            return  dataSource + File.separator + "laserData";

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


    public void copy(String oldNum , String newNum, String  path,Boolean flag){
        Map<String,Object> params = new HashMap<>();
        params.put("sceneCode", newNum);
        params.put("oldSceneCode", oldNum);
        params.put("path",path);
        params.put("init",flag);

        if(flag){
            rabbitMqProducer.sendByWorkQueue(laserInitCopyScene,params);
            return;
        }
        rabbitMqProducer.sendByWorkQueue(laserCopyScene,params);
    }

    public List<SceneBySnCodeVo> getScenesBySnCode(String snCode, String token) {
        List<SceneBySnCodeVo> sceneVo = new ArrayList<>();
        try {
            HashMap<String ,String> param = new HashMap<>();
            param.put("snCode",snCode);
            Result responseEntity = laserClient.getScenesBySnCode(param, token);
            if( responseEntity.getCode() != HttpStatus.OK.value()){
                log.error("根据snCode获取激光转台场景失败!");
                return sceneVo;
            }
            sceneVo = JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getData()), List.class);
        }catch (Exception e){
            log.error("根据snCode获取激光转台场景失败!",e);
        }
        return sceneVo ;
    }
    public SSDownSceneVo downOfflineSceneStatus(String num) {
        try {
            SSDownSceneVo vo ;
            SSDownSceneParam param = new SSDownSceneParam();
            param.setSceneCode(num);
            Result responseEntity = laserClient.downOfflineSceneStatus(param);
            if( responseEntity.getCode() != HttpStatus.OK.value()){
                log.error("downOfflineSceneStatus-根据场景码获取激光转台下载状态失败:{}",responseEntity);
                return null;
            }
            vo = JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getData()), SSDownSceneVo.class);
            return vo;

        }catch (Exception e){
            log.error("downOfflineSceneStatus-根据场景码获取激光转台下载状态失败!",e);
        }
        return null ;
    }

    public SSDownSceneVo downOfflineScene(String num) {
        try {
            SSDownSceneVo vo ;
            SSDownSceneParam param = new SSDownSceneParam();
            param.setSceneCode(num);
            Result responseEntity = laserClient.downOfflineScene(param);
            if( responseEntity.getCode() != HttpStatus.OK.value()){
                log.error("downOfflineScene-根据场景码获取激光转台下载失败:{}",responseEntity);
                return null;
            }
            vo = JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getData()), SSDownSceneVo.class);
            return vo ;
        }catch (Exception e){
            log.error("downOfflineScene-根据场景码获取激光转台下载状态失败!",e);
        }
        return null ;
    }

    public void delete(String num) {
        HashMap<String,Object> map = new HashMap<>();
        map.put("numList",Arrays.asList(num));
        rabbitMqProducer.sendByWorkQueue(MqQueueUtil.laserDeleteScene,map);

    }


    @Autowired
    private FYunFileServiceInterface fYunFileService;
    @Autowired
    private RabbitMqProducer rabbitMqProducer;

    @Value("${4dkk.laserService.cloud-point-fyun-path:testdata/%s/data/bundle_%s/building/}")
    private String cloudPointFyunPath;
    @Value("${4dkk.laserService.bucket:laser-data}")
    private String bucket;
    @Value("${queue.application.laser.cloud-point-build:laser-cloud-point-build}")
    private String cloudPointBuild;
    @Value("${queue.application.laser.copy-scene:laser-copy-scene}")
    private String laserCopyScene;
    @Value("${queue.application.laser.copy-scene:laser-copy-scene-init}")
    private String laserInitCopyScene;



    public void cloudPointBuild(String oldSceneCode,String sceneCode) {
        if (!fYunFileService.fileExist(bucket,String.format(cloudPointFyunPath,oldSceneCode,oldSceneCode) +"vision_edit.txt")){
            return;
        }
        log.info("开始同步点云编辑文件");
        // 上传点云编辑文件，并通知激光系统
        fYunFileService.copyFileBetweenBucket(bucket,String.format(cloudPointFyunPath,oldSceneCode,oldSceneCode) + "vision_edit.txt",
                bucket,String.format(cloudPointFyunPath,sceneCode,sceneCode) + "vision_edit.txt");

        fYunFileService.copyFileBetweenBucket(bucket,String.format(cloudPointFyunPath,oldSceneCode,oldSceneCode) + "uuidcloud",
                bucket,String.format(cloudPointFyunPath,sceneCode,sceneCode) + "uuidcloud");

        Map<String, Object> params = new HashMap<>();
        params.put("sceneNum", sceneCode);
        params.put("businessType", 0);
        rabbitMqProducer.sendByWorkQueue(cloudPointBuild, params);
    }

    public void toBind(Boolean bind,String snCode,String userName,Long userId) {
        try {
            SsBindParam param = new SsBindParam();
            param.setBind(bind);
            param.setSnCode(Lists.newArrayList(snCode));
            param.setPhone(userName);
            param.setUserId(userId);
            Result responseEntity = laserClient.toBind(param);
            if( responseEntity.getCode() != HttpStatus.OK.value()){
                log.error("解绑用户激光转台下载失败:{}",responseEntity);
            }
        }catch (Exception e){
            log.error("解绑用户获取激光转台下载状态失败!",e);
        }
    }

    public void updateStatus(List<String> numList, Integer payStatus) {
        Map<String,Object> params = new HashMap<>();
        params.put("sceneCodes", numList);
        params.put("payStatus", payStatus);
        rabbitMqProducer.sendByWorkQueue("update-laser-scene-status" ,params);
        //return laserClient.updateStatus( params);
    }
    public void updatePanoStatus(List<String> numList, Integer payStatus) {
        Map<String,Object> params = new HashMap<>();
        params.put("sceneCodes", numList);
        params.put("payStatus", payStatus);
        rabbitMqProducer.sendByWorkQueue("pano-paystatus-scene-queue" ,params);
        //return laserClient.updateStatus( params);
    }


    public HashMap<String, JSONObject> list(List<String> sceneNumList,Integer sceneSource) {
        LaserSceneParam newParam = new LaserSceneParam();
        newParam.setPageNum(1);
        newParam.setSceneSource(sceneSource);
        newParam.setPageSize(sceneNumList.size());
        newParam.setSceneCodes(sceneNumList);
        return this.list(newParam);
    }
    public HashMap<String, JSONObject> list(List<String> sceneNumList,Integer status,Integer sceneSource) {
        LaserSceneParam newParam = new LaserSceneParam();
        newParam.setPageNum(1);
        newParam.setSceneSource(sceneSource);
        newParam.setPageSize(sceneNumList.size());
        newParam.setSceneCodes(sceneNumList);
        newParam.setStatus(status);
        return this.list(newParam);
    }

    public HashMap<String, JSONObject> list(LaserSceneParam newParam) {
        HashMap<String, JSONObject> map = new HashMap<>();
        Result fdkkResponse = laserClient.sceneList(newParam);
        JSONObject jsonObject = (JSONObject) fdkkResponse.getData();
        if(jsonObject == null){
            return map;
        }
        JSONArray list = jsonObject.getJSONArray("list");

        for (Object o : list) {
            JSONObject obj = (JSONObject) o;
            map.put(obj.getString("num"),obj);
        }
        return map;
    }


    public SSDownSceneVo downE57Status(String num,String splitType) {
        try {
            SSDownSceneVo vo ;
            SSDownSceneParam param = new SSDownSceneParam();
            param.setSceneCode(num);
            param.setSplitType(splitType);
            Result responseEntity = laserClient.downE57Status(param);
            if( responseEntity.getCode() != HttpStatus.OK.value()){
                log.error("downE57Status-根据场景码获取激光转台下载状态失败:{}",responseEntity);
                return null;
            }
            if(responseEntity.getCode() == 407){
                throw new BusinessException(ResultCodeMsg.FAILURE_CODE_400011, ResultCodeMsg.FAILURE_MSG_400011);
            }
            vo = JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getData()), SSDownSceneVo.class);
            return vo;

        }catch (BusinessException e){
            throw new BusinessException(ResultCodeMsg.FAILURE_CODE_400011, ResultCodeMsg.FAILURE_MSG_400011);
        }catch (Exception e){
            log.error("downE57Status-根据场景码获取激光转台下载状态失败!",e);
        }
        return null ;
    }

    public SSDownSceneVo downE57(String num,String splitType) {
        try {
            SSDownSceneVo vo ;
            SSDownSceneParam param = new SSDownSceneParam();
            param.setSceneCode(num);
            param.setSplitType(splitType);
            Result responseEntity = laserClient.downE57(param);
            if( responseEntity.getCode() != HttpStatus.OK.value()){
                log.error("downE57-根据场景码获取激光转台下载失败:{}",responseEntity);
                return null;
            }
            if(responseEntity.getCode() == 407){
                throw new BusinessException(ResultCodeMsg.FAILURE_CODE_400011, ResultCodeMsg.FAILURE_MSG_400011);
            }
            vo = JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getData()), SSDownSceneVo.class);
            return vo ;
        }catch (BusinessException e){
            throw new BusinessException(ResultCodeMsg.FAILURE_CODE_400011, ResultCodeMsg.FAILURE_MSG_400011);
        }catch (Exception e){
            log.error("downE57-根据场景码获取激光转台下载状态失败!",e);
        }
        return null ;
    }
    public SceneStatusInfoDTO laserSceneInfo(String num) {
        try {
            SceneStatusInfoDTO vo ;
            Result responseEntity = laserClient.laserSceneInfo(num);
            if( responseEntity.getCode() != HttpStatus.OK.value()){
                log.error("LaserSceneInfo-根据场景码获取激光转台下载失败:{}",responseEntity);
                return null;
            }
            if(responseEntity.getCode() == 407){
                throw new BusinessException(ResultCodeMsg.FAILURE_CODE_400011, ResultCodeMsg.FAILURE_MSG_400011);
            }
            vo = JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getData()), SceneStatusInfoDTO.class);
            return vo ;
        }catch (BusinessException e){
            throw new BusinessException(ResultCodeMsg.FAILURE_CODE_400011, ResultCodeMsg.FAILURE_MSG_400011);
        }catch (Exception e){
            log.error("LaserSceneInfo-根据场景码获取激光转台下载状态失败!",e);
        }
        return null ;
    }

    public void saveBatchCooperation(List<String> numList2,List<String> snCodeList, List<String> userNameList,String type,String operatingMode) {
        log.info(numList2.size() +"---------"+snCodeList.size());
        if(numList2.isEmpty() && snCodeList.isEmpty()){
            return;
        }
        HashMap<String,Object> map = new HashMap<>();
        map.put("numList",numList2);
        map.put("type",type);
        map.put("snCodeList",snCodeList);
        map.put("userNameList",userNameList);
        map.put("operatingMode",operatingMode);
        rabbitMqProducer.sendByWorkQueue("laser-batch-save-cooperation",map);
    }
}
