import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import test from 'node:test'
import { fileURLToPath } from 'node:url'

import { checkBackendHealth, useBackendHealth } from '../src/composables/useBackendHealth.js'

const routerScript = readFileSync(
  fileURLToPath(new URL('../src/router/index.js', import.meta.url)),
  'utf8'
)
const backendUnavailableScript = readFileSync(
  fileURLToPath(new URL('../src/views/scripts/BackendUnavailableRouteView.js', import.meta.url)),
  'utf8'
)

test('app route guard allows stale healthy state when health check times out', () => {
  assert.match(routerScript, /checkBackendHealth\(\{\s*allowStaleOnTimeout:\s*true\s*\}\)/)
})

test('authenticated in-app navigation does not wait for backend health check', () => {
  assert.match(routerScript, /function isAuthenticatedAppNavigation\(to, from\)/)
  assert.match(
    routerScript,
    /if \(isAuthenticatedAppNavigation\(to, from\)\) \{[\s\S]*scheduleBackgroundBackendHealthCheck\(\)[\s\S]*return true[\s\S]*\}/
  )
})

test('backend health timeout does not block app rendering when stale fallback is allowed', async () => {
  const originalFetch = global.fetch

  global.fetch = async (_url, options = {}) =>
    new Promise((_, reject) => {
      options.signal.addEventListener('abort', () => {
        const error = new Error('aborted')
        error.name = 'AbortError'
        reject(error)
      })
    })

  try {
    const ok = await checkBackendHealth({
      force: true,
      allowStaleOnTimeout: true,
      timeoutMs: 1
    })
    const { backendHealthy, backendError } = useBackendHealth()

    assert.equal(ok, true)
    assert.equal(backendHealthy.value, true)
    assert.match(backendError.value, /健康检查超时|health/i)
  } finally {
    global.fetch = originalFetch
  }
})

test('backend unavailable page automatically recovers after service startup race', () => {
  assert.match(backendUnavailableScript, /onMounted\(\s*\(\)\s*=>\s*\{/)
  assert.match(backendUnavailableScript, /startAutoRecover\(\)/)
  assert.match(backendUnavailableScript, /globalThis\.setInterval/)
  assert.match(backendUnavailableScript, /router\.replace\(loggedIn\.value \? resolveEntryRoute\(\) : \{ name: 'login' \}\)/)
  assert.match(backendUnavailableScript, /onBeforeUnmount\(\s*\(\)\s*=>\s*\{/)
})
