package com.imdroid.sideslope.service;

import com.imdroid.secapi.dto.GnssDevice;
import com.imdroid.sideslope.bd.Gga;
import com.imdroid.sideslope.bd.UBXUtil;
import lombok.Data;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 基站 & 测站设备
 *
 * @author Layton
 * @date 2023/2/3 20:39
 */
@Data
public class Device {

    /**
     * 基站
     */
    public static final int DEVICE_BASE_STATION = 1;

    /**
     * 测站
     */
    public static final int DEVICE_ROVER = 0;

    public static final byte CHANNEL_TYPE_TCP = 0;
    public static final byte CHANNEL_TYPE_UDP = 1;

    private String name;
    private Integer tenantId;

    private String deviceId;

    private String parentId;
    private String projectId;
    private String fwdId;

    private Integer deviceType;
    private Short model;

    private Integer calcGroupId;
    private Short opMode;
    private boolean b562AsCalc = true;//算法版本
    private Integer basicGroupId;
    private short gnssSampleRate = 1;

    int d3xxCount = 0;
    int d3xxbytes = 0;
    int d341Count = 0;
    int d341bytes = 0;
    int d342Bytes = 0;
    int d342Count = 0;
    int d341In42Count = 0;
    int satelitesInUse = 0;//平均卫星数
    int sataStatCount = 0;
    int jumpCount = 0;

    Double latitude;
    Double longitude;
    Double altitude;
    Double ecefx;
    Double ecefy;
    Double ecefz;

    Double iPose;
    Double iPosn;
    Double iPosd;
    private BigDecimal remaining;
    private BigDecimal total;
    private BigDecimal used;

    LocalDateTime lastRxTime;
    LocalDateTime lastD3f0f2Time;
    LocalDateTime lastD3f2Time;
    short noFixedAndFloatResult=0;

    // 日志记录控制
    Short loggingmode;

    int lastRxHead = 0;

    int fixedNum = 0;
    int floatNum = 0;
    LocalDateTime lastValidCalcDataTime; //最近一次有效解
    int warningcode = 0;
    short abnormalD341Num = 0;
    byte cfgChannelType = CHANNEL_TYPE_TCP; // 0:TCP;1:DUP
    byte dataChannelType = CHANNEL_TYPE_UDP; // 0:TCP;1:DUP
    int lasQuality = 0;

    public void updateRx(int head, int bytes,int count){
        lastRxHead = head;

        switch (head){
            case 0xd3f0:
                lastD3f0f2Time = LocalDateTime.now();
                //clearStat();
                break;
            case 0xd3f2:
                lastD3f2Time = LocalDateTime.now();
                break;
            case 0xd331:
                d3xxCount+=count;
                d3xxbytes += bytes;
                lastRxTime = LocalDateTime.now();
                break;
            case 0xd341:
                d341Count+=count;
                d341bytes += bytes;
                lastRxTime = LocalDateTime.now();
                if(model== GnssDevice.MODEL_G510 && bytes>100) abnormalD341Num++;
                break;
            case 0xd342:
                d342Count ++;
                d342Bytes += bytes;
                d341In42Count += count;
                break;
        }
    }

    public void updateSatelitesNum(int num){
        if(num>0) {
            sataStatCount++;
            satelitesInUse = (satelitesInUse*(sataStatCount-1) + num) / sataStatCount;
        }
    }

    public void updateCalcQuality(int quality){
        lasQuality = quality;
        if(b562AsCalc) {
            if (quality == UBXUtil.FIX_RESULT) fixedNum++;
            else if (quality == UBXUtil.FLOAT_RESULT) floatNum++;
        }
        else{
            if (quality == Gga.FIX_RESULT) fixedNum++;
            else if (quality == Gga.FLOAT_RESULT) floatNum++;
        }
    }

    public void clearStat(){
        if(fixedNum+floatNum <= 5 && deviceType == DEVICE_ROVER) noFixedAndFloatResult++;
        else noFixedAndFloatResult = 0;

        d3xxCount = 0;
        d3xxbytes = 0;
        d341Count = 0;
        d341bytes = 0;
        sataStatCount = 0;
        satelitesInUse = 0;
        fixedNum = 0;
        floatNum = 0;
        jumpCount = 0;
    }

    public void clearD342Stat(){
        d342Count = 0;
        d342Bytes = 0;
        d341In42Count = 0;
    }

    public void clearNoResultStat(){
        noFixedAndFloatResult = 0;
        warningcode = 0;
        abnormalD341Num = 0;
    }

}
