package com.ruoyi.system.service.impl;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.constant.AMapConstants;
import com.ruoyi.common.core.domain.AMapResult;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.system.domain.TElectronicFenceKey;
import com.ruoyi.system.domain.TElectronicFenceService;
import com.ruoyi.system.domain.to.*;
import com.ruoyi.system.domain.vo.AMapFenceVo;
import com.ruoyi.system.domain.vo.ElectronicFenceVo;
import com.ruoyi.system.mapper.TElectronicFenceMapper;
import com.ruoyi.system.service.ITElectronicFenceKeyService;
import com.ruoyi.system.service.ITElectronicFenceServiceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.domain.TElectronicFence;
import com.ruoyi.system.service.ITElectronicFenceService;
import org.springframework.validation.annotation.Validated;

/**
 * 【请填写功能名称】Service业务层处理
 *
 * @author ruoyi
 * @date 2023-09-14
 */
@Service
public class TElectronicFenceServiceImpl implements ITElectronicFenceService {
    private static final Logger log = LoggerFactory.getLogger(TElectronicFenceServiceImpl.class);

    @Autowired
    private TElectronicFenceMapper tElectronicFenceMapper;
    @Autowired
    private ITElectronicFenceKeyService iElectronicFenceKeyService;
    @Autowired
    private ITElectronicFenceServiceService iElectronicFenceServiceService;

    /**
     * 查询【请填写功能名称】
     *
     * @param id 【请填写功能名称】主键
     * @return 【请填写功能名称】
     */
    @Override
    public TElectronicFence selectTElectronicFenceById(Long id) {
        return tElectronicFenceMapper.selectTElectronicFenceById(id);
    }

