import { runtimeConfig } from '../../config/runtime.js'

const DEFAULT_TIMEOUT_MS = 60_000

type OcrAction = 'recognize' | 'batch'

type OcrRequestPayload = Record<string, unknown>

type OcrHttpResult = Record<string, any> & {
  code: number
  msg?: string
}

export async function recognizeTencentCaptcha(payload: OcrRequestPayload): Promise<OcrHttpResult> {
  return callOcrViaHttp('recognize', payload)
}

export async function recognizeImageCaptcha(payload: OcrRequestPayload): Promise<OcrHttpResult> {
  return callOcrViaHttp('recognize', payload)
}

export async function batchRecognizeTencentCaptcha(payload: OcrRequestPayload): Promise<OcrHttpResult> {
  return callOcrViaHttp('batch', payload, { timeoutMs: 180_000 })
}

export async function warmupOcrService(): Promise<void> {
  await warmupOcrViaHttp()
}

export async function closeOcrService(): Promise<void> {
  // HTTP 模式无持久连接，无需关闭。
}

// ── HTTP Call ───────────────────────────────────────────────────────────────

async function callOcrViaHttp(
  action: OcrAction,
  payload: OcrRequestPayload,
  { timeoutMs = DEFAULT_TIMEOUT_MS }: { timeoutMs?: number } = {},
): Promise<OcrHttpResult> {
  const baseUrl = String(runtimeConfig.ocr.baseUrl).trim().replace(/\/+$/, '')

  if (!baseUrl) {
    throw new Error('OCR_BASE_URL 未配置，无法调用 OCR 服务')
  }

  const url = `${baseUrl}/ocr/${action}`

  let response
  try {
    response = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload),
      signal: AbortSignal.timeout(timeoutMs),
    })
  } catch (err) {
    if (err instanceof Error && err.name === 'TimeoutError') {
      throw new Error(`OCR 请求超时（${timeoutMs}ms），请检查 OCR 服务状态`)
    }
    throw new Error(`OCR 服务不可用（${baseUrl}），请检查 OCR_BASE_URL 或外部 OCR 服务状态`)
  }

  if (!response.ok) {
    throw new Error(`OCR 服务返回错误：HTTP ${response.status}`)
  }

  const result = await response.json()
  if (!result || typeof result !== 'object' || Array.isArray(result)) {
    throw new Error('OCR 服务返回了无效响应')
  }
  const ocrResult = result as OcrHttpResult
  if (ocrResult.code !== 0) {
    throw new Error(`OCR 服务返回错误：${ocrResult.msg || '未知错误'}`)
  }

  return ocrResult
}

async function warmupOcrViaHttp(): Promise<void> {
  const baseUrl = String(runtimeConfig.ocr.baseUrl).trim().replace(/\/+$/, '')

  if (!baseUrl) {
    throw new Error('OCR_BASE_URL 未配置，无法启动 OCR 健康检查')
  }

  let response
  try {
    response = await fetch(`${baseUrl}/health`, {
      signal: AbortSignal.timeout(30_000),
    })
  } catch (err) {
    if (err instanceof Error && err.name === 'TimeoutError') {
      throw new Error(`OCR 服务健康检查超时，请检查 ${baseUrl} 是否可访问`)
    }
    throw new Error(`OCR 服务不可用（${baseUrl}），请检查 OCR_BASE_URL 或外部 OCR 服务状态`)
  }
  if (!response.ok) {
    throw new Error(`OCR 服务健康检查失败：HTTP ${response.status}`)
  }
}
