// 全局 WS 配置接口
interface WsConfig {
  url: string
  reconnectMaxTimes: number // 最大重连次数
  reconnectDelay: number // 重连延迟（毫秒）
  heartbeatInterval: number // 心跳间隔（毫秒）
  heartbeatMsg: string // 心跳消息
}

// 默认配置（适配你的项目环境变量）
const defaultConfig: WsConfig = {
  url: `ws://localhost:${import.meta.env.VITE_PRINT_EXE_API_URL}/ws/`,
  reconnectMaxTimes: 30,
  reconnectDelay: 5000,
  heartbeatInterval: 10000,
  heartbeatMsg: JSON.stringify({ Type: 'heartbeat' })
}

// 全局状态管理
let wsInstance: WebSocket | null = null
let reconnectCount = 0 // 已重连次数
let isReconnecting = false // 是否正在重连
let heartbeatTimer: NodeJS.Timeout | null = null // 心跳定时器
const tips = { value: '' } // 临时提示状态（适配示例中的提示逻辑）

/**
 * 初始化/重连 WebSocket 实例
 * @param config 自定义配置（可选）
 * @returns Promise<WebSocket>
 */
export const initWebSocket = (config: Partial<WsConfig> = {}): Promise<WebSocket> => {
  const finalConfig = { ...defaultConfig, ...config }

  // 防止重复重连
  if (isReconnecting) {
    return Promise.reject(new Error('WebSocket 正在重连中，请稍等'))
  }

  // 超过最大重连次数
  if (reconnectCount >= finalConfig.reconnectMaxTimes) {
    return Promise.reject(
      new Error(`WebSocket 重连已达到最大次数(${finalConfig.reconnectMaxTimes})，请检查服务端`)
    )
  }

  isReconnecting = true
  reconnectCount++

  // 关闭旧实例
  if (wsInstance) {
    try {
      wsInstance.close(1000, '主动关闭旧连接，准备重连')
    } catch (e) {
      console.warn('关闭旧 WebSocket 实例失败:', e)
    }
    wsInstance = null
  }

  return new Promise((resolve, reject) => {
    try {
      // 创建新的 WebSocket 实例
      wsInstance = new WebSocket(finalConfig.url)

      // 连接成功回调
      wsInstance.onopen = () => {
        console.log('WebSocket 连接成功')
        globalThis.socketOpen = true
        isReconnecting = false
        reconnectCount = 0 // 重置重连次数

        // // 启动心跳检测
        // startHeartbeat(finalConfig)

        resolve(wsInstance!)
      }

      // 连接错误回调
      wsInstance.onerror = (error) => {
        // console.error('WebSocket 连接错误:', error)
        globalThis.socketOpen = false
        isReconnecting = false
        reject(new Error('WebSocket 连接错误'))
      }

      // 连接关闭回调
      wsInstance.onclose = (event) => {
        // console.log('WebSocket 连接关闭:', event.reason, event.code)
        globalThis.socketOpen = false
        isReconnecting = false

        // 停止心跳
        stopHeartbeat()

        // 非主动关闭且未达最大次数，自动重连
        if (event.code !== 1000 && reconnectCount) {
          // console.log(
          //   `WebSocket 异常断开，${finalConfig.reconnectDelay}ms 后尝试第 ${reconnectCount + 1} 次重连`
          // )
          setTimeout(() => {
            initWebSocket(finalConfig).catch(() => {})
          }, finalConfig.reconnectDelay)
        }
      }
    } catch (error) {
      isReconnecting = false
      reject(new Error(`创建 WebSocket 实例失败: ${(error as Error).message}`))
    }
  })
}

/**
 * 通用 WebSocket 请求方法（自动处理重连）
 * @param params 请求参数
 * @returns Promise<any>
 */
export const sendWebSocketRequest = async (params: {
  requestType: string
  responseType: string
  timeoutMessage: string
  data?: any
}) => {
  const { requestType, responseType, timeoutMessage, data } = params

  // 步骤1：检查 WS 连接，断开则自动重连
  let ws: WebSocket
  try {
    // 如果已有实例且连接正常，直接使用；否则初始化（重连）
    if (wsInstance && wsInstance.readyState === WebSocket.OPEN) {
      ws = wsInstance
    } else {
      tips.value = 'WebSocket 连接断开，自动重连中...'
      ws = await initWebSocket() // 重连成功后返回实例
    }
  } catch (reconnectError) {
    throw new Error(`重连失败：${(reconnectError as Error).message}`)
  }

  // 步骤2：发送请求（复用原有逻辑）
  return new Promise((resolve, reject) => {
    // 监听消息回调
    const handleMessage = (event: MessageEvent) => {
      console.log(`收到${responseType}消息:`, event.data)
      try {
        const resData = JSON.parse(event.data)
        console.log('解析后的数据:', resData)

        // 匹配响应类型：成功
        if (resData.Type === responseType) {
          ws.removeEventListener('message', handleMessage)
          resolve(resData)
        }

        // 业务错误
        if (resData.Type === 'error' || resData.Type === 'Error') {
          ws.removeEventListener('message', handleMessage)
          reject(new Error(resData.Error?.Message || '请求失败'))
        }
      } catch (parseError) {
        ws.removeEventListener('message', handleMessage)
        reject(new Error(`解析${responseType}消息失败：${(parseError as Error).message}`))
      }
    }

    // 绑定消息监听
    ws.addEventListener('message', handleMessage)

    // 构造并发送请求数据
    const sendData = {
      Type: requestType, // 补充请求类型（适配业务逻辑）
      ...data
    }
    console.log(`发送${requestType}请求:`, sendData)
    ws.send(JSON.stringify(sendData))

    // 超时处理（10秒）
    setTimeout(() => {
      ws.removeEventListener('message', handleMessage)
      reject(new Error(timeoutMessage))
    }, 10000)
  })
}

/**
 * 启动心跳检测
 * @param config 配置项
 */
const startHeartbeat = (config: WsConfig) => {
  stopHeartbeat() // 先清除旧定时器
  if (wsInstance && wsInstance.readyState === WebSocket.OPEN) {
    heartbeatTimer = setInterval(() => {
      try {
        wsInstance!.send(config.heartbeatMsg)
      } catch (e) {
        console.warn('发送心跳包失败:', e)
      }
    }, config.heartbeatInterval)
  }
}

/**
 * 停止心跳检测
 */
const stopHeartbeat = () => {
  if (heartbeatTimer) {
    clearInterval(heartbeatTimer)
    heartbeatTimer = null
  }
}

/**
 * 销毁 WS 实例（组件卸载/页面关闭时调用）
 */
export const destroyWebSocket = () => {
  stopHeartbeat()
  if (wsInstance) {
    wsInstance.close(1000, '主动销毁实例')
    wsInstance = null
  }
  reconnectCount = 0
  isReconnecting = false
}

// 暴露当前 WS 实例（供调试/特殊场景使用）
export const getWsInstance = () => wsInstance