    /**
     * 查询【请填写功能名称】列表
     *
     * @param tElectronicFence 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public List<TElectronicFence> selectTElectronicFenceList(TElectronicFence tElectronicFence) {
        //查询未删除窗台
        tElectronicFence.setDelState(1);
        return tElectronicFenceMapper.selectTElectronicFenceList(tElectronicFence);
    }

    /**
     * 新增【请填写功能名称】
     *
     * @param tElectronicFence 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int insertTElectronicFence(TElectronicFence tElectronicFence) {
        tElectronicFence.setCreateTime(DateUtils.getNowDate());
        return tElectronicFenceMapper.insertTElectronicFence(tElectronicFence);
    }

    /**
     * 修改【请填写功能名称】
     *
     * @param tElectronicFence 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int updateTElectronicFence(TElectronicFence tElectronicFence) {
        tElectronicFence.setUpdateTime(DateUtils.getNowDate());
        return tElectronicFenceMapper.updateTElectronicFence(tElectronicFence);
    }

    /**
     * 批量删除【请填写功能名称】
     *
     * @param ids 需要删除的【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteTElectronicFenceByIds(Long[] ids) {
        /**
         * TODO 队列MQ删除高德围栏，现阶段直接更改围栏状态为删除
         */
        return tElectronicFenceMapper.deleteTElectronicFenceStateByIds(ids);
    }

    /**
     * 删除【请填写功能名称】信息
     *
     * @param id 【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteTElectronicFenceById(Long id) {
        return tElectronicFenceMapper.deleteTElectronicFenceById(id);
    }

    @Override
    public int insertTElectronicFenceVo(ElectronicFenceVo electronicFenceVo) {
        if (electronicFenceVo.getGeofence_type() == 0) {
            //围栏-圆形
            return trackGeofenceAddCircle(electronicFenceVo);
        } else if (electronicFenceVo.getGeofence_type() == 1) {
            //围栏-多边形围栏
            return trackGeofenceAddPolygon(electronicFenceVo);
        } else if (electronicFenceVo.getGeofence_type() == 2) {
            //围栏-线形围栏
            return trackGeofenceAddPolyline(electronicFenceVo);
        } else if (electronicFenceVo.getGeofence_type() == 3) {
            //围栏-行政区划围栏
            return trackGeofenceAddDistrict(electronicFenceVo);
        } else {
            log.error("创建围栏类型不匹配，类型：{}.", electronicFenceVo.getGeofence_type());
            throw new ServiceException("创建围栏类型不匹配！");
        }
    }

    @Override
    public List<AMapFenceVo> selectTElectronicFenceListByDeviceId(Long deviceId) {
        List<TElectronicFence> tElectronicFences = tElectronicFenceMapper.selectTElectronicFenceListByDeviceId(deviceId);
        if (tElectronicFences == null || tElectronicFences.isEmpty()) {
            log.info("通过deviceId查询围栏，返回结果为空 ，deviceId：{}！", deviceId);
            return null;
        }
        List<AMapFenceVo> electronicFenceVos = tElectronicFences.stream()
                .map(tElectronicFence -> {
                    TElectronicFenceService fenceService = iElectronicFenceServiceService.selectTElectronicFenceServiceById(tElectronicFence.getServiceId());
                    TElectronicFenceKey tElectronicFenceKey = iElectronicFenceKeyService.selectTElectronicFenceKeyById(fenceService.getKeyId());
                    AMapFenceVo aMapFenceVo = new AMapFenceVo();
                    aMapFenceVo.setId(tElectronicFence.getId());
                    aMapFenceVo.setKey(tElectronicFenceKey.getAmapKey());
                    aMapFenceVo.setSid(fenceService.getAmapSid());
                    aMapFenceVo.setGfid(tElectronicFence.getGfid());
                    aMapFenceVo.setUserId(tElectronicFence.getUserId());
                    aMapFenceVo.setDeviceId(tElectronicFence.getDeviceId());
                    aMapFenceVo.setName(tElectronicFence.getName());
                    aMapFenceVo.setStartTime(convertToCurrentDateTimestamp(tElectronicFence.getStartTime().getTime()));
                    aMapFenceVo.setEndTime(convertToCurrentDateTimestamp(tElectronicFence.getEndTime().getTime()));
                    aMapFenceVo.setState(tElectronicFence.geteState());
                    aMapFenceVo.setType(tElectronicFence.geteType());
                    aMapFenceVo.setDesc(tElectronicFence.geteDesc());
                    return aMapFenceVo;
                })
                .collect(Collectors.toList());
        return electronicFenceVos;
    }

    public static Long convertToCurrentDateTimestamp(long timestamp) {
        // 将时间戳转换为LocalDateTime对象
        LocalDateTime dateTime = LocalDateTime.ofEpochSecond(timestamp, 0, ZoneOffset.UTC);
        // 获取当前日期
        LocalDateTime currentDate = LocalDateTime.now().withHour(dateTime.getHour())
                .withMinute(dateTime.getMinute())
                .withSecond(dateTime.getSecond());
        // 将当前日期转换为时间戳
        long currentTimestamp = currentDate.toEpochSecond(ZoneOffset.UTC);
        return currentTimestamp;
    }

    @Override
    public int updateTElectronicFenceEditVo(ElectronicFenceVo tElectronicFenceEditVo) {
        //校验围栏类型是否为空
        if (tElectronicFenceEditVo.getGeofence_type() == null) {
            log.error("更新围栏禁止围栏类型为空，id：{}.", tElectronicFenceEditVo.getId());
            throw new ServiceException("更新围栏禁止围栏类型为空！");
        }
        //查询库中的围栏信息
        TElectronicFence tElectronicFence = tElectronicFenceMapper.selectTElectronicFenceById(tElectronicFenceEditVo.getId());
        if (tElectronicFence == null) {
            log.error("获取本地围栏为空.");
            throw new ServiceException("获取本地围栏为空！");
        }
        TElectronicFenceService fenceService = iElectronicFenceServiceService.selectTElectronicFenceServiceById(tElectronicFence.getServiceId());
        if (fenceService == null) {
            log.error("围栏对应的高德服务为空，围栏ID：{}.", tElectronicFence.getServiceId());
            throw new ServiceException("围栏对应的高德服务为空！");
        }
        TElectronicFenceKey tElectronicFenceKey = iElectronicFenceKeyService.selectTElectronicFenceKeyById(fenceService.getKeyId());
        if (tElectronicFenceKey == null) {
            log.error("围栏对应的高德key为空，围栏ID：{}. 服务ID：{}", tElectronicFence.getId(), tElectronicFence.getServiceId());
            throw new ServiceException("围栏对应的高德key为空！");
        }
        //更新数据库围栏信息
        TElectronicFence fence = new TElectronicFence();
        fence.setId(tElectronicFenceEditVo.getId());
        //围栏昵称
        if (!StringUtils.isEmpty(tElectronicFenceEditVo.getName())) {
            fence.setName(tElectronicFenceEditVo.getName());
        }
        //围栏开始时间
        if (tElectronicFenceEditVo.getStart_time() != null && tElectronicFenceEditVo.getStart_time() > 0) {
            fence.setStartTime(new Date(tElectronicFenceEditVo.getStart_time()));
        }
        //围栏结束时间
        if (tElectronicFenceEditVo.getEnd_time() != null && tElectronicFenceEditVo.getEnd_time() > 0) {
            fence.setEndTime(new Date(tElectronicFenceEditVo.getEnd_time()));
        }
        //围栏状态：（0：关闭 1：开启）
        if (tElectronicFenceEditVo.getState() != null && tElectronicFenceEditVo.getState() >= 0 && tElectronicFenceEditVo.getState() <= 1) {
            fence.seteState(tElectronicFenceEditVo.getState());
        }
        //围栏开启状态（0：默认 1：禁止离开 2：禁止进入）
        if (tElectronicFenceEditVo.getType() != null && tElectronicFenceEditVo.getState() >= 0 && tElectronicFenceEditVo.getState() <= 2) {
            fence.seteType(tElectronicFenceEditVo.getType());
        }
        //描述
        if (tElectronicFenceEditVo.getDesc() != null && !StringUtils.isEmpty(tElectronicFenceEditVo.getDesc())) {
            fence.seteDesc(tElectronicFenceEditVo.getDesc());
        }
        //更新围栏
        String gfid = null;
        if (tElectronicFenceEditVo.getGeofence_type() == 0) {
            //围栏-圆形
            gfid = trackGeofenceUpdateCircle(tElectronicFenceEditVo, tElectronicFenceKey, fenceService, tElectronicFence);
        } else if (tElectronicFenceEditVo.getGeofence_type() == 1) {
            //围栏-多边形围栏
            gfid = trackGeofenceUpdatePolygon(tElectronicFenceEditVo, tElectronicFenceKey, fenceService, tElectronicFence);
        } else if (tElectronicFenceEditVo.getGeofence_type() == 2) {
            //围栏-线形围栏
            gfid = trackGeofenceUpdatePolyline(tElectronicFenceEditVo, tElectronicFenceKey, fenceService, tElectronicFence);
        } else if (tElectronicFenceEditVo.getGeofence_type() == 3) {
            //围栏-行政区划围栏
            gfid = trackGeofenceUpdateDistrict(tElectronicFenceEditVo, tElectronicFenceKey, fenceService, tElectronicFence);
        } else {
            log.error("更新围栏禁止围栏类型为不匹配，id：{}.", tElectronicFenceEditVo.getId());
            throw new ServiceException("更新围栏禁止围栏类型为不匹配！");
        }
        //更新围栏失败
        if (gfid == null || StringUtils.isEmpty(gfid)) {
            log.error("更新围栏失败，id：{}.", tElectronicFenceEditVo.getId());
            throw new ServiceException("更新围栏失败！");
        }
        //围栏的唯一标识
        fence.setGfid(gfid);
        //围栏服务ID
        fence.setServiceId(fenceService.getId());
        //更新时间
        fence.setUpdateTime(DateUtils.getNowDate());
        return tElectronicFenceMapper.updateTElectronicFence(fence);
    }


    /**
     * 创建围栏-圆形
     */
    private int trackGeofenceAddCircle(ElectronicFenceVo fenceVo) {
        //获取所有高德Key
        TElectronicFenceKey electronicFenceKey = iElectronicFenceKeyService.selectAccessAvailableElectronicFenceKey();
        if (electronicFenceKey == null) {
            log.error("获取高德所有amap_key为空.");
            throw new ServiceException("获取所有高德amap_key为空！");
        }
        //通过key查询service（每个 Key 下最多注册15个 Service）
        TElectronicFenceService electronicFenceService = iElectronicFenceServiceService.selectAccessAvailableElectronicFenceServiceByKeyId(electronicFenceKey.getId());
        if (electronicFenceService == null) {
            log.error("获取高德所有amap_service为空,key:{}", electronicFenceKey.getAmapKey());
            throw new ServiceException("获取所有高德amap_service为空！");
        }
        //通过service创建围栏（一个service下最多可创建1000个围栏）
        String gfid = sendGeoAddCircle(electronicFenceKey, electronicFenceService, fenceVo);
        if (StringUtils.isEmpty(gfid)) {
            log.error("创建高德围栏异常!");
            throw new ServiceException("创建高德围栏异常！");
        }
        //存储围栏信息
        TElectronicFence tElectronicFence = new TElectronicFence();
        tElectronicFence.setName(fenceVo.getName());
        tElectronicFence.setStartTime(new Date(fenceVo.getStart_time()));
        tElectronicFence.setEndTime(new Date(fenceVo.getEnd_time()));
        tElectronicFence.seteState(fenceVo.getState());
        tElectronicFence.seteType(fenceVo.getType());
        tElectronicFence.setGfid(gfid);
        tElectronicFence.setUserId(fenceVo.getUsdId());
        tElectronicFence.setDeviceId(fenceVo.getDeviceId());
        tElectronicFence.setServiceId(electronicFenceService.getId());
        tElectronicFence.setCreateTime(DateUtils.getNowDate());
        return tElectronicFenceMapper.insertTElectronicFence(tElectronicFence);
    }

    /**
     * 创建围栏-多边形围栏
     */
    private int trackGeofenceAddPolygon(ElectronicFenceVo fenceVo) {
        //获取所有高德Key
        TElectronicFenceKey electronicFenceKey = iElectronicFenceKeyService.selectAccessAvailableElectronicFenceKey();
        if (electronicFenceKey == null) {
            log.error("获取高德所有amap_key为空.");
            throw new ServiceException("获取所有高德amap_key为空！");
        }
        //通过key查询service（每个 Key 下最多注册15个 Service）
        TElectronicFenceService electronicFenceService = iElectronicFenceServiceService.selectAccessAvailableElectronicFenceServiceByKeyId(electronicFenceKey.getId());
        if (electronicFenceService == null) {
            log.error("获取高德所有amap_service为空,key:{}", electronicFenceKey.getAmapKey());
            throw new ServiceException("获取所有高德amap_service为空！");
        }
        //通过service创建围栏（一个service下最多可创建1000个围栏）
        String gfid = sendGeoAddPolygon(electronicFenceKey, electronicFenceService, fenceVo);
        if (StringUtils.isEmpty(gfid)) {
            log.error("创建高德围栏异常!");
            throw new ServiceException("创建高德围栏异常！");
        }
        //存储围栏信息
        TElectronicFence tElectronicFence = new TElectronicFence();
        tElectronicFence.setName(fenceVo.getName());
        tElectronicFence.setStartTime(new Date(fenceVo.getStart_time()));
        tElectronicFence.setEndTime(new Date(fenceVo.getEnd_time()));
        tElectronicFence.seteState(fenceVo.getState());
        tElectronicFence.seteType(fenceVo.getType());
        tElectronicFence.setGfid(gfid);
        tElectronicFence.setUserId(fenceVo.getUsdId());
        tElectronicFence.setDeviceId(fenceVo.getDeviceId());
        tElectronicFence.setServiceId(electronicFenceService.getId());
        tElectronicFence.setCreateTime(DateUtils.getNowDate());
        return tElectronicFenceMapper.insertTElectronicFence(tElectronicFence);
    }

    /**
     * 创建围栏-线形围栏
     */
    private int trackGeofenceAddPolyline(ElectronicFenceVo fenceVo) {
        //获取所有高德Key
        TElectronicFenceKey electronicFenceKey = iElectronicFenceKeyService.selectAccessAvailableElectronicFenceKey();
        if (electronicFenceKey == null) {
            log.error("获取高德所有amap_key为空.");
            throw new ServiceException("获取所有高德amap_key为空！");
        }
        //通过key查询service（每个 Key 下最多注册15个 Service）
        TElectronicFenceService electronicFenceService = iElectronicFenceServiceService.selectAccessAvailableElectronicFenceServiceByKeyId(electronicFenceKey.getId());
        if (electronicFenceService == null) {
            log.error("获取高德所有amap_service为空,key:{}", electronicFenceKey.getAmapKey());
            throw new ServiceException("获取所有高德amap_service为空！");
        }
        //通过service创建围栏（一个service下最多可创建1000个围栏）
        String gfid = sendGeoAddPolyline(electronicFenceKey, electronicFenceService, fenceVo);
        if (StringUtils.isEmpty(gfid)) {
            log.error("创建高德围栏异常!");
            throw new ServiceException("创建高德围栏异常！");
        }
        //存储围栏信息
        TElectronicFence tElectronicFence = new TElectronicFence();
        tElectronicFence.setName(fenceVo.getName());
        tElectronicFence.setStartTime(new Date(fenceVo.getStart_time()));
        tElectronicFence.setEndTime(new Date(fenceVo.getEnd_time()));
        tElectronicFence.seteState(fenceVo.getState());
        tElectronicFence.seteType(fenceVo.getType());
        tElectronicFence.setGfid(gfid);
        tElectronicFence.setUserId(fenceVo.getUsdId());
        tElectronicFence.setDeviceId(fenceVo.getDeviceId());
        tElectronicFence.setServiceId(electronicFenceService.getId());
        tElectronicFence.setCreateTime(DateUtils.getNowDate());
        return tElectronicFenceMapper.insertTElectronicFence(tElectronicFence);
    }

    /**
     * 创建围栏-行政区划围栏
     */
    private int trackGeofenceAddDistrict(ElectronicFenceVo fenceVo) {
        //获取所有高德Key
        TElectronicFenceKey electronicFenceKey = iElectronicFenceKeyService.selectAccessAvailableElectronicFenceKey();
        if (electronicFenceKey == null) {
            log.error("获取高德所有amap_key为空.");
            throw new ServiceException("获取所有高德amap_key为空！");
        }
        //通过key查询service（每个 Key 下最多注册15个 Service）
        TElectronicFenceService electronicFenceService = iElectronicFenceServiceService.selectAccessAvailableElectronicFenceServiceByKeyId(electronicFenceKey.getId());
        if (electronicFenceService == null) {
            log.error("获取高德所有amap_service为空,key:{}", electronicFenceKey.getAmapKey());
            throw new ServiceException("获取所有高德amap_service为空！");
        }
        //通过service创建围栏（一个service下最多可创建1000个围栏）
        String gfid = sendGeoAddDistrict(electronicFenceKey, electronicFenceService, fenceVo);
        if (StringUtils.isEmpty(gfid)) {
            log.error("创建高德围栏异常!");
            throw new ServiceException("创建高德围栏异常！");
        }
        //存储围栏信息
        TElectronicFence tElectronicFence = new TElectronicFence();
        tElectronicFence.setName(fenceVo.getName());
        tElectronicFence.setStartTime(new Date(fenceVo.getStart_time()));
        tElectronicFence.setEndTime(new Date(fenceVo.getEnd_time()));
        tElectronicFence.seteState(fenceVo.getState());
        tElectronicFence.seteType(fenceVo.getType());
        tElectronicFence.setGfid(gfid);
        tElectronicFence.setUserId(fenceVo.getUsdId());
        tElectronicFence.setDeviceId(fenceVo.getDeviceId());
        tElectronicFence.setServiceId(electronicFenceService.getId());
        tElectronicFence.setCreateTime(DateUtils.getNowDate());
        return tElectronicFenceMapper.insertTElectronicFence(tElectronicFence);
    }

    /**
     * 通过高德接口创建圆形围栏
     *
     * @param fenceKey
     * @param fenceService
     * @param fenceVo
     * @return
     */
    private String sendGeoAddCircle(TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, ElectronicFenceVo fenceVo) {
        //创建圆形围栏
        Map<Object, Object> params = new HashMap();
        params.put("key", fenceKey.getAmapKey());
        params.put("sid", fenceService.getAmapSid());
        params.put("name", fenceVo.getName());
        if (!StringUtils.isEmpty(fenceVo.getDesc())) {
            params.put("desc", fenceVo.getDesc());
        }
        params.put("center", fenceVo.getCenter());
        params.put("radius", fenceVo.getRadius());
        String paramsString = HttpUtils.getParamsToString(params);
        // 去掉最后一个"&"符号
        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_ADD_CIRCLE, paramsString);
        log.info("创建高德围栏Url：{} ,\n返回结果：{}", AMapConstants.AMAP_GEOFENCE_ADD_CIRCLE + "?" + paramsString, result);
        AMapResult<Map<String, String>> aMapResult = JSONObject.parseObject(result, AMapResult.class);
        if (aMapResult != null && aMapResult.getData() != null && aMapResult.getData().containsKey("gfid")) {
            return String.valueOf(aMapResult.getData().get("gfid"));
        }
        log.info("创建高德围栏异常，key：{} ，code：{} ,msg:{}", fenceKey.getAmapKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
        throw new ServiceException("创建高德围栏异常，msg：" + aMapResult.getErrdetail() + " ！");
    }

    /**
     * 通过高德接口创建多边形围栏
     *
     * @param fenceKey
     * @param fenceService
     * @param fenceVo
     * @return
     */
    private String sendGeoAddPolygon(TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, ElectronicFenceVo fenceVo) {
        //创建圆形围栏
        Map<Object, Object> params = new HashMap();
        params.put("key", fenceKey.getAmapKey());
        params.put("sid", fenceService.getAmapSid());
        params.put("name", fenceVo.getName());
        if (!StringUtils.isEmpty(fenceVo.getDesc())) {
            params.put("desc", fenceVo.getDesc());
        }
        params.put("points", fenceVo.getPoints());
        String paramsString = HttpUtils.getParamsToString(params);
        // 去掉最后一个"&"符号
        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_ADD_POLYGON, paramsString);
        log.info("创建高德围栏Url：{} ,\n返回结果：{}", AMapConstants.AMAP_GEOFENCE_ADD_POLYGON + "?" + paramsString, result);
        AMapResult<Map<String, String>> aMapResult = JSONObject.parseObject(result, AMapResult.class);
        if (aMapResult != null && aMapResult.getData() != null && aMapResult.getData().containsKey("gfid")) {
            return String.valueOf(aMapResult.getData().get("gfid"));
        }
        log.info("创建高德围栏异常，key：{} ，code：{} ,msg:{}", fenceKey.getAmapKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
        throw new ServiceException("创建高德围栏异常，msg：" + aMapResult.getErrdetail() + " ！");
    }

    /**
     * 通过高德接口创建线形围栏
     *
     * @param fenceKey
     * @param fenceService
     * @param fenceVo
     * @return
     */
    private String sendGeoAddPolyline(TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, ElectronicFenceVo fenceVo) {
        //创建圆形围栏
        Map<Object, Object> params = new HashMap();
        params.put("key", fenceKey.getAmapKey());
        params.put("sid", fenceService.getAmapSid());
        params.put("name", fenceVo.getName());
        if (!StringUtils.isEmpty(fenceVo.getDesc())) {
            params.put("desc", fenceVo.getDesc());
        }
        params.put("points", fenceVo.getCenter());
        params.put("bufferradius", fenceVo.getBufferradius());
        String paramsString = HttpUtils.getParamsToString(params);
        // 去掉最后一个"&"符号
        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_ADD_POLYLINE, paramsString);
        log.info("创建高德围栏Url：{} ,\n返回结果：{}", AMapConstants.AMAP_GEOFENCE_ADD_POLYLINE + "?" + paramsString, result);
        AMapResult<Map<String, String>> aMapResult = JSONObject.parseObject(result, AMapResult.class);
        if (aMapResult != null && aMapResult.getData() != null && aMapResult.getData().containsKey("gfid")) {
            return String.valueOf(aMapResult.getData().get("gfid"));
        }
        log.info("创建高德围栏异常，key：{} ，code：{} ,msg:{}", fenceKey.getAmapKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
        throw new ServiceException("创建高德围栏异常，msg：" + aMapResult.getErrdetail() + " ！");
    }

    /**
     * 通过高德接口创建行政区划围栏
     *
     * @param fenceKey
     * @param fenceService
     * @param fenceVo
     * @return
     */
    private String sendGeoAddDistrict(TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, ElectronicFenceVo fenceVo) {
        //创建圆形围栏
        Map<Object, Object> params = new HashMap();
        params.put("key", fenceKey.getAmapKey());
        params.put("sid", fenceService.getAmapSid());
        params.put("name", fenceVo.getName());
        if (!StringUtils.isEmpty(fenceVo.getDesc())) {
            params.put("desc", fenceVo.getDesc());
        }
        params.put("adcode", fenceVo.getAdcode());
        String paramsString = HttpUtils.getParamsToString(params);
        // 去掉最后一个"&"符号
        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_ADD_DISTRICT, paramsString);
        log.info("创建高德围栏Url：{} ,\n返回结果：{}", AMapConstants.AMAP_GEOFENCE_ADD_DISTRICT + "?" + paramsString, result);
        AMapResult<Map<String, String>> aMapResult = JSONObject.parseObject(result, AMapResult.class);
        if (aMapResult != null && aMapResult.getData() != null && aMapResult.getData().containsKey("gfid")) {
            return String.valueOf(aMapResult.getData().get("gfid"));
        }
        log.info("创建高德围栏异常，key：{} ，code：{} ,msg:{}", fenceKey.getAmapKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
        throw new ServiceException("创建高德围栏异常，msg：" + aMapResult.getErrdetail() + " ！");
    }

    /**
     * 通过高德接口删除围栏
     *
     * @param fenceKey
     * @param fenceService
     * @param gfids
     * @return
     */
    private String sendGeoDel(TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, String gfids) {
        //创建圆形围栏
        Map<Object, Object> params = new HashMap();
        params.put("key", fenceKey.getAmapKey());
        params.put("sid", fenceService.getAmapSid());
        params.put("gfids", gfids);
        String paramsString = HttpUtils.getParamsToString(params);
        // 去掉最后一个"&"符号
        String result = HttpUtils.sendPost(AMapConstants.AMAP_TRACK_SERVICE_DELETE, paramsString);
        log.info("删除高德围栏Url：{} ,\n返回结果：{}", AMapConstants.AMAP_TRACK_SERVICE_DELETE + "?" + paramsString, result);
        AMapResult<Map<String, String>> aMapResult = JSONObject.parseObject(result, AMapResult.class);
        if (aMapResult != null && aMapResult.getData() != null && aMapResult.getData().containsKey("gfids")) {
            return String.valueOf(aMapResult.getData().get("gfids"));
        }
        log.info("删除高德围栏异常，key：{}，gfids：{} ，code：{} ,msg:{}", fenceKey.getAmapKey(), gfids, aMapResult.getErrmsg(), aMapResult.getErrdetail());
        throw new ServiceException("删除高德围栏异常，msg：" + aMapResult.getErrdetail() + " ！");
    }

    /**
     * 更新围栏-圆形
     *
     * @param fenceVo
     * @param fenceKey
     * @param fenceService
     * @param tElectronicFence
     * @return
     */
    private String trackGeofenceUpdateCircle(ElectronicFenceVo fenceVo, TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, TElectronicFence tElectronicFence) {
        //更新圆形围栏
        AMapUpdateCircleTo aMapUpdateCircleTo = new AMapUpdateCircleTo();
        BeanUtils.copyBeanProp(aMapUpdateCircleTo, fenceVo);
        aMapUpdateCircleTo.setKey(fenceKey.getAmapKey());
        aMapUpdateCircleTo.setSid(fenceService.getAmapSid());
        aMapUpdateCircleTo.setGfid(tElectronicFence.getGfid());
        //围栏昵称
        if (!StringUtils.isEmpty(aMapUpdateCircleTo.getName())) {
            //修改围栏昵称
            aMapUpdateCircleTo.setName(aMapUpdateCircleTo.getName());
        } else {
            //不修改围栏昵称
            aMapUpdateCircleTo.setName(tElectronicFence.getName());
        }
        //围栏描述
        if (!StringUtils.isEmpty(aMapUpdateCircleTo.getDesc())) {
            //修改围栏描述
            aMapUpdateCircleTo.setDesc(aMapUpdateCircleTo.getDesc());
        } else {
            //不修改围栏描述
            aMapUpdateCircleTo.setDesc(tElectronicFence.geteDesc());
        }
        //围栏中心点坐标 格式X,Y 必填
        if (!StringUtils.isEmpty(aMapUpdateCircleTo.getCenter())) {
            //修改围栏中心点坐标
            aMapUpdateCircleTo.setCenter(aMapUpdateCircleTo.getCenter());
        } else {
            log.error("围栏中心点坐标禁止为空，gfid：{}.", tElectronicFence.getGfid());
            throw new ServiceException("更新围栏禁止围栏中心点坐标为空！");
        }
        //围栏半径 单位：米，整数，取值范[1,50000] 必填
        if (!StringUtils.isEmpty(aMapUpdateCircleTo.getRadius())) {
            //修改围栏半径
            aMapUpdateCircleTo.setRadius(aMapUpdateCircleTo.getRadius());
        } else {
            log.error("围栏半径禁止为空，gfid：{}.", tElectronicFence.getGfid());
            throw new ServiceException("更新围栏禁止围栏半径为空！");
        }
        return sendGeoUpdateCircle(aMapUpdateCircleTo);
    }

    /**
     * 更新围栏-多边形围栏
     */
    private String trackGeofenceUpdatePolygon(ElectronicFenceVo fenceVo, TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, TElectronicFence tElectronicFence) {
        //更新多边形围栏
        AMapUpdatePolygonTo aMapUpdatePolygonTo = new AMapUpdatePolygonTo();
        BeanUtils.copyBeanProp(aMapUpdatePolygonTo, fenceVo);
        aMapUpdatePolygonTo.setKey(fenceKey.getAmapKey());
        aMapUpdatePolygonTo.setSid(fenceService.getAmapSid());
        aMapUpdatePolygonTo.setGfid(tElectronicFence.getGfid());
        //围栏昵称
        if (!StringUtils.isEmpty(aMapUpdatePolygonTo.getName())) {
            //修改围栏昵称
            aMapUpdatePolygonTo.setName(aMapUpdatePolygonTo.getName());
        } else {
            //不修改围栏昵称
            aMapUpdatePolygonTo.setName(tElectronicFence.getName());
        }
        //围栏描述
        if (!StringUtils.isEmpty(aMapUpdatePolygonTo.getDesc())) {
            //修改围栏描述
            aMapUpdatePolygonTo.setDesc(aMapUpdatePolygonTo.getDesc());
        } else {
            //不修改围栏描述
            aMapUpdatePolygonTo.setDesc(tElectronicFence.geteDesc());
        }
        //多边形顶点坐标 格式 X1,Y1;X2,Y2 必填
        if (!StringUtils.isEmpty(aMapUpdatePolygonTo.getPoints())) {
            //修改围栏多边形顶点坐标
            aMapUpdatePolygonTo.setPoints(aMapUpdatePolygonTo.getPoints());
        } else {
            log.error("围栏多边形顶点坐标禁止为空，gfid：{}.", tElectronicFence.getGfid());
            throw new ServiceException("更新围栏禁止多边形顶点坐标为空！");
        }
        return sendGeoUpdatePolygon(aMapUpdatePolygonTo);
    }

    /**
     * 更新围栏-线形围栏
     */
    private String trackGeofenceUpdatePolyline(ElectronicFenceVo fenceVo, TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, TElectronicFence tElectronicFence) {
        //更新线形围栏
        AMapUpdatePolyLineTo aMapUpdatePolyLineTo = new AMapUpdatePolyLineTo();
        BeanUtils.copyBeanProp(aMapUpdatePolyLineTo, fenceVo);
        aMapUpdatePolyLineTo.setKey(fenceKey.getAmapKey());
        aMapUpdatePolyLineTo.setSid(fenceService.getAmapSid());
        aMapUpdatePolyLineTo.setGfid(tElectronicFence.getGfid());
        //围栏昵称
        if (!StringUtils.isEmpty(aMapUpdatePolyLineTo.getName())) {
            //修改围栏昵称
            aMapUpdatePolyLineTo.setName(aMapUpdatePolyLineTo.getName());
        } else {
            //不修改围栏昵称
            aMapUpdatePolyLineTo.setName(tElectronicFence.getName());
        }
        //围栏描述
        if (!StringUtils.isEmpty(aMapUpdatePolyLineTo.getDesc())) {
            //修改围栏描述
            aMapUpdatePolyLineTo.setDesc(aMapUpdatePolyLineTo.getDesc());
        } else {
            //不修改围栏描述
            aMapUpdatePolyLineTo.setDesc(tElectronicFence.geteDesc());
        }
        //多边形顶点坐标 格式 X1,Y1;X2,Y2 必填
        if (!StringUtils.isEmpty(aMapUpdatePolyLineTo.getPoints())) {
            //修改围栏多边形顶点坐标
            aMapUpdatePolyLineTo.setPoints(aMapUpdatePolyLineTo.getPoints());
        } else {
            log.error("围栏线形顶点坐标禁止为空，gfid：{}.", tElectronicFence.getGfid());
            throw new ServiceException("更新围栏禁止线形点坐标为空！");
        }
        //沿线偏移距离 单位：米 取值范围 [1，300]
        if (!StringUtils.isEmpty(aMapUpdatePolyLineTo.getBufferradius())) {
            //修改围栏多边形顶点坐标
            aMapUpdatePolyLineTo.setBufferradius(aMapUpdatePolyLineTo.getBufferradius());
        } else {
            log.error("围栏线形沿线偏移距离禁止为空，gfid：{}.", tElectronicFence.getGfid());
            throw new ServiceException("更新围栏禁止线形沿线偏移距离为空！");
        }
        return sendGeoUpdatePolyline(aMapUpdatePolyLineTo);
    }

    /**
     * 更新围栏-行政区划围栏
     */
    private String trackGeofenceUpdateDistrict(ElectronicFenceVo fenceVo, TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, TElectronicFence tElectronicFence) {
        //更新行政区划围栏
        AMapUpdateDistrictTo aMapUpdateDistrictTo = new AMapUpdateDistrictTo();
        BeanUtils.copyBeanProp(aMapUpdateDistrictTo, fenceVo);
        aMapUpdateDistrictTo.setKey(fenceKey.getAmapKey());
        aMapUpdateDistrictTo.setSid(fenceService.getAmapSid());
        aMapUpdateDistrictTo.setGfid(tElectronicFence.getGfid());
        //围栏昵称
        if (!StringUtils.isEmpty(aMapUpdateDistrictTo.getName())) {
            //修改围栏昵称
            aMapUpdateDistrictTo.setName(aMapUpdateDistrictTo.getName());
        } else {
            //不修改围栏昵称
            aMapUpdateDistrictTo.setName(tElectronicFence.getName());
        }
        //围栏描述
        if (!StringUtils.isEmpty(aMapUpdateDistrictTo.getDesc())) {
            //修改围栏描述
            aMapUpdateDistrictTo.setDesc(aMapUpdateDistrictTo.getDesc());
        } else {
            //不修改围栏描述
            aMapUpdateDistrictTo.setDesc(tElectronicFence.geteDesc());
        }
        //行政区划编码 参考行政区划编码表 必填
        if (!StringUtils.isEmpty(aMapUpdateDistrictTo.getAdcode())) {
            //修改围栏多边形顶点坐标
            aMapUpdateDistrictTo.setAdcode(aMapUpdateDistrictTo.getAdcode());
        } else {
            log.error("围栏行政区划行政区划编码禁止为空，gfid：{}.", tElectronicFence.getGfid());
            throw new ServiceException("更新围栏禁止行政区划行政区划编码为空！");
        }
        return sendGeoUpdateDistrict(aMapUpdateDistrictTo);
    }

    /**
     * 通过高德接口更新圆形围栏
     *
     * @param aMapUpdateCircleTo
     * @return
     */
    private String sendGeoUpdateCircle(@Validated AMapUpdateCircleTo aMapUpdateCircleTo) {
        //更新圆形围栏
        Map<Object, Object> params = new HashMap();
        params.put("key", aMapUpdateCircleTo.getKey());
        params.put("sid", aMapUpdateCircleTo.getSid());
        params.put("gfid", aMapUpdateCircleTo.getGfid());
        params.put("name", aMapUpdateCircleTo.getName());
        if (!StringUtils.isEmpty(aMapUpdateCircleTo.getDesc())) {
            params.put("desc", aMapUpdateCircleTo.getDesc());
        }
        params.put("center", aMapUpdateCircleTo.getCenter());
        params.put("radius", aMapUpdateCircleTo.getRadius());
        String paramsString = HttpUtils.getParamsToString(params);
        // 去掉最后一个"&"符号
        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_UPDATE_CIRCLE, paramsString);
        log.info("更新高德围栏Url：{} ,\n返回结果：{}", AMapConstants.AMAP_GEOFENCE_UPDATE_CIRCLE + "?" + paramsString, result);
        AMapResult aMapResult = JSONObject.parseObject(result, AMapResult.class);
        if (aMapResult != null && aMapResult.getErrcode() == 10000) {
            return aMapUpdateCircleTo.getGfid();
        }
        log.info("更新高德围栏异常，key：{} ，code：{} ,msg:{}", aMapUpdateCircleTo.getKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
        throw new ServiceException("更新高德围栏异常，msg：" + aMapResult.getErrdetail() + " ！");
    }

    /**
     * 通过高德接口更新多边形围栏
     *
     * @param aMapUpdatePolygonTo
     * @return
     */
    private String sendGeoUpdatePolygon(@Validated AMapUpdatePolygonTo aMapUpdatePolygonTo) {
        //更新多边形围栏
        Map<Object, Object> params = new HashMap();
        params.put("key", aMapUpdatePolygonTo.getKey());
        params.put("sid", aMapUpdatePolygonTo.getSid());
        params.put("gfid", aMapUpdatePolygonTo.getGfid());
        params.put("name", aMapUpdatePolygonTo.getName());
        if (!StringUtils.isEmpty(aMapUpdatePolygonTo.getDesc())) {
            params.put("desc", aMapUpdatePolygonTo.getDesc());
        }
        params.put("points", aMapUpdatePolygonTo.getPoints());
        String paramsString = HttpUtils.getParamsToString(params);
        // 去掉最后一个"&"符号
        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_UPDATE_POLYGON, paramsString);
        log.info("更新高德围栏Url：{} ,\n返回结果：{}", AMapConstants.AMAP_GEOFENCE_UPDATE_POLYGON + "?" + paramsString, result);
        AMapResult aMapResult = JSONObject.parseObject(result, AMapResult.class);
        if (aMapResult != null && aMapResult.getErrcode() == 10000) {
            return aMapUpdatePolygonTo.getGfid();
        }
        log.info("更新高德围栏异常，key：{} ，code：{} ,msg:{}", aMapUpdatePolygonTo.getKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
        throw new ServiceException("更新高德围栏异常，msg：" + aMapResult.getErrdetail() + " ！");
    }

    /**
     * 通过高德接口更新线形围栏
     *
     * @param aMapUpdatePolyLineTo
     * @return
     */
    private String sendGeoUpdatePolyline(@Validated AMapUpdatePolyLineTo aMapUpdatePolyLineTo) {
        //更新多边形围栏
        Map<Object, Object> params = new HashMap();
        params.put("key", aMapUpdatePolyLineTo.getKey());
        params.put("sid", aMapUpdatePolyLineTo.getSid());
        params.put("gfid", aMapUpdatePolyLineTo.getGfid());
        params.put("name", aMapUpdatePolyLineTo.getName());
        if (!StringUtils.isEmpty(aMapUpdatePolyLineTo.getDesc())) {
            params.put("desc", aMapUpdatePolyLineTo.getDesc());
        }
        params.put("points", aMapUpdatePolyLineTo.getPoints());
        params.put("bufferradius", aMapUpdatePolyLineTo.getBufferradius());
        String paramsString = HttpUtils.getParamsToString(params);
        // 去掉最后一个"&"符号
        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_UPDATE_POLYLINE, paramsString);
        log.info("更新高德围栏Url：{} ,\n返回结果：{}", AMapConstants.AMAP_GEOFENCE_UPDATE_POLYLINE + "?" + paramsString, result);
        AMapResult aMapResult = JSONObject.parseObject(result, AMapResult.class);
        if (aMapResult != null && aMapResult.getErrcode() == 10000) {
            return aMapUpdatePolyLineTo.getGfid();
        }
        log.info("更新高德围栏异常，key：{} ，code：{} ,msg:{}", aMapUpdatePolyLineTo.getKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
        throw new ServiceException("更新高德围栏异常，msg：" + aMapResult.getErrdetail() + " ！");
    }

    /**
     * 通过高德接口更新行政区划围栏
     *
     * @param aMapUpdateDistrictTo
     * @return
     */
    private String sendGeoUpdateDistrict(@Validated AMapUpdateDistrictTo aMapUpdateDistrictTo) {
        //更新多边形围栏
        Map<Object, Object> params = new HashMap();
        params.put("key", aMapUpdateDistrictTo.getKey());
        params.put("sid", aMapUpdateDistrictTo.getSid());
        params.put("gfid", aMapUpdateDistrictTo.getGfid());
        params.put("name", aMapUpdateDistrictTo.getName());
        if (!StringUtils.isEmpty(aMapUpdateDistrictTo.getDesc())) {
            params.put("desc", aMapUpdateDistrictTo.getDesc());
        }
        params.put("adcode", aMapUpdateDistrictTo.getAdcode());
        String paramsString = HttpUtils.getParamsToString(params);
        // 去掉最后一个"&"符号
        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_UPDATE_DISTRICT, paramsString);
        log.info("更新高德围栏Url：{} ,\n返回结果：{}", AMapConstants.AMAP_GEOFENCE_UPDATE_DISTRICT + "?" + paramsString, result);
        AMapResult aMapResult = JSONObject.parseObject(result, AMapResult.class);
        if (aMapResult != null && aMapResult.getErrcode() == 10000) {
            return aMapUpdateDistrictTo.getGfid();
        }
        log.info("更新高德围栏异常，key：{} ，code：{} ,msg:{}", aMapUpdateDistrictTo.getKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
        throw new ServiceException("更新高德围栏异常，msg：" + aMapResult.getErrdetail() + " ！");
    }
}
