package com.inspect.patrol.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.inspect.access.base.model.RuleCollectionModel;
import com.inspect.access.base.model.RuleModel;
import com.inspect.base.core.constant.Constants;
import com.inspect.base.core.domain.Response;
import com.inspect.base.core.exception.ServiceException;
import com.inspect.base.core.sftp.SftpClient;
import com.inspect.base.core.utils.DateUtils;
import com.inspect.base.core.utils.HttpClientUtils;
import com.inspect.base.core.utils.StringUtils;
import com.inspect.base.core.utils.poi.ExcelUtil;
import com.inspect.base.core.web.controller.BaseController;
import com.inspect.base.core.web.domain.AjaxResult;
import com.inspect.base.core.web.page.TableDataInfo;
import com.inspect.common.log.annotation.Log;
import com.inspect.common.log.enums.BizType;
import com.inspect.base.redis.service.RedisService;
import com.inspect.fegin.FeignBasedataPatrolPointPresetService;
import com.inspect.patrol.contants.AccessApiConstant;
import com.inspect.patrol.contants.ChannelTypeEnum;
import com.inspect.patrol.contants.PresetControlEnum;
import com.inspect.patrol.domain.PatrolPresetAction;
import com.inspect.patrol.domain.PatrolPresetParam;
import com.inspect.patrol.domain.PatrolPresetPos;
import com.inspect.patrol.domain.PatrolPresetRecord;
import com.inspect.patrol.feignservice.IvsFeignService;
import com.inspect.patrol.feignservice.CustIotInvokeClient;
import com.inspect.patrol.linkage.util.JsonUtil;
import com.inspect.patrol.model.PresetAccessModel;
import com.inspect.patrol.model.PtzModel;
import com.inspect.patrol.model.SnapModel;
import com.inspect.patrol.service.BasedataAlgSubtypeService;
import com.inspect.patrol.service.BasedataAreaService;
import com.inspect.patrol.service.BasedataChannelService;
import com.inspect.patrol.service.BasedataDeviceService;
import com.inspect.patrol.service.BasedataEqpbookService;
import com.inspect.patrol.service.BasedataPatrolPointService;
import com.inspect.patrol.service.BasedataPatrolPointPresetService;
import com.inspect.patrol.service.BasedataStdPatrolPointService;
import com.inspect.patrol.service.IPatrolPresetActionService;
import com.inspect.patrol.service.IPatrolPresetParamService;
import com.inspect.patrol.service.IPatrolPresetPosService;
import com.inspect.patrol.service.IPatrolPresetRecordService;
import com.inspect.patrol.service.PatrolTaskService;
import com.inspect.patrol.service.impl.DeviceIntoService;
import com.inspect.patrol.service.impl.Video2NvrComponent;
import com.inspect.patrol.vo.CameraVo;
import com.inspect.system.base.domain.SysDictData;

import java.net.URLEncoder;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.inspect.base.core.constant.Color;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

@ApiIgnore
@RestController
@RequestMapping({"/preset"})
public class PatrolPresetPosController extends BaseController {
    private final IPatrolPresetPosService patrolPresetPosService;
    private final BasedataStdPatrolPointService basedataStdPatrolPointService;
    private final BasedataPatrolPointService basedataPatrolPointService;
    private final BasedataDeviceService basedataDeviceService;
    private final IPatrolPresetParamService patrolPresetParamService;
    private final IPatrolPresetActionService patrolPresetActionService;
    private final BasedataAlgSubtypeService basedataAlgSubtypeService;
    private final BasedataEqpbookService basedataEqpbookService;
    private final BasedataChannelService basedataChannelService;
    private final BasedataAreaService basedataAreaService;
    private final BasedataPatrolPointPresetService basedataPatrolpointPresetService;
    private final HttpServletRequest httpServletRequest;
    private final DeviceIntoService deviceIntoService;
    private final PatrolTaskService patrolTaskService;
    private final SftpClient sftpClient;
    final
    CustIotInvokeClient remoteInvokeService;
    private final RedisService redisService;
    private final Video2NvrComponent video2NvrComponent;
    private final IPatrolPresetRecordService patrolPresetRecordService;

    private final FeignBasedataPatrolPointPresetService basedataPatrolPointPresetServiceClient;
    final
    IvsFeignService ivsFeignService;
    @Value("${gwb.url}")
    private String deviceUrl;
    @Value("${liveSIPB.url}")
    private String liveSIPBUrl;
    @Value("${sftp.ip}")
    private String ip;
    @Value("${sftp.port}")
    private String port;
    @Value("${sftp.username}")
    private String username;
    @Value("${sftp.password}")
    private String password;
    @Value("${ivs.version:3800}")
    private String version;
    private final String INSERT_PATROL_POINT_PURPOSE = "数据分析,在线监视";
    private final String SELECT_PRESET_CODE_CLASS_BIND = "1";
    private final String SELECT_PRESET_CODE_CLASS_STOP = "2";

