import { computed, ref, type ComputedRef } from 'vue'

import { POLL_INTERVAL_MS, POLL_FAILURE_LIMIT } from './sessionConstants'

export interface UseSessionPollingOptions {
  /** Whether there is an active session – used as a guard inside the poll loop. */
  hasSession: ComputedRef<boolean>
  /** Called on each poll tick (typically refreshSessionSummary). */
  onPollTick: () => Promise<unknown>
  /** Optional: determines whether polling should continue. Defaults to checking hasSession. */
  shouldKeepPolling?: ComputedRef<boolean>
  /** Context-specific warning message prefix when polling fails repeatedly. */
  pollWarningPrefix: string
}

export function useSessionPolling(options: UseSessionPollingOptions) {
  const { hasSession, onPollTick, pollWarningPrefix } = options

  const pollWarningMessage = ref('')

  let pollTimer: ReturnType<typeof setTimeout> | null = null
  let pollToken = 0
  let pollFailureCount = 0

  const sessionNotice = computed(() => pollWarningMessage.value)

  function startPolling() {
    const tokenId = ++pollToken

    const loop = async () => {
      if (tokenId !== pollToken || !hasSession.value) {
        return
      }

      await onPollTick()

      if (tokenId !== pollToken) {
        return
      }

      const keepPolling = options.shouldKeepPolling
        ? options.shouldKeepPolling.value
        : hasSession.value

      if (!keepPolling) {
        return
      }

      pollTimer = setTimeout(() => {
        void loop()
      }, POLL_INTERVAL_MS)
    }

    pollTimer = setTimeout(() => {
      void loop()
    }, POLL_INTERVAL_MS)
  }

  function resetPolling() {
    pollToken += 1

    if (pollTimer) {
      clearTimeout(pollTimer)
      pollTimer = null
    }
  }

  function resetPollingWarning() {
    pollFailureCount = 0
    pollWarningMessage.value = ''
  }

  function handleSilentPollingError(error: unknown) {
    console.error(error)
    pollFailureCount += 1

    if (pollFailureCount < POLL_FAILURE_LIMIT) {
      return
    }

    pollWarningMessage.value = `${pollWarningPrefix}，已暂停自动轮询，请手动刷新。`
    resetPolling()
  }

  return {
    pollWarningMessage,
    sessionNotice,
    startPolling,
    resetPolling,
    resetPollingWarning,
    handleSilentPollingError,
  }
}
