import { ref, reactive, onUnmounted, nextTick } from "vue";
import { onHide } from "@dcloudio/uni-app";

/**
 * useWebSocket - 封装适用于 uni-app App 平台的 WebSocket Hook
 * 支持自动重连、心跳检测、事件监听、消息记录等
 *
 * @param {string} url WebSocket 服务器地址（如 wss://example.com/ws）
 * @param {object} options 可选配置项
 * @returns {object} 提供连接状态、消息、发送、断开等方法
 */
export default function useWebSocket(url, options = {}) {
  // 默认配置项
  const defaultOptions = {
    protocols: [], // 子协议
    autoConnect: true, // 是否自动连接
    reconnect: true, // 是否断线重连
    reconnectInterval: 3000, // 重连间隔（ms）
    maxReconnectAttempts: 3, // 最大重连次数
    heartbeat: true, // 是否启用心跳
    heartbeatInterval: 30000, // 心跳间隔（ms）
    heartbeatMessage: "ping", // 心跳消息内容
    ...options,
  };

  // 响应式状态
  const socketTask = ref(null); // WebSocket 实例
  const isConnected = ref(false); // 当前是否已连接
  const isConnecting = ref(false); // 当前是否正在连接
  const reconnectCount = ref(0); // 当前重连次数
  const lastMessage = ref(null); // 最后一条接收到的消息
  const messageHistory = ref([]); // 所有接收到的历史消息（上限100）

  // 事件监听器
  const listeners = reactive({
    open: [],
    message: [],
    error: [],
    close: [],
  });

  // 控制标志与定时器
  let reconnectTimer = null;
  let heartbeatTimer = null;
  let heartbeatTimeoutTimer = null;
  let isManuallyClosed = false; // 是否为手动断开（用于判断是否执行自动重连）

  /**
   * 创建 WebSocket 连接
   */
  const connect = () => {
    if (isConnected.value || isConnecting.value) {
      console.warn("WebSocket 已连接或正在连接中");
      return;
    }

    isConnecting.value = true;
    isManuallyClosed = false;

    // 发起连接
    socketTask.value = uni.connectSocket({
      url,
      protocols: defaultOptions.protocols,
      success: () => {
        console.log("WebSocket 连接请求已发出");
        nextTick(() => {
          setupListeners();
        });
      },
      fail: (err) => {
        isConnecting.value = false;
        console.error("WebSocket 连接请求失败:", err);
        handleError(err);
      },
    });
  };

  /**
   * 绑定 socket 事件监听器
   */
  const setupListeners = () => {
    console.log("socketTask.value", socketTask.value);
    if (!socketTask.value) return;

    socketTask.value.onOpen((res) => {
      console.log("WebSocket 已连接");
      isConnected.value = true;
      isConnecting.value = false;
      reconnectCount.value = 0;

      // 启动心跳机制
      if (defaultOptions.heartbeat) {
        startHeartbeat();
      }

      listeners.open.forEach((cb) => cb(res));
    });

    socketTask.value.onMessage((res) => {
      const message = {
        data: res.data,
        timestamp: Date.now(),
      };

      lastMessage.value = message;
      messageHistory.value.push(message);

      // 限制消息历史上限为100条
      if (messageHistory.value.length > 100) {
        messageHistory.value.shift();
      }

      listeners.message.forEach((cb) => cb(message));
    });

    socketTask.value.onError((err) => {
      console.error("WebSocket 发生错误:", err);
      handleError(err);
    });

    socketTask.value.onClose((res) => {
      console.log("WebSocket 已关闭", res);
      isConnected.value = false;
      isConnecting.value = false;

      stopHeartbeat();
      listeners.close.forEach((cb) => cb(res));

      // 自动重连（仅当未手动断开时）
      if (
        !isManuallyClosed &&
        defaultOptions.reconnect &&
        reconnectCount.value < defaultOptions.maxReconnectAttempts
      ) {
        attemptReconnect();
      }
    });
  };

  /**
   * 主动断开连接
   */
  const disconnect = () => {
    isManuallyClosed = true;
    clearReconnectTimer();
    stopHeartbeat();

    if (socketTask.value) {
      socketTask.value.close({
        code: 1000,
        reason: "客户端主动断开",
      });
    }

    isConnected.value = false;
    isConnecting.value = false;
    reconnectCount.value = 0;
    socketTask.value = null;
  };

  /**
   * 发送消息
   * @param {string|object} data 发送的数据（支持对象自动转 JSON）
   * @returns {Promise}
   */
  const send = (data) => {
    // console.log('isConnected', isConnected.value)
    if (!isConnected.value || !socketTask.value) {
      return Promise.reject(new Error("WebSocket 未连接"));
    }

    return new Promise((resolve, reject) => {
      try {
        const msg = typeof data === "object" ? JSON.stringify(data) : data;
        socketTask.value.send({
          data: msg,
          success: resolve,
          fail: reject,
        });
      } catch (err) {
        console.error("发送数据格式错误:", err);
        reject(err);
      }
    });
  };

  /**
   * 尝试自动重连
   */
  const attemptReconnect = () => {
    if (reconnectCount.value >= defaultOptions.maxReconnectAttempts) {
      console.warn("已达到最大重连次数，停止重连");
      return;
    }

    reconnectCount.value++;
    console.log(`尝试第 ${reconnectCount.value} 次重连...`);

    reconnectTimer = setTimeout(() => {
      connect();
    }, defaultOptions.reconnectInterval);
  };

  /**
   * 清除重连定时器
   */
  const clearReconnectTimer = () => {
    if (reconnectTimer) {
      clearTimeout(reconnectTimer);
      reconnectTimer = null;
    }
  };

  /**
   * 启动心跳检测
   */
  const startHeartbeat = () => {
    stopHeartbeat();

    heartbeatTimer = setInterval(() => {
      if (!isConnected.value) return;

      send(defaultOptions.heartbeatMessage)
        .then(() => {
          clearTimeout(heartbeatTimeoutTimer);
          heartbeatTimeoutTimer = setTimeout(() => {
            console.warn("心跳无响应，断开连接");
            socketTask.value?.close();
          }, defaultOptions.heartbeatInterval + 2000);
        })
        .catch((err) => {
          console.error("心跳发送失败:", err);
        });
    }, defaultOptions.heartbeatInterval);
  };

  /**
   * 停止心跳定时器
   */
  const stopHeartbeat = () => {
    if (heartbeatTimer) {
      clearInterval(heartbeatTimer);
      heartbeatTimer = null;
    }
    if (heartbeatTimeoutTimer) {
      clearTimeout(heartbeatTimeoutTimer);
      heartbeatTimeoutTimer = null;
    }
  };

  /**
   * 分发错误事件
   * @param {any} error
   */
  const handleError = (error) => {
    listeners.error.forEach((cb) => cb(error));
  };

  /**
   * 注册事件监听器
   * @param {string} event 事件名 open/message/error/close
   * @param {Function} callback
   */
  const on = (event, callback) => {
    if (listeners[event]) {
      listeners[event].push(callback);
    }
  };

  /**
   * 移除事件监听器
   * @param {string} event
   * @param {Function} callback
   */
  const off = (event, callback) => {
    if (listeners[event]) {
      const index = listeners[event].indexOf(callback);
      if (index > -1) {
        listeners[event].splice(index, 1);
      }
    }
  };

  /**
   * 清除消息历史
   */
  const clearHistory = () => {
    messageHistory.value = [];
    lastMessage.value = null;
  };

  /**
   * 手动执行重连（带清理）
   */
  const reconnect = () => {
    disconnect();
    nextTick(() => {
      reconnectCount.value = 0;
      isManuallyClosed = false;
      connect();
    });
  };

  // 页面加载时自动连接
  if (defaultOptions.autoConnect) {
    connect();
  }

  // 页面离开时时断开连接
  // onHide(() => {
  //   disconnect()
  // })

  // 对外暴露状态与操作方法
  return {
    isConnected,
    isConnecting,
    reconnectCount,
    lastMessage,
    messageHistory,
    connect,
    disconnect,
    send,
    reconnect,
    clearHistory,
    on,
    off,
  };
}
