package com.huashe.park.application.engine.impl;

import com.alibaba.fastjson2.JSONObject;
import com.huashe.park.application.engine.EvtFusionEngine;
import com.huashe.park.application.engine.LocationInfo;
import com.huashe.park.application.socket.server.PointWebSocketServer;
import com.huashe.park.infrastructure.cfg.mqtt.MqttCfg;
import com.huashe.park.common.DateTimeUtil;
import com.huashe.park.common.consts.BDConst;
import com.huashe.park.core.service.IBdDevcTrailUwbService;
import com.huashe.park.domain.entity.BdDevcTrailUwb;
import net.dreamlu.iot.mqtt.spring.client.MqttClientTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * The type Point fusion engine.
 *
 * @author chen.cheng
 */
@Service
@ConditionalOnBean(MqttClientTemplate.class)
public class PointFusionEngine extends EvtFusionEngine {

    @Autowired
    private IBdDevcTrailUwbService bdDevcTrailUwbService;

    /**
     * The constant MAX_POINT_DISTANCE.
     * 单位米
     *
     * @author chen.cheng
     */
    private static final int MAX_POINT_DISTANCE = 5;

    /**
     * The constant MAX_POINT_TIME_GAP.
     * 单位秒
     *
     * @author chen.cheng
     */
    private static final int MAX_POINT_TIME_GAP = 2;

    @Autowired
    private PointWebSocketServer webSocketServer;

    private final List<LinkedBlockingQueue<JSONObject>> messageQueueList = new ArrayList<>(5);

    @PostConstruct
    public void init() {
        super.init();
        this.setEngineName("坐标点位抽稀");
    }

    @Override
    public Boolean check(LocationInfo older, LocationInfo newer) {
        long gap = newer.getSrcTimestamp() - older.getSrcTimestamp();
        // 将gap 转换为秒
        gap = gap / 1000;
        boolean isSamePoint = Double.compare(older.getLatitude(), newer.getLatitude()) == 0 && Double.compare(older.getLongitude(), newer.getLongitude()) == 0;
        return gap <= MAX_POINT_TIME_GAP && isSamePoint;
    }
    @Override
    public String getKey(LocationInfo msg) {
        return BDConst.REDIS_KEY.BD_POINT_KEY + msg.getMsg().getString("deviceId");
    }

    @Override
    public List<LinkedBlockingQueue<JSONObject>> getQueue() {
        return messageQueueList;
    }

    @Override
    public void getBizId(LocationInfo msg) {
        long evtTimestamp = msg.getEvtTimestamp();
        BdDevcTrailUwb bdDevcTrailUwb = new BdDevcTrailUwb();
        bdDevcTrailUwb.setDevcKey(msg.getMsg().getString("deviceId"));
        bdDevcTrailUwb.setLat(msg.getLatitude());
        bdDevcTrailUwb.setLng(msg.getLongitude());
        bdDevcTrailUwb.setDt(DateTimeUtil.currentDateTime(DateTimeUtil.DateFormatter.yyyyMMdd));
        bdDevcTrailUwb.setTp(MAX_POINT_TIME_GAP);
        bdDevcTrailUwb.setStepIndex(DateTimeUtil.getStepIndexFromMills(MAX_POINT_TIME_GAP, evtTimestamp));
        bdDevcTrailUwbService.insertBdDevcTrailUwb(bdDevcTrailUwb);
        msg.setBizId(bdDevcTrailUwb.getId().toString());
    }

    @Override
    public void newEvtCallback(LocationInfo msg) {
        webSocketServer.sendInfo(msg.getMsg().getString("deviceId"), msg.getMsg().toJSONString());
    }

    public void pushDevcLocation(LocationInfo msg) {
        webSocketServer.sendInfo(msg.getMsg().getString("deviceId"), msg.getMsg().toJSONString());
    }
}
