import { Injectable } from "@angular/core";
import { Subject, Observable, from } from "rxjs";
import * as Atmosphere from "atmosphere.js";

@Injectable({
  providedIn: "root",
})
export class WebsocketIndexService {
  constructor() { }
  private lockReconnect = false; //避免ws重复连接
  ws = null; //定义websocket
  private url = ""; //ws连接地址
  private urlParams; //ws连接传参
  private isHandler = false; //是否手动
  private subject;
  private reconnectTimer = null;//重连的计时器
  // 连接websocket
  connectWs(url, data): Observable<any> {
    this.url = url;
    this.urlParams = data;
    this.subject = new Subject<any>();
    let request: any = {
      webSocketUrl: url,
      trackMessageLength: true, //校验数据完整性
      transport: "websocket",
      handleOnlineOffline: false,
      suspend: false,
      maxReconnectOnClose: 0,
    };

    request.onOpen = (response) => {
      console.log("ws连接成功" + new Date().toLocaleString());
      this.heartCheck.reset().start(this);
      console.log(response);
      this.ws.push(JSON.stringify(data));
    };

    request.onMessage = (response) => {
      this.heartCheck.reset().start(this);
      let message = response.responseBody;
      try {
        console.log("收到消息" + message);
        if (message !== "pong") {
          this.subject.next(JSON.parse(message));
        }
      } catch (e) {
        console.log("This doesn't look like a valid JSON: ", message);
        return;
      }
    };

    request.onClose = (response) => {
      console.log("ws连接关闭" + new Date().toLocaleString(), this.isHandler);
      this.ws = null;
      console.log(response)
      if (!this.isHandler && response.status === 408) {
        this.reconnect(this.url, this.urlParams);
      }
    };

    request.onError = (response) => {
      console.log("ws连接错误", this.isHandler);
      this.ws = null;
      if (response.status === 0) {
        this.reconnect(this.url, this.urlParams);
      }
    };
    this.ws = Atmosphere.subscribe(request);
    return this.subject.asObservable();
  }
  //断线重连
  private reconnect(url, data) {
    if (this.lockReconnect) return;
    this.lockReconnect = true;
    this.reconnectTimer = setTimeout(() => {
      //没连接上会一直重连，设置延迟避免请求过多
      this.connectWs(url, data);
      this.lockReconnect = false;
    }, 15000);
  }
  private heartCheck = {
    timeout: 30000, //发一次心跳的间隔时间
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function () {
      clearTimeout(this.timeoutObj);
      clearTimeout(this.serverTimeoutObj);
      return this;
    },
    start: function (_this) {
      this.timeoutObj = setTimeout(() => {
        //这里发送一个心跳，后端收到后，返回一个心跳消息，
        //onmessage拿到返回的心跳就说明连接正常
        if (_this.ws) {
          _this.ws.push("ping");
        }
        this.serverTimeoutObj = setTimeout(() => {
          //如果超过一定时间还没重置，说明后端主动断开了
          _this.closeWs(); //如果onclose会执行reconnect，我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
        }, this.timeout);
      }, this.timeout);
    },
  };

  // 断开websocket
  closeWs(flag: boolean = false) {
    this.isHandler = flag;
    if (flag) {
      clearTimeout(this.reconnectTimer);
    }
    if (this.ws) {
      this.ws.close();
    }
  }
}
