import { defineStore } from "pinia";
import verConfig from "@/ver.config";
import { Toast } from "@/utils";
import { useUserStore } from "./user";

const state = () => ({
  socket: null,
  heartBeatInterval: null,
  connectNum: 1,
  timeout: 30000,
  heartbeatInterval: null,
  reconnectTimeOut: null,
  is_open_socket: false,
  traderDetailIndex: 100,
  accountStateIndex: 100,
  followFlake: false,
  init: false,
  networkStatus: true,
  socket_id: ''
})

export const useSocketStore = defineStore('socket', {
  state,
  getters: {
    socketId() {
      return this.socket_id;
    }
  },
  actions: {
    connect() {
      this.socket = uni.connectSocket({
        url: verConfig.wsUrl,
        success: () => { console.log("Connection successful") }
      })
      this.socket.onOpen(() => this.onOpen());
      this.socket.onMessage((res) => this.onMessage(res));
      this.socket.onClose(() => this.onClose());
    },

    CALLBACK(res) {
      if (res.isConnected) {
        this.traderDetailIndex = 2;
        this.connect()
      }
    },

    send(_data) {
      if (this.socket) {
        this.socket.send({
          data: JSON.stringify(_data),
          async success() { },
        });
      }
    },

    onOpen(event) {
      uni.$emit('socketStatus', true);
      if (!this.networkStatus) {
        uni.offNetworkStatusChange(this.CALLBACK);
      }
      this.networkStatus = true;
      this.connectNum = 1;
      // this.send({ "event": "pusher:subscribe", "data": { "auth": "", "channel": "chat" } });
      clearInterval(this.reconnectTimeOut)
      clearInterval(this.heartbeatInterval)
      this.is_open_socket = true;
      this.start();
    },

    onMessage(res) {
      const useUser = useUserStore();
      const messageData = JSON.parse(res.data || '{}');
      const message = (messageData.data && messageData.data != '{}') ? JSON.parse(messageData.data) : {};
      if (Object.keys(message).length && messageData.event != 'pusher:connection_established') { uni.$emit('$onMessage', { event: messageData.event, channel: messageData.channel || '', data: message }) }
      if (messageData.event === 'pusher:connection_established') {
        this.timeout = Number(message.activity_timeout) * 1000;
        this.socket_id = message.socket_id;
        if (useUser.getuserInfo.id && message.socket_id) return useUser.setAuth({ id: useUser.getuserInfo.id, socket_id: message.socket_id });
      }
    },

    onClose() {
      clearInterval(this.heartbeatInterval)
      clearInterval(this.reconnectTimeOut)
      this.is_open_socket = false;
      this.socket = null
      if (this.connectNum < 6) {
        this.reconnect();
      } else {
        uni.$emit('connectError');
        this.networkStatus = false;
        uni.onNetworkStatusChange(this.CALLBACK);
        this.connectNum = 1
      }
    },

    checkStatus() {
      console.log("检查状态")
      clearInterval(this.reconnectTimeOut)
      const { readyState } = this.socket
      if (!this.socket || [2, 3].includes(readyState)) {
        console.log("未链接！")
        return false;
      }
      return true;
    },

    start() {
      this.heartbeatInterval = setInterval(() => {
        this.send({ "event": "pusher:ping", "data": {} });
      }, this.timeout)
    },

    reconnect() {
      clearInterval(this.heartbeatInterval)
      if (!this.is_open_socket && (this.traderDetailIndex == 2 || this.accountStateIndex == 0 || this
        .followFlake)) {
        console.log("5秒后重新连接...")
        this.reconnectTimeOut = setInterval(() => {
          this.connect();
        }, 5000)
      }
    },

    closeScoket() {
      if (!this.is_open_socket) return;
      this.socket.close({
        success() { Toast('Scoket 关闭成功') }
      });
    },

    setSate(_state = {}) {
      let keys = Object.keys(_state);
      if (keys.length) {
        this[keys[0]] = _state[keys[0]]
      }
    }
  }
})