import { Capacitor } from '@capacitor/core'

// Biometric login for the bundled native app (Phase 1). Stores a durable, REVOCABLE snapshot of the
// session (refresh token + context — never the password) in the Android Keystore, released only on a
// successful biometric match (getSecureCredentials). On unlock we mint a fresh access token via the
// existing /api/app-auth/token-refresh, so no new server route is needed.
//
// Everything is native-only: the plugins are dynamically imported behind isNativePlatform(), so the
// web build never loads @capgo/capacitor-native-biometric or @capacitor/preferences from here.

const SERVER = 'app.logship.de'       // namespace key for the stored credential
const FLAG = 'logship_biometric_enabled'

const native = () => Capacitor.isNativePlatform()

const loadPlugins = async () => {
  const [bio, prefs] = await Promise.all([
    import('@capgo/capacitor-native-biometric'),
    import('@capacitor/preferences'),
  ])
  return { NativeBiometric: bio.NativeBiometric, AccessControl: bio.AccessControl, Preferences: prefs.Preferences }
}

export const useBiometricAuth = () => {
  // { available, type } — type is the BiometryType enum (3=fingerprint, 2/4=face, …).
  const isAvailable = async (): Promise<{ available: boolean, type: number }> => {
    if (!native()) return { available: false, type: 0 }
    try {
      const { NativeBiometric } = await loadPlugins()
      const r: any = await NativeBiometric.isAvailable({ useFallback: false })
      return { available: !!r?.isAvailable, type: Number(r?.biometryType ?? 0) }
    } catch { return { available: false, type: 0 } }
  }

  const isEnabled = async (): Promise<boolean> => {
    if (!native()) return false
    try {
      const { Preferences } = await loadPlugins()
      const { value } = await Preferences.get({ key: FLAG })
      return value === 'true'
    } catch { return false }
  }

  // Store the snapshot biometric-bound. BIOMETRY_ANY keeps it usable when the user adds a new
  // fingerprint (convenience); switch to BIOMETRY_CURRENT_SET for stricter security (invalidates on
  // biometric enrollment changes). The stored secret is a revocable refresh token, not a password.
  const enable = async (snapshot: any, username?: string): Promise<boolean> => {
    if (!native()) return false
    try {
      const { NativeBiometric, AccessControl, Preferences } = await loadPlugins()
      await NativeBiometric.deleteCredentials({ server: SERVER }).catch(() => {})
      await NativeBiometric.setCredentials({
        username: String(username || 'logship'),
        password: JSON.stringify(snapshot),
        server: SERVER,
        accessControl: AccessControl.BIOMETRY_ANY,
      })
      await Preferences.set({ key: FLAG, value: 'true' })
      return true
    } catch (e) {
      console.warn('[biometric] enable failed', e)
      return false
    }
  }

  // Prompts biometric and returns the stored snapshot, or null on cancel/lockout/biometrics-changed.
  const unlock = async (): Promise<any | null> => {
    if (!native()) return null
    try {
      const { NativeBiometric } = await loadPlugins()
      const cred: any = await NativeBiometric.getSecureCredentials({
        server: SERVER,
        title: 'LogShip',
        subtitle: 'Mit Biometrie anmelden',
        reason: 'Anmeldung bestätigen',
        negativeButtonText: 'Abbrechen',
      })
      return cred?.password ? JSON.parse(cred.password) : null
    } catch (e) {
      console.warn('[biometric] unlock cancelled/failed', e)
      return null
    }
  }

  const disable = async (): Promise<void> => {
    if (!native()) return
    try {
      const { NativeBiometric, Preferences } = await loadPlugins()
      await NativeBiometric.deleteCredentials({ server: SERVER }).catch(() => {})
      await Preferences.remove({ key: FLAG })
    } catch { /* non-fatal */ }
  }

  return { isAvailable, isEnabled, enable, unlock, disable }
}