    public PatrolPresetPosController(
            IPatrolPresetPosService patrolPresetPosService,
            BasedataStdPatrolPointService basedataStdPatrolPointService,
            BasedataPatrolPointService basedataPatrolPointService,
            CustIotInvokeClient remoteInvokeService,
            RedisService redisService,
            BasedataDeviceService basedataDeviceService,
            IPatrolPresetParamService patrolPresetParamService,
            Video2NvrComponent video2NvrComponent,
            HttpServletRequest httpServletRequest,
            DeviceIntoService deviceIntoService,
            IPatrolPresetRecordService patrolPresetRecordService,
            IPatrolPresetActionService patrolPresetActionService,
            BasedataAlgSubtypeService basedataAlgSubtypeService,
            BasedataEqpbookService basedataEqpbookService,
            IvsFeignService ivsFeignService,
            BasedataChannelService basedataChannelService,
            PatrolTaskService patrolTaskService,
            SftpClient sftpClient,
            BasedataAreaService basedataAreaService,
            BasedataPatrolPointPresetService basedataPatrolpointPresetService,
            FeignBasedataPatrolPointPresetService basedataPatrolPointPresetServiceClient) {
        this.patrolPresetPosService = patrolPresetPosService;
        this.basedataStdPatrolPointService = basedataStdPatrolPointService;
        this.basedataPatrolPointService = basedataPatrolPointService;
        this.remoteInvokeService = remoteInvokeService;
        this.redisService = redisService;
        this.basedataDeviceService = basedataDeviceService;
        this.patrolPresetParamService = patrolPresetParamService;
        this.video2NvrComponent = video2NvrComponent;
        this.httpServletRequest = httpServletRequest;
        this.deviceIntoService = deviceIntoService;
        this.patrolPresetRecordService = patrolPresetRecordService;
        this.patrolPresetActionService = patrolPresetActionService;
        this.basedataAlgSubtypeService = basedataAlgSubtypeService;
        this.basedataEqpbookService = basedataEqpbookService;
        this.ivsFeignService = ivsFeignService;
        this.basedataChannelService = basedataChannelService;
        this.patrolTaskService = patrolTaskService;
        this.sftpClient = sftpClient;
        this.basedataAreaService = basedataAreaService;
        this.basedataPatrolpointPresetService = basedataPatrolpointPresetService;
        this.basedataPatrolPointPresetServiceClient = basedataPatrolPointPresetServiceClient;
    }

    @GetMapping({"/list"})
    public TableDataInfo list(PatrolPresetPos patrolPresetPos) {
        this.startPage();
        List<PatrolPresetPos> list = this.patrolPresetPosService.selectPatrolPresetPosList(patrolPresetPos);
        return this.getDataTable(list);
    }

    @GetMapping({"/camera/{channelType}"})
    public AjaxResult findCameraByChannelType(@PathVariable("channelType") String channelType) {
        List<CameraVo> list = patrolPresetPosService.selectCameraByChannelType(channelType);
        JSONArray jsonArray =
                JSONObject.parseObject(JSONObject.toJSONString(basedataAreaService.list(new JSONObject()))).getJSONArray("data");
        for (int i = 0; i < jsonArray.size(); ++i) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            jsonObject.put("id", jsonObject.getString("areaId"));
            jsonObject.put("name", jsonObject.getString("areaName"));
            for (int j = 0; j < list.size(); ++j) {
                CameraVo cameraVo = list.get(j);
                if (jsonObject.getString("areaId").equals(cameraVo.getAreaId())) {
                    cameraVo.setId("c" + j);
                    cameraVo.setParentId(jsonObject.getString("id"));
                    if (!jsonObject.containsKey("children")) {
                        jsonObject.put("children", new JSONArray());
                    }

                    jsonObject.getJSONArray("children").add(cameraVo);
                }
            }
        }

