package com.baoshi.swms.net.listener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import com.baoshi.swms.net.constant.SwmsWebSocketConstant;
import com.google.gson.Gson;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Date;

import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;

/**
 * websocket监听程序
 *
 * @author Zhendong Zhou
 * @date 2021/12/9 16:55
 */
public class SwmsWebSocketListener extends WebSocketListener {

    private final int HEARTBEAT_HZ = 10; //S
    private final String SUBSCRIBE = "{\"dataType\":\"subscribe\",\"subscribeList\":[{\"subType\":\"pieceSize\"}]}";
    public boolean START_STATUS = false;
    public WebSocket webSocket;
    public Handler handler;
    private final Long timestamp;

    //构造方法获取主线程的消息处理器
    public SwmsWebSocketListener(Handler handler){
        this.timestamp = new Date().getTime(); //先记录下尝试启动时的时间戳
        this.handler = handler;
    }
    @Override
    public void onOpen(@NotNull WebSocket webSocket, @NotNull Response response) {
        this.webSocket = webSocket;
        openTimeTask();
    }

    @Override
    public void onMessage(@NotNull WebSocket webSocket, @NotNull String text) {
        Gson gson = new Gson();
        Struct struct = gson.fromJson(text, Struct.class);
        if (isPushMsg(struct)){
            //执行UI更新
            Message message = handler.obtainMessage();
            message.obj = SwmsWebSocketConstant.PULL_SIGN;
            Bundle arg = new Bundle();
            arg.putInt("number",((Double) struct.getData()).intValue());
            message.setData(arg);
            handler.sendMessage(message);
        }
    }

    @Override
    public void onFailure(@NotNull WebSocket webSocket, @NotNull Throwable t, @Nullable Response response) {
        closeTimeTask();
    }

    @Override
    public void onClosing(@NotNull WebSocket webSocket, int code, @NotNull String reason) {
        closeTimeTask();
    }

    @Override
    public void onClosed(@NotNull WebSocket webSocket, int code, @NotNull String reason) {
        closeTimeTask();
    }

    private void openTimeTask(){
        START_STATUS = true;
        new Thread(()->{
            try {
                while (START_STATUS){
                    webSocket.send(SUBSCRIBE);
                    Thread.sleep(HEARTBEAT_HZ * 1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }

    private void closeTimeTask(){
        START_STATUS = false;

        //如果启动时间至关闭 不足十秒让他sleep 防止频繁的消息推送
        long diff = new Date().getTime()-this.timestamp;
        long touch = (long) (HEARTBEAT_HZ * 1000);
        if (diff < touch){
            try{
                Thread.sleep(touch-diff);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //通知主线程 websocket监听被关闭,让它重启
        Message message = handler.obtainMessage();
        message.obj = SwmsWebSocketConstant.CLOSE_SIGN;
        handler.sendMessage(message);
    }

    private boolean isPushMsg(Struct struct){
        return "subscribe.pieceSize".equals(struct.getDataType());
    }

    static class Struct{
        private Object data;
        private String dataType;

        public String getDataType() {
            return dataType;
        }

        public void setDataType(String dataType) {
            this.dataType = dataType;
        }

        public Object getData() {
            return data;
        }

        public void setData(Object data) {
            this.data = data;
        }
    }
}
