/**
 * 极验 v4 二次校验封装。bind 模式（用 showCaptcha 主动触发），按需创建实例。
 * 未配置 captchaId 时直通（开发友好）。
 */

export interface CaptchaResult {
  lot_number: string
  captcha_output: string
  pass_token: string
  gen_time: string
}

interface GeetestInstance {
  appendTo(target: string | HTMLElement): GeetestInstance
  getValidate(): CaptchaResult | false
  reset(): void
  destroy(): void
  showCaptcha(): void
  onReady(cb: () => void): GeetestInstance
  onSuccess(cb: () => void): GeetestInstance
  onError(cb: (err: { code: string; msg: string }) => void): GeetestInstance
  onClose(cb: () => void): GeetestInstance
  onFail(cb: (obj: unknown) => void): GeetestInstance
}

type InitGeetest4 = (
  config: { captchaId: string; product?: "bind" | "popup" | "float"; language?: string },
  callback: (instance: GeetestInstance) => void,
) => void

declare global {
  interface Window {
    initGeetest4?: InitGeetest4
  }
}

const CAPTCHA_ID = import.meta.env.VITE_GEETEST_CAPTCHA_ID as string | undefined
const GT4_SRC = "https://static.geetest.com/v4/gt4.js"

let scriptPromise: Promise<void> | null = null

function loadScript(): Promise<void> {
  if (typeof window === "undefined") return Promise.reject(new Error("no window"))
  if (window.initGeetest4) return Promise.resolve()
  if (scriptPromise) return scriptPromise
  scriptPromise = new Promise<void>((resolve, reject) => {
    const s = document.createElement("script")
    s.src = GT4_SRC
    s.async = true
    s.onload = () => resolve()
    s.onerror = () => {
      scriptPromise = null
      reject(new Error("加载极验脚本失败"))
    }
    document.head.appendChild(s)
  })
  return scriptPromise
}

export function isCaptchaEnabled(): boolean {
  return !!CAPTCHA_ID
}

/**
 * 弹出极验校验并等待用户完成。返回校验结果；未配置 captchaId 时返回 null（后端会跳过校验）。
 * 用户关闭弹窗 / 网络错误时会 reject。
 */
export async function verifyCaptcha(): Promise<CaptchaResult | null> {
  if (!CAPTCHA_ID) return null

  await loadScript()
  if (!window.initGeetest4) throw new Error("极验未就绪")

  return new Promise<CaptchaResult>((resolve, reject) => {
    let instance: GeetestInstance | null = null
    let settled = false

    const cleanup = () => {
      try { instance?.destroy() } catch { /* ignore */ }
      instance = null
    }

    window.initGeetest4!(
      { captchaId: CAPTCHA_ID, product: "bind", language: "zho" },
      (cap) => {
        instance = cap
        cap.onReady(() => {
          try { cap.showCaptcha() } catch (e) { reject(e); cleanup() }
        })
        cap.onSuccess(() => {
          if (settled) return
          const r = cap.getValidate()
          if (!r) {
            reject(new Error("验证结果无效"))
          } else {
            settled = true
            resolve(r)
          }
          cleanup()
        })
        cap.onError((err) => {
          if (settled) return
          settled = true
          reject(new Error(err?.msg || "人机验证出错"))
          cleanup()
        })
        cap.onClose(() => {
          if (settled) return
          settled = true
          reject(new Error("已取消人机验证"))
          cleanup()
        })
      },
    )
  })
}