        JSONArray tree = this.treeMenuList(jsonArray, "0");
        this.removeEmptyTree(tree);
        return AjaxResult.success(tree);
    }

    public void removeEmptyTree(JSONArray tree) {
        for (int i = tree.size() - 1; i >= 0; --i) {
            JSONObject jsonObject = tree.getJSONObject(i);
            if (jsonObject.containsKey("children")) {
                JSONArray children = jsonObject.getJSONArray("children");
                this.removeEmptyTree(children);
                if (children.isEmpty() && !jsonObject.containsKey("eqpBookId")) {
                    tree.remove(i);
                }
            } else if (!jsonObject.containsKey("eqpBookId")) {
                tree.remove(i);
            }
        }

    }

    private JSONArray treeMenuList(JSONArray menuList, String parentId) {
        JSONArray childMenu = new JSONArray();

        for (int i = 0; i < menuList.size(); ++i) {
            JSONObject jsonMenu = menuList.getJSONObject(i);
            String menuId = jsonMenu.getString("id");
            String pid = jsonMenu.getString("parentId");
            if (parentId.equals(pid)) {
                JSONArray jsonArray = this.treeMenuList(menuList, menuId);
                if (!jsonArray.isEmpty()) {
                    if (!jsonMenu.containsKey("children")) {
                        jsonMenu.put("children", jsonArray);
                    } else {
                        jsonMenu.getJSONArray("children").addAll(jsonArray);
                    }
                }

                childMenu.add(jsonMenu);
            }
        }

        return childMenu;
    }

    @GetMapping({"issue"})
    public AjaxResult issue(PresetAccessModel presetAccessModel) throws Exception {
        presetAccessModel.setCommand(PresetControlEnum.SET);
        String presetIndex = null;
        try {
            presetIndex = this.controlPresetAdd(presetAccessModel);
        } catch (ServiceException e) {
            return AjaxResult.error(e.getMessage());
        }
        if (null != presetIndex) {
            presetAccessModel.setPreset(presetIndex);
            presetAccessModel.setPresetCode(presetIndex);
            this.addPresetRecord(presetAccessModel);
        }

        return AjaxResult.success();
    }

    @GetMapping({"issueUpdate"})
    public AjaxResult issueUpdate(PresetAccessModel presetAccessModel) throws Exception {
        logger.info("-----------------issueUpdate presetAccessModel,{}", presetAccessModel);
        PatrolPresetPos patrolPresetPos = new PatrolPresetPos();
        patrolPresetPos.setPatrolDeviceCode(presetAccessModel.getSerial());
        patrolPresetPos.setPresetPosCode(presetAccessModel.getPreset());
        patrolPresetPos.setChannelCode(presetAccessModel.getCode());
        presetAccessModel.setCommand(PresetControlEnum.UPDATE);
        logger.info("-----------------issueUpdate presetAccessModel {}", JSONObject.toJSONString(presetAccessModel));
        this.controlPreset(presetAccessModel);
        this.addPresetRecord(presetAccessModel);
        return AjaxResult.success();
    }

    @GetMapping({"goto"})
    public AjaxResult gotoPreset(String presetPosId, String presetCode, String channelCode, String patroldeviceCode) throws Exception {
        patroldeviceCode = this.video2NvrComponent.toNvrCode(patroldeviceCode);
        boolean manualControlPTZ = this.patrolTaskService.isManualControlPTZ(patroldeviceCode, this.httpServletRequest);
        if (!manualControlPTZ) {
            return AjaxResult.error("控制失败，正在执行任务，您的权限不足！");
        } else {
            PresetAccessModel presetAccessModel;
            if (StringUtils.isEmpty(presetPosId)) {
                presetAccessModel = new PresetAccessModel();
                presetAccessModel.setPreset(presetCode);
                presetAccessModel.setCommand(PresetControlEnum.GOTO);
                presetAccessModel.setCode(channelCode);
                presetAccessModel.setSerial(patroldeviceCode);
            } else {
                presetAccessModel = this.queryById(presetPosId, PresetControlEnum.GOTO);
            }

            this.controlPreset(presetAccessModel);
            return AjaxResult.success();
        }
    }

    @GetMapping({"rm"})
    public AjaxResult removeRemotePreset(String presetPosId) throws Exception {
        PresetAccessModel presetAccessModel = this.queryById(presetPosId, PresetControlEnum.REMOVE);
        this.deletePresetRecord(presetAccessModel);
        return AjaxResult.success();
    }

    private PresetAccessModel queryById(String presetPosId, PresetControlEnum presetControlEnum) {
        PatrolPresetPos patrolPresetPos = this.patrolPresetPosService.selectPatrolPresetPosByPresetPosId(presetPosId);
        PresetAccessModel presetAccessModel = JSONObject.parseObject(JSONObject.toJSONString(patrolPresetPos), PresetAccessModel.class);
        presetAccessModel.setCommand(presetControlEnum);
        presetAccessModel.setPresetCode(patrolPresetPos.getPresetPosCode());
        presetAccessModel.setPreset(patrolPresetPos.getPresetPosCode());
        return presetAccessModel;
    }

    private void controlPreset(PresetAccessModel presetAccessModel) throws Exception {
        String params = JsonUtil.json2Str(JSONObject.parseObject(JSONObject.toJSONString(presetAccessModel)));
        HttpClientUtils.get(this.deviceUrl + AccessApiConstant.PRESET_POINT_CONTROL, params);
    }

    private String controlPresetAdd(PresetAccessModel presetAccessModel) throws ServiceException {
        String presetIndex = null;
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", presetAccessModel.getCode());
        jsonObject.put("name", presetAccessModel.getName());
        jsonObject.put("patroldeviceCode", presetAccessModel.getPatrolDeviceCode());
        jsonObject.put("command", presetAccessModel.getCommand());
        jsonObject.put("channelCode", presetAccessModel.getChannelCode());
        Response presetIndexRet = this.ivsFeignService.preset(jsonObject);
        JSONObject ivsPresetInfo = (JSONObject) JSONObject.toJSON(presetIndexRet);
        logger.info("ivsPresetInfo:{}", ivsPresetInfo.toString());
        if (!Objects.equals(ivsPresetInfo.getInteger("code"), Constants.SUCCESS)) {
            throw new ServiceException(ivsPresetInfo.getString("msg"));
        }
        JSONObject resultJson = (JSONObject) ivsPresetInfo.get("data");
        if (null != resultJson) {
            presetIndex = resultJson.getInteger("presetIndex") == null ? null : String.valueOf(resultJson.getInteger("presetIndex"));
            presetAccessModel.setPreset(presetIndex);
            presetAccessModel.setPresetCode(presetIndex);
            return presetIndex;
        } else {
            return presetIndex;
        }
    }

    @GetMapping({"/device/{deviceId}"})
    public TableDataInfo queryByDeviceId(@PathVariable("deviceId") String deviceId) {
        this.startPage();
        List<PatrolPresetPos> list = this.patrolPresetPosService.selectListByDeviceId(deviceId);
        return this.getDataTable(list);
    }

//    @GetMapping({"/listByEqIdAndChannelId"})
//    public AjaxResult queryListByEqIdAndChannelId(PtzModel ptzModel) throws Exception {
//        String patroldeviceCode = ptzModel.getPatrolDeviceCode();
//        String channelCode = ptzModel.getChannelCode();
//        List<SysDictData> presetPoints = new ArrayList<>();
//        String params = "code=" + channelCode;
//        String result = HttpClientUtils.get(this.deviceUrl + AccessApiConstant.PTZ_LIST, params);
//        JSONObject ivsPresetInfo = JSONObject.parseObject(result);
//        String resultCode = ivsPresetInfo.getString("resultCode");
//        if (null != resultCode && resultCode.equals("0")) {
//            JSONObject ptzPresetInfoListJson = ivsPresetInfo.getJSONObject("ptzPresetInfoList");
//            JSONArray ptzPresetInfoArray = ptzPresetInfoListJson.getJSONArray("ptzPresetInfo");
//            if (!ptzPresetInfoArray.isEmpty()) {
//                for (Object ivspresetObject : ptzPresetInfoArray) {
//                    JSONObject ivsPresetJson = (JSONObject) JSONObject.toJSON(ivspresetObject);
//                    String presetIndex = ivsPresetJson.getString("presetIndex");
//                    String presetName = ivsPresetJson.getString("presetName");
//                    SysDictData sysDictData = SysDictData.builder().build();
//                    sysDictData.setDictValue(presetIndex);
//                    sysDictData.setDictLabel(presetName);
//                    presetPoints.add(sysDictData);
//                }
//            }
//
//            PatrolPresetRecord patrolPresetRecord = new PatrolPresetRecord();
//            patrolPresetRecord.setPatrolDeviceCode(patroldeviceCode);
//            patrolPresetRecord.setChannelCode(channelCode);
//            List<PatrolPresetRecord> patrolPresetRecords = this.patrolPresetRecordService.selectPatrolPresetRecordList(patrolPresetRecord);
//            presetPoints.forEach((item) -> {
//                patrolPresetRecords.forEach((presetPos) -> {
//                    if (item.getDictValue().equals(presetPos.getPresetPosCode())) {
//                        item.setCssClass(SELECT_PRESET_CODE_CLASS_BIND);
//                    }
//
//                });
//            });
//            return AjaxResult.success(presetPoints);
//        } else {
//            return AjaxResult.success(presetPoints);
//        }
//    }

    @GetMapping({"/listByEqIdAndChannelId"})
    public AjaxResult queryListByEqIdAndChannelId(
            @RequestParam("patroldeviceCode") String patrolDeviceCode,
            @RequestParam("channelCode") String channelCode
    ) throws Exception {
        AjaxResult ajaxResult = basedataChannelService.queryEqpBookChannelByChannelCode(channelCode);
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult)).getJSONObject(("data"));
        if (jsonObject == null) {
            return ajaxResult;
        }
        String host = jsonObject.getString(("host"));
        String port = jsonObject.getString(("port"));
        String address = jsonObject.getString(("address"));
        String username = jsonObject.getString(("username"));
        String password = jsonObject.getString(("password"));
        List<SysDictData> presetPoints = new ArrayList<>();
        String params = "code=" + channelCode;
        if (StringUtils.isNotEmpty(host)) params.concat(("&host=")).concat(URLEncoder.encode(host, ("UTF-8")));
        if (StringUtils.isNotEmpty(port)) params.concat(("&port=")).concat(URLEncoder.encode(port, ("UTF-8")));
        if (StringUtils.isNotEmpty(username))
            params.concat(("&username=")).concat(URLEncoder.encode(username, ("UTF-8")));
        if (StringUtils.isNotEmpty(password))
            params.concat(("&password=")).concat(URLEncoder.encode(password, ("UTF-8")));
        if (StringUtils.isNotEmpty(address)) params.concat(("&address=")).concat(URLEncoder.encode(address, ("UTF-8")));
        String result = HttpClientUtils.get((this.deviceUrl + AccessApiConstant.PTZ_LIST), params);
        JSONObject ivsPresetInfo = JSONObject.parseObject(result);
        String resultCode = ivsPresetInfo.getString("resultCode");
        if (null != resultCode && resultCode.equals("0")) {
            JSONObject ptzPresetInfoListJson = ivsPresetInfo.getJSONObject("ptzPresetInfoList");
            JSONArray ptzPresetInfoArray = ptzPresetInfoListJson.getJSONArray("ptzPresetInfo");
            if (!ptzPresetInfoArray.isEmpty()) {
                for (Object ivspresetObject : ptzPresetInfoArray) {
                    JSONObject ivsPresetJson = (JSONObject) JSONObject.toJSON(ivspresetObject);
                    String presetIndex = ivsPresetJson.getString("presetIndex");
                    String presetName = ivsPresetJson.getString("presetName");
                    SysDictData sysDictData = SysDictData.builder().build();
                    sysDictData.setDictValue(presetIndex);
                    sysDictData.setDictLabel(presetName);
                    presetPoints.add(sysDictData);
                }
            }

            PatrolPresetRecord patrolPresetRecord = new PatrolPresetRecord();
            patrolPresetRecord.setPatrolDeviceCode(patrolDeviceCode);
            patrolPresetRecord.setChannelCode(channelCode);
            List<PatrolPresetRecord> patrolPresetRecords = this.patrolPresetRecordService.selectPatrolPresetRecordList(patrolPresetRecord);
            presetPoints.forEach((item) -> {
                patrolPresetRecords.forEach((presetPos) -> {
                    if (item.getDictValue().equals(presetPos.getPresetPosCode())) {
                        item.setCssClass(SELECT_PRESET_CODE_CLASS_BIND);
                    }

                });
            });
            return AjaxResult.success(presetPoints);
        } else {
            // IVS错误码
            if (result == "119108006") {
                return AjaxResult.error("设备不存在");
            }

            return AjaxResult.error("设备异常");
        }
    }

    @Log(
            title = "巡检_视频预置位",
            businessType = BizType.EXPORT
    )
    @PostMapping({"/export"})
    public void export(HttpServletResponse response, PatrolPresetPos patrolPresetPos) {
        List<PatrolPresetPos> list = this.patrolPresetPosService.selectPatrolPresetPosList(patrolPresetPos);
        ExcelUtil<PatrolPresetPos> util = new ExcelUtil(PatrolPresetPos.class);
        util.exportExcel(response, list, "巡检_视频预置位数据");
    }

    @GetMapping({"/{presetPosId}"})
    public AjaxResult getInfo(@PathVariable("presetPosId") String presetPosId) {
        PatrolPresetPos patrolPresetPos = this.patrolPresetPosService.selectPatrolPresetPosByPresetPosId(presetPosId);
        List<PatrolPresetParam> presetParamList = this.patrolPresetParamService.selectPatrolPresetParamByPosPatrolPresetId(Long.getLong(presetPosId));
        patrolPresetPos.setPresetParamList(presetParamList);
        List<PatrolPresetAction> presetActionList = this.patrolPresetActionService.selectPatrolPresetActionByPatrolPresetPosId(Long.getLong(presetPosId));
        patrolPresetPos.setPresetActionList(presetActionList);
        return AjaxResult.success(patrolPresetPos);
    }

    @GetMapping
    public AjaxResult getInfoByPatrolPointId(@RequestParam("patrolpointId") String patrolPointId) {
        logger.info("[PRESET] getInfoByPatrolPointId patrolPointId: {}", patrolPointId);
        List<PatrolPresetPos> patrolPresetPos = this.patrolPresetPosService.selectPatrolPresetPosByPatrolPointId(patrolPointId);
        return AjaxResult.success(patrolPresetPos);
    }

    @Log(
            title = "巡检_视频预置位",
            businessType = BizType.INSERT
    )
    @PostMapping
    public AjaxResult add(@RequestBody PatrolPresetPos patrolPresetPos) throws Exception {
        if (StringUtils.isEmpty(patrolPresetPos.getPresetPosCode())) {
            patrolPresetPos.setPresetPosCode("1");
            patrolPresetPos.setPresetPosName("虚拟守望预置位");
        }
        logger.info("[PRESET] patrolPresetPos PresetPosCode: {},PresetPosName: {}", patrolPresetPos.getPresetPosCode(), patrolPresetPos.getPresetPosName());
        logger.info("[PRESET] patrolPresetPos eqpBookId: {}, body: {}", patrolPresetPos.getEqpBookId(), patrolPresetPos);
        AjaxResult ajaxResult = this.basedataEqpbookService.queryById(patrolPresetPos.getEqpBookId());
        JSONObject eqpBook = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult)).getJSONObject("data");
        logger.info("[PRESET] eqpBook: {}", eqpBook);
        patrolPresetPos.setPatrolDeviceCode(StringUtils.isEmpty(eqpBook.getString("patrolDeviceCode")) ? eqpBook.getString("patroldeviceCode") : eqpBook.getString("patrolDeviceCode"));
        ajaxResult = this.basedataChannelService.queryById(patrolPresetPos.getChannelId());
        JSONObject channel = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult)).getJSONObject("data");
        patrolPresetPos.setChannelCode(channel.getString("channelCode"));
        patrolPresetPos.setChannelType(channel.getString("channelType"));
        patrolPresetPos.setVideoNvrCode(eqpBook.getString("videoNvrCode"));
        JSONObject basePreset;
        String snap;
        if (patrolPresetPos.getPatrolPointId() == null) {
            // 标准点位
            ajaxResult = this.basedataStdPatrolPointService.queryById(patrolPresetPos.getStdParolPointId());
            //qinyl
            basePreset = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult)).getJSONObject("data");
            ajaxResult = this.basedataDeviceService.queryById(patrolPresetPos.getDeviceId());
            JSONObject device = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult)).getJSONObject("data");
            snap = device.getString("areaId");
            String stdPatrolPointId = patrolPresetPos.getStdParolPointId();
            JSONObject paramJson = (new JSONObject())
                    .fluentPut("deviceId", patrolPresetPos.getDeviceId())
                    .fluentPut("patrolContent", basePreset.getString("patrolContent"))
                    .fluentPut("purpose", INSERT_PATROL_POINT_PURPOSE)
                    .fluentPut("areaId", snap)
                    .fluentPut("stdParolPointId", stdPatrolPointId)
                    .fluentPut("deviceTypeId", device.getString("deviceTypeId"))
                    .fluentPut("lowerValue", basePreset.getString("lowerValue"))
                    .fluentPut("alarmThreshold", basePreset.getString("alarmThreshold"))
                    .fluentPut("upperValue", basePreset.getString("upperValue"))
                    .fluentPut("algSubtypeIds", basePreset.getString("algSubtypeIds"))
                    .fluentPut("patrolPointName", device.getString("deviceName") + "_" + basePreset.getString("stdPatrolPointName"));
            ajaxResult = this.basedataPatrolPointService.add(paramJson);
            JSONObject patrolPoint = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult));
            patrolPresetPos.setPatrolPointId(patrolPoint.getLong("data"));
        }

        Integer basePresetId = null;
        try {
            this.basedataPatrolPointService.UpPatrolPointModel((new JSONObject()).fluentPut("patrolPointId", patrolPresetPos.getPatrolPointId()));
            // insert into basedata_patrolpoint_preset
            JSONArray objects = this.selectBasePreset(patrolPresetPos);
            if (objects == null || objects.isEmpty()) {
                basePresetId = this.insertBasePreset(patrolPresetPos);
            }
            SnapModel snapModel = new SnapModel();
            snapModel.setCode(patrolPresetPos.getChannelCode());
            snapModel.setPatrolDeviceCode(patrolPresetPos.getPatrolDeviceCode());
            snap = this.deviceIntoService.snap(snapModel);
            patrolPresetPos.setChannelImg(snap);
            logger.info("PRESET_ADD patrolPointId: {}, patrolPresetPos: {}", patrolPresetPos.getPatrolPointId(), patrolPresetPos);
            // update basedata_patrolpoint
            try {
                JSONObject editJsonObject = (new JSONObject())
                        .fluentPut("patrolpointId", patrolPresetPos.getPatrolPointId())
                        .fluentPut("meterType", patrolPresetPos.getPresetParamList().get(0).getCoordinate());
                logger.info("PRESET_ADD editJsonObject: {}", editJsonObject);
                basedataPatrolPointService.edit(editJsonObject);
            } catch (Exception e) {
                e.printStackTrace();
            }

            PatrolPresetPos patrolPresetPos1 = new PatrolPresetPos();
            patrolPresetPos1.setPatrolPointId(patrolPresetPos.getPatrolPointId());
            List<PatrolPresetPos> presetPosList = patrolPresetPosService.selectPatrolPresetPosList(patrolPresetPos1);
            if (presetPosList.isEmpty()) {
                if (StringUtils.isEmpty(patrolPresetPos.getPresetPosCode())) {
                    logger.info("[PRESET] 预置位编码不能为空！: {}", patrolPresetPos.getPresetPosCode());
//                    throw new ServiceException("预置位编码不能为空！");
                } else {
                    logger.info(Color.GREEN + "[PRESET] INSERT patrolPresetPos: {}" + Color.END, patrolPresetPos);
                    int insertResId = patrolPresetPosService.insertPatrolPresetPos(patrolPresetPos);
                    logger.info("[PRESET] insert insertResId: {}", insertResId);
                    logger.info("红外添加完成==》往1800中同步配置,version{}", version);
                    //往1800中写规则
                    if (version.equals("1800")) {
                        PatrolPresetParam patrolPresetParam = patrolPresetPos.getPresetParamList().get(0);
                        final String temperUrl = liveSIPBUrl + "/api/v1/device/setHwConfig";
                        logger.info("=========temperUrl====={}", temperUrl);
                        logger.info("=========patrolPresetParam====={}", patrolPresetParam);
                        JSONObject temperParam = new JSONObject();
                        temperParam.put("ruleId", Integer.parseInt(patrolPresetParam.getPresetParamCode()));  //设置ruleId
                        temperParam.put("presetId", patrolPresetPos.getPresetPosCode());
                        temperParam.put("name", patrolPresetParam.getMeasureName());
                        temperParam.put("cameraCode", patrolPresetPos.getChannelCode());
                        List<Map<String, Object>> polygonList = new ArrayList<>();
                        String[] split = patrolPresetParam.getCoordinate().split(StringUtils.COMMA);
                        if (split.length == 10) {
                            Map<String, Object> point = new HashMap<>();
                            point.put("x", (int) ((Double.parseDouble(split[0]) / Double.parseDouble(split[8])) * 8190));
                            point.put("y", (int) ((Double.parseDouble(split[1]) / Double.parseDouble(split[9])) * 8190));
                            Map<String, Object> point1 = new HashMap<>();
                            point1.put("x", (int) ((Double.parseDouble(split[2]) / Double.parseDouble(split[8])) * 8190));
                            point1.put("y", (int) ((Double.parseDouble(split[3]) / Double.parseDouble(split[9])) * 8190));
                            Map<String, Object> point2 = new HashMap<>();
                            point2.put("x", (int) ((Double.parseDouble(split[4]) / Double.parseDouble(split[8])) * 8190));
                            point2.put("y", (int) ((Double.parseDouble(split[5]) / Double.parseDouble(split[9])) * 8190));
                            Map<String, Object> point3 = new HashMap<>();
                            point3.put("x", (int) ((Double.parseDouble(split[6]) / Double.parseDouble(split[8])) * 8190));
                            point3.put("y", (int) ((Double.parseDouble(split[7]) / Double.parseDouble(split[9])) * 8190));
                            polygonList.add(point);
                            polygonList.add(point1);
                            polygonList.add(point2);
                            polygonList.add(point3);
                            temperParam.put("polygonList", polygonList);
                        }
                        logger.info("=========temperParam{}", temperParam);
                        final String temperUrlRes = HttpClientUtils.sendPostAgain(temperUrl, temperParam.toString());
                        logger.info("[infra_1800] prePointExec temperUrlRes: {}", temperUrlRes);
                    }

                }
            } else {
                logger.info("[PRESET] patrolPresetPos: {} already added!", patrolPresetPos1.getPatrolPointId());
            }
        } catch (Exception e) {
            logger.warn(Color.RED + "[PRESET] INSERT into patrolPresetPos Exception class: {}" + Color.END, e.getClass());
            if (e.getClass().equals(DuplicateKeyException.class)) {
                logger.warn(Color.RED + "[PRESET] INSERT into patrolPresetPos Exception class!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1" + Color.END);
                return AjaxResult.fail(500, "该监测点已经绑定！");
            } else {
                logger.warn("[PRESET] INSERT into patrolPresetPos 2: {}", e.getMessage());
                this.basedataPatrolPointService.remove(new Long[]{patrolPresetPos.getPatrolPointId()});
                if (basePresetId != null) {
                    this.basedataPatrolpointPresetService.remove(new Long[]{Long.parseLong(basePresetId + "")});
                }
                throw new ServiceException("连接超时！");
            }
        }

        this.toSdkIrParam(patrolPresetPos, eqpBook);
        return AjaxResult.success(patrolPresetPos.getPatrolPointId());
    }

    private void toSdkIrParam(PatrolPresetPos patrolPresetPos, JSONObject eqpBook) {
        (new Thread(() -> {
            if (!ChannelTypeEnum.VL.getType().equals(patrolPresetPos.getChannelType())) {
                PatrolPresetParam patrolPresetParam = patrolPresetPos.getPresetParamList().get(0);

                try {
                    Map<Object, Object> map = new HashMap<>();
                    map.put("preset", patrolPresetPos.getPresetPosCode());
                    map.put("name", patrolPresetParam.getMeasureName());
                    map.put("distance", patrolPresetParam.getMeasureDistance());
                    map.put("emissivity", patrolPresetParam.getRadioRate());
                    map.put("temperature", patrolPresetParam.getReflexTemp());
                    String measureAreaType = patrolPresetParam.getMeasureAreaType();
                    byte bValue = -1;
                    switch (measureAreaType) {
                        case "Rectangle":
                            bValue = 2;
                            break;
                        case "BrokenLine":
                            bValue = 1;
                            break;
                        case "Point":
                            bValue = 0;
                            break;
                    }

                    switch (bValue) {
                        case 0:
                            map.put("meterType", "POINT");
                            break;
                        case 1:
                            map.put("meterType", "LINE");
                            break;
                        case 2:
                            map.put("meterType", "REGION");
                            break;
                        default:
                            throw new ServiceException("无此框选类型");
                    }

                    String[] split = patrolPresetParam.getCoordinate().split(StringUtils.COMMA);
                    JSONArray points = new JSONArray();

                    for (int i = 0; i < split.length - 2; i += 2) {
                        points.add((new JSONObject()).fluentPut("positionX", split[i]).fluentPut("positionY", split[i + 1]));
                    }

                    map.put("points", points.toJSONString());
                    map.put("coordinate", split[split.length - 2] + "*" + split[split.length - 1]);
                    this.remoteInvokeService.invoke("IR_SET", patrolPresetPos.getPatrolDeviceCode().split("#")[0], map);

                } catch (Exception ignored) {

                }

            }
        })).start();
    }

    private int insertBasePreset(PatrolPresetPos patrolPresetPos) {
        JSONObject params = JSONObject.parseObject(JSONObject.toJSONString(patrolPresetPos)).fluentPut("presetCode", patrolPresetPos.getPresetPosCode()).fluentPut("presetName", patrolPresetPos.getPresetPosName());

        logger.info("[METADATA] !!!!!!!!!!!!!!!!!!!!!insertBasePreset params: {}", params.toString());
        return (Integer) this.basedataPatrolpointPresetService.add(params).get("data");
    }

    private JSONArray selectBasePreset(PatrolPresetPos patrolPresetPos) {
        JSONObject params = new JSONObject();
        params.put("patrolPointId", patrolPresetPos.getPatrolPointId());
        Object presetListObject = basedataPatrolPointPresetServiceClient.getPatrolPointPresetListByDeviceIdS(params).getRows();
        JSONArray presetListObjects = JSONArray.parseArray(JSONObject.toJSONString(presetListObject));
        logger.info("[METADATA] !!!!!!!!!!!!!!!!!!!!!selectBasePreset params: {}", params.toString());
        logger.info("[METADATA] !!!!!!!!!!!!!!!!!!!!!selectBasePreset result: {}", presetListObjects);
        return presetListObjects;
    }

    @Log(
            title = "绑定预置点",
            businessType = BizType.UPDATE
    )
    @PostMapping({"/edit"})
    public AjaxResult edit(@RequestBody PatrolPresetPos patrolPresetPos) {
        return this.toAjax(this.patrolPresetPosService.updatePatrolPresetPos(patrolPresetPos));
    }

    @Log(
            title = "巡检_视频预置位",
            businessType = BizType.DELETE
    )
    @GetMapping({"/remove/{presetPosIds}"})
    public AjaxResult remove(@PathVariable Long[] presetPosIds) {
        (new Thread(() -> {
            try {
                for (Long id : presetPosIds) {
                    // delete from patrol_preset_record
                    this.removeRemotePreset(id + "");
                }

            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        })).start();
        (new Thread(() -> {
            List<PatrolPresetPos> patrolPresetPos = this.patrolPresetPosService.selectPatrolPresetPosListByIds(presetPosIds);
            List<PatrolPresetPos> list = patrolPresetPos.stream().filter((item) -> {
                return ChannelTypeEnum.IR.getType().equals(item.getChannelType());
            }).collect(Collectors.toList());
            if (!list.isEmpty()) {
                List<String> eqpBookIds = list.stream().map((item) -> {
                    return item.getEqpBookId();
                }).distinct().collect(Collectors.toList());

                for (String eqpBookId : eqpBookIds) {
                    AjaxResult ajaxResult = this.basedataEqpbookService.queryById(eqpBookId);
                    JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult.get("data")));
                    RuleCollectionModel ruleCollectionModel = new RuleCollectionModel();
                    ruleCollectionModel.init(jsonObject.getString("ipAddr"), jsonObject.getInteger("port"), jsonObject.getString("user"), jsonObject.getString("password"));

                    for (Integer object : list.stream().filter((item) -> {
                        return item.getEqpBookId().equals(eqpBookId);
                    }).map((item) -> {
                        return Integer.parseInt(item.getPresetPosCode());
                    }).collect(Collectors.toList())) {
                        RuleModel ruleModel = new RuleModel();
                        ruleModel.nPresetId = object;
                        ruleCollectionModel.addRuleModel(ruleModel);
                        Map<Object, Object> map = new HashMap<>();
                        map.put("preset", object);
                        this.remoteInvokeService.invoke("IR_DEL", jsonObject.getString("patrolDeviceCode").split("#")[0], map);
                    }
                }

            }
        })).start();
        return this.toAjax(this.patrolPresetPosService.deletePatrolPresetPosByPresetPosId(presetPosIds));
    }

    private void addPresetRecord(PresetAccessModel presetAccessModel) throws Exception {
        PatrolPresetRecord patrolPresetRecord = new PatrolPresetRecord();
        patrolPresetRecord.setCreateTime(DateUtils.getNowDate());
        patrolPresetRecord.setPresetPosCode(presetAccessModel.getPresetCode());
        patrolPresetRecord.setPresetPosName(presetAccessModel.getName());
        String channelCode = presetAccessModel.getChannelCode();
        String patrolDeviceCode = presetAccessModel.getPatrolDeviceCode();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("patrolDeviceCode", patrolDeviceCode);
        jsonObject.put("channelCode", channelCode);
        Object object = this.basedataChannelService.queryChannelList(jsonObject).getRows().get(0);
        JSONObject eqpBookChannel = JSONObject.parseObject(JSONObject.toJSONString(object));
        if (!eqpBookChannel.isEmpty()) {
            Long channelId = eqpBookChannel.getLongValue("channelId");
            Long eqpBookId = eqpBookChannel.getLongValue("eqpBookId");
            String channelType = eqpBookChannel.getString("channelType");
            patrolPresetRecord.setChannelId(channelId);
            patrolPresetRecord.setChannelCode(presetAccessModel.getChannelCode());
            patrolPresetRecord.setPatrolDeviceCode(patrolDeviceCode);
            patrolPresetRecord.setEqpBookId(eqpBookId);
            patrolPresetRecord.setChannelType(channelType);
            this.patrolPresetRecordService.insertPatrolPresetRecord(patrolPresetRecord);
        }

    }

    private void deletePresetRecord(PresetAccessModel presetAccessModel) throws Exception {
        PatrolPresetRecord patrolPresetRecord = new PatrolPresetRecord();
        patrolPresetRecord.setPresetPosCode(presetAccessModel.getPresetCode());
        String channelCode = presetAccessModel.getChannelCode();
        String patrolDeviceCode = presetAccessModel.getPatrolDeviceCode();
        patrolPresetRecord.setChannelCode(channelCode);
        patrolPresetRecord.setPatrolDeviceCode(patrolDeviceCode);
        List<PatrolPresetRecord> records = this.patrolPresetRecordService.selectPatrolPresetRecordList(patrolPresetRecord);
        if (!records.isEmpty()) {
            PatrolPresetRecord record = records.get(0);
            this.patrolPresetRecordService.deletePatrolPresetRecordByPresetRecordId(record.getPresetRecordId());
        }

    }
}
