package com.inspect.job.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.inspect.access.base.feign.AccessFeign;
import com.inspect.access.base.model.LoginModel;
import com.inspect.access.base.vo.OnlineStatsVo;
import com.inspect.base.core.constant.Color;
import com.inspect.base.websocket.configure.WsPool;
import com.inspect.base.core.domain.Response;
import com.inspect.base.core.utils.DateUtils;
import com.inspect.base.core.utils.HttpClientUtils;
import com.inspect.base.redis.service.RedisService;
import com.inspect.ivs.base.feign.IvsFeign;
import com.inspect.job.client.MontQueryClient;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("patrolDeviceStatusSynTask")
public class PatrolDeviceStatusSynTask {
    Logger logger = LoggerFactory.getLogger(PatrolDeviceStatusSynTask.class);

    @Value("${liveSIPB.url}")
    private String liveSIPB_URL;
    @Value("${spring.rabbitmq.listener.montdata.exchange.name}")
    private String exchange;
    @Value("${spring.rabbitmq.listener.montdata.queue.name}")
    private String queue;
    @Value("${spring.rabbitmq.listener.montdata.key}")
    private String routingKey;
    @Value("${nvr.ip}")
    private String nvr_ip;
    @Value("${nvr.port}")
    private int nvr_port;
    @Value("${nvr.username}")
    private String nvr_username;
    @Value("${nvr.password}")
    private String nvr_password;
    @Value("${nvr.nvrcode}")
    private String nvr_nvrcode;

    final
    RabbitTemplate rabbitTemplate;
    final
    AccessFeign accessFeign;
    final
    RedisService redisService;
    final
    MontQueryClient montQueryClient;
    final
    MontQueryClient basedataClient;
    final
    IvsFeign ivsFeign;

    public PatrolDeviceStatusSynTask(RabbitTemplate rabbitTemplate, AccessFeign accessFeign, RedisService redisService, MontQueryClient montQueryClient, MontQueryClient basedataClient, IvsFeign ivsFeign) {
        this.rabbitTemplate = rabbitTemplate;
        this.accessFeign = accessFeign;
        this.redisService = redisService;
        this.montQueryClient = montQueryClient;
        this.basedataClient = basedataClient;
        this.ivsFeign = ivsFeign;
    }

    public void synPatrolEqpOnlineStatusFromGwbMedia() {
        String url = liveSIPB_URL + "/api/v1/device/channellist";
        String result;

        try {
            result = HttpClientUtils.get(url, StringUtils.EMPTY);
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (null != jsonObject) {
                JSONArray jsonObjectItems = jsonObject.getJSONArray("ChannelList");
                if (null != jsonObjectItems) {
                    Object data = this.basedataClient.list(new JSONObject()).getRows();
                    JSONArray objects = JSONArray.parseArray(JSONObject.toJSONString(data));
                    System.out.println("synPatrolEqpOnlineStatusFromGwbMedia，JSONObject.toJSONString(data)::" + JSONObject.toJSONString(data));
                    List<String> list = objects.stream().map((item) -> JSONObject.parseObject(JSONObject.toJSONString(item)).getString("patroldeviceCode")).collect(Collectors.toList());
                    for (int i = 0; i < jsonObjectItems.size(); ++i) {
                        JSONObject item = jsonObjectItems.getJSONObject(i);
                        String patrolDeviceCode = item.getString("ID");
                        String patrolDeviceName = item.getString("Name");
                        boolean online = item.getBoolean("Status");
                        if (list.contains(patrolDeviceCode) && online) {
                            JSONObject json = new JSONObject();
                            json.put("SendCode", "nvrGwbMedia");
                            json.put("heartBeatInterval", 1800);
                            json.put("Type", "heartbeat");
                            json.put("patrolDeviceCode", patrolDeviceCode);
                            json.put("eventType", "heart");
                            String jsonString = json.toJSONString();
                            rabbitTemplate.convertAndSend(exchange, routingKey, jsonString);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void synPatrolEqpOnlineStatusFromGwbMedia2() {
        try {
            JSONObject jsonObject = this.ivsFeign.channelListJson(new JSONObject());
            String resultCode = jsonObject.getString("resultCode");
            logger.debug(Color.MAGENTA + "synPatrolEqpOnlineStatusFromGwbMedia2 resultCode: {}, result: {}" + Color.END, resultCode, jsonObject.toJSONString());
            if (null != resultCode && resultCode.equals("0")) {
                //摄像机设备信息V2版本列表（根据请求中deviceType字段确定返回类型）
                JSONObject cameraBriefInfosV2 = jsonObject.getJSONObject("cameraBriefInfosV2");
                if (null != cameraBriefInfosV2) {
                    int total = cameraBriefInfosV2.getInteger("total");
                    logger.debug("synPatrolEqpOnlineStatusFromGwbMedia2 cameraBriefInfosV2.total: {}", total);
                    if (total > 0) {
                        JSONArray ivsJsonObjectItems = cameraBriefInfosV2.getJSONObject("cameraBriefInfoList").getJSONArray("cameraBriefInfo");
                        if (!ivsJsonObjectItems.isEmpty()) {
                            Object basedata = basedataClient.list(new JSONObject()).getRows();
                            JSONArray patrolDeviceObjects = JSONArray.parseArray(JSONObject.toJSONString(basedata));
                            logger.debug("synPatrolEqpOnlineStatusFromGwbMedia2 patrolDeviceObjects size: {}", patrolDeviceObjects.size());
                            Map<String, Boolean> ivsDeviceStatusMap = new HashMap<>();
                            if (!patrolDeviceObjects.isEmpty()) {
                                for (int i = 0; i < ivsJsonObjectItems.size(); ++i) {
                                    JSONObject item = ivsJsonObjectItems.getJSONObject(i);
                                    String patrolDeviceCode = item.getString("code");
                                    int status = item.getInteger("status");
                                    if (status == 1) {
                                        ivsDeviceStatusMap.put(patrolDeviceCode, Boolean.TRUE);
                                    }
                                }
                            }

                            int heart_beat_interval = 1800;
                            int heartBeatInterval = (int) Math.floor((double) heart_beat_interval * 1.5D);
                            Date nowTime = DateUtils.getNowDate();
                            String dateTimeNowFormat = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, nowTime);
                            int webSendFlag = 0;

                            for (int i = 0; i < patrolDeviceObjects.size(); ++i) {
                                JSONObject item = patrolDeviceObjects.getJSONObject(i);
                                String patrolDeviceCode = item.getString("patrolDeviceCode");
                                if (StringUtils.isEmpty(patrolDeviceCode)) {
                                    patrolDeviceCode = item.getString("patroldeviceCode");
                                }
                                Long eqpBookId = item.getLongValue("eqpBookId");
                                if (eqpBookId == 0) {
                                    eqpBookId = item.getLongValue("eqpbookId");
                                }
                                if (ivsDeviceStatusMap.containsKey(patrolDeviceCode)) {
                                    boolean online = ivsDeviceStatusMap.get(patrolDeviceCode);
                                    if (online) {
                                        Boolean hasKey = redisService.hasKey("mont_patrol_device_online_status:" + patrolDeviceCode);
                                        if (!hasKey) {
                                            if (webSendFlag == 0) {
                                                webSendFlag = 1;
                                            }

                                            JSONObject returnJsonObject = patrolDeviceMesHandle(patrolDeviceCode, null, eqpBookId, heart_beat_interval, heartBeatInterval, dateTimeNowFormat);
                                            redisService.setCacheObject("mont_patrol_device_online_status:" + patrolDeviceCode, returnJsonObject);
                                            redisService.expire("mont_patrol_device_online_status:" + patrolDeviceCode, heartBeatInterval);
                                        } else {
                                            redisService.expire("mont_patrol_device_online_status:" + patrolDeviceCode, heartBeatInterval);
                                        }
                                    }
                                }

                                patrolDeviceChannelOnlineHandle(ivsDeviceStatusMap, patrolDeviceCode, eqpBookId, heart_beat_interval, heartBeatInterval, dateTimeNowFormat, webSendFlag);
                            }

                            if (webSendFlag == 1) {
                                JSONObject item = patrolDeviceObjects.getJSONObject(0);
                                String patrolDeviceCode = item.getString("patrolDeviceCode");
                                if (StringUtils.isEmpty(patrolDeviceCode)) {
                                    patrolDeviceCode = item.getString("patroldeviceCode");
                                }
                                Long eqpBookId = item.getLongValue("eqpBookId");
                                if (eqpBookId == 0) {
                                    eqpBookId = item.getLongValue("eqpbookId");
                                }
                                JSONObject returnJsonObject = patrolDeviceMesHandle(patrolDeviceCode, null, eqpBookId, heart_beat_interval, heartBeatInterval, dateTimeNowFormat);
                                parseMessage(JSON.toJSONString(returnJsonObject));
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void synNvrOnlineStatusFromSdk() {
        LoginModel loginModel = new LoginModel();
        loginModel.setIp(this.nvr_ip);
        loginModel.setPort(this.nvr_port);
        loginModel.setUsername(this.nvr_username);
        loginModel.setPassword(this.nvr_password);
        Response<List<OnlineStatsVo>> online = this.accessFeign.online(loginModel);
        List list = online.getData();
        if (null != list && !list.isEmpty()) {
            JSONObject json = new JSONObject();
            json.put("heartBeatInterval", 60);
            json.put("Type", "heartbeat");
            json.put("patrolDeviceCode", this.nvr_nvrcode);
            json.put("eventType", "heart");
            String jsonString = json.toJSONString();
            this.rabbitTemplate.convertAndSend(this.exchange, this.routingKey, jsonString);
        }

    }

    public void synNvrStorageStatusFromSdk() {
        this.montQueryClient.synNvrStorageStatusFromSdk();
    }

    public void statisBasedataStatisRobotUavOnlineDay() {
        System.out.println("EXEC statisBasedataStatisRobotUavOnlineDay");
        this.montQueryClient.statisBasedataStatisRobotuavOnlineDay();
    }

    public void patrolDeviceChannelOnlineHandle(
            Map<String, Boolean> ivsDeviceStatusMap,
            String patrolDeviceCode,
            Long eqpBookId,
            int heart_beat_interval,
            int heartBeatInterval,
            String dateTimeNowFormat,
            int webSendFlag) {
        JSONObject channelQuery = new JSONObject();
        channelQuery.put("eqpBookId", eqpBookId);
        Object channelDataObject = this.basedataClient.channelList(channelQuery).getRows();
        JSONArray channelDataJsonList = JSONArray.parseArray(JSONObject.toJSONString(channelDataObject));
        if (null != channelDataJsonList && !channelDataJsonList.isEmpty()) {
            for (Object channelObject : channelDataJsonList) {
                JSONObject channelJson = (JSONObject) JSONObject.toJSON(channelObject);
                String channelCode = channelJson.getString("channelCode");
                Boolean hasKey = this.redisService.hasKey("mont_patrol_device_channel_online_status:" + channelCode);
                if (!hasKey) {
                    if (webSendFlag == 0) {
                        webSendFlag = 1;
                    }

                    if (ivsDeviceStatusMap.containsKey(channelCode)) {
                        JSONObject returnJsonObject = this.patrolDeviceMesHandle(patrolDeviceCode, channelCode, eqpBookId, heart_beat_interval, heartBeatInterval, dateTimeNowFormat);
                        this.redisService.setCacheObject("mont_patrol_device_channel_online_status:" + channelCode, returnJsonObject);
                        this.redisService.expire("mont_patrol_device_channel_online_status:" + channelCode, heartBeatInterval);
                    }
                } else {
                    this.redisService.expire("mont_patrol_device_channel_online_status:" + channelCode, heartBeatInterval);
                }
            }
        }
    }

    public JSONObject patrolDeviceMesHandle(String patrolDeviceCode, String channelCode, Long eqpBookId, int heartBeatInterval, int heartBeatInterval2, String dateTimeNowFormat) {
        JSONObject returnJsonObject = new JSONObject();
        returnJsonObject.put("eqpBookId", eqpBookId);
        returnJsonObject.put("patrolDeviceChannelCode", channelCode);
        returnJsonObject.put("patrolDeviceCode", patrolDeviceCode);
        returnJsonObject.put("heartBeatInterval", heartBeatInterval);
        returnJsonObject.put("patrolDeviceOnlineStatus", "1");
        returnJsonObject.put("heart_beat_time", dateTimeNowFormat);
        returnJsonObject.put("receiveTime", dateTimeNowFormat);
        returnJsonObject.put("event", "mont/montHeartBeatData");
        return returnJsonObject;
    }

    public void parseMessage(String order) {
        WsPool.sendMessageToAll(order);
    }
}
