import { WsClient } from '@arcblock/ws';
import get from 'lodash/get';
import { useEffect, useRef } from 'react';

const RELAY_SOCKET_PREFIX = '/.well-known/service/relay';
const getAppId = () => get(window, 'blocklet.appPid') || get(window, 'blocklet.appId') || '';
const getRelayChannel = (token: string) => `relay:${getAppId()}:${token}`;
const getRelayProtocol = () => (window.location.protocol === 'https:' ? 'wss:' : 'ws:');
const getSocketHost = () => new URL(window.location.href).host;

/**
 * @description channel 的值不能包含分隔符 / . : 等，否则前端接受不到事件
 * @export
 * @param {string} channel
 * @return {*}
 */
export function useSubscription(channel: string) {
  const socket = useRef<typeof WsClient>(null);
  const subscription = useRef<any>(null);

  useEffect(() => {
    if (getAppId()) {
      const needReconnect = !socket.current || socket.current.isConnected() === false;
      if (needReconnect) {
        socket.current = new WsClient(`${getRelayProtocol()}//${getSocketHost()}${RELAY_SOCKET_PREFIX}`, {
          longpollerTimeout: 5000, // connection timeout
          heartbeatIntervalMs: 30 * 1000,
        });
        socket.current.connect();
      }
    }

    return () => {
      if (socket.current) {
        socket.current.disconnect();
        socket.current = null;
      }
    };
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    if (channel) {
      let needSubscription = false;
      if (subscription.current) {
        if (subscription.current.channel !== channel) {
          socket.current?.unsubscribe(getRelayChannel(subscription.current.channel));
          needSubscription = true;
        }
      } else {
        needSubscription = true;
      }

      if (needSubscription && socket.current) {
        subscription.current = socket.current.subscribe(getRelayChannel(channel));
        subscription.current.channel = channel;
      }
    }

    return () => {
      if (subscription.current) {
        socket.current?.unsubscribe(getRelayChannel(subscription.current.channel));
        subscription.current = null;
      }
    };
  }, [channel]); // eslint-disable-line react-hooks/exhaustive-deps

  return subscription.current;
}
