import {
  startRegistration,
  startAuthentication,
  browserSupportsWebAuthn,
  WebAuthnAbortService,
} from '@simplewebauthn/browser'

export interface RegisteredKey {
  credentialId: string
  nickname: string
  createdAt: number
  transports: string[]
  deviceType: string | null
}

export const useWebAuthn = () => {
  const isSupported = (): boolean => {
    if (typeof window === 'undefined') return false
    try {
      return browserSupportsWebAuthn()
    } catch {
      return false
    }
  }

  const register = async (nickname: string) => {
    // Clear any leftover ceremony so a previously-cancelled prompt does not
    // leave the abort controller in a state that suppresses the next call.
    try { WebAuthnAbortService.cancelCeremony() } catch {}
    const options = await $fetch('/api/idempiere-auth/webauthn/register-options', {
      method: 'POST',
      headers: useRequestHeaders(['cookie']),
    })
    const attestation = await startRegistration({ optionsJSON: options as any })
    return await $fetch('/api/idempiere-auth/webauthn/register-verify', {
      method: 'POST',
      headers: useRequestHeaders(['cookie']),
      body: { response: attestation, nickname },
    })
  }

  const loginWithKey = async (opts: { mobileWorker?: boolean } = {}) => {
    // After a user-cancelled passkey prompt, the lib's internal AbortController
    // can still hold the previous signal. Without resetting it, calling
    // startAuthentication again silently no-ops in some browsers and the user
    // has to reload the page. Explicitly cancel before each attempt.
    try { WebAuthnAbortService.cancelCeremony() } catch {}
    const options = await $fetch('/api/idempiere-auth/webauthn/login-options', {
      method: 'POST',
      headers: useRequestHeaders(['cookie']),
    })
    const assertion = await startAuthentication({ optionsJSON: options as any })
    const isPwa = typeof window !== 'undefined'
      && (window.matchMedia('(display-mode: standalone)').matches || !!(navigator as any)['standalone'])
    return await $fetch('/api/idempiere-auth/webauthn/login-verify', {
      method: 'POST',
      headers: useRequestHeaders(['cookie']),
      body: { response: assertion, pwa: isPwa, mobileWorker: !!opts.mobileWorker },
    })
  }

  const listKeys = async (): Promise<{ keys: RegisteredKey[]; hasPasswordStored: boolean }> => {
    return await $fetch('/api/idempiere-auth/webauthn/list', {
      headers: useRequestHeaders(['cookie']),
    })
  }

  const deleteKey = async (credentialId: string) => {
    return await $fetch('/api/idempiere-auth/webauthn/delete', {
      method: 'DELETE',
      headers: useRequestHeaders(['cookie']),
      body: { credentialId },
    })
  }

  return { isSupported, register, loginWithKey, listKeys, deleteKey }
}
