import { startRegistration } from '@simplewebauthn/browser'
import { PublicKeyCredentialCreationOptionsJSON } from '@simplewebauthn/types'
import { Button } from 'univoq'
import type {
	WebAuthnRegisterFinishPayload,
	WebAuthnRegisterStartPayload,
} from '../routes/api/webauthn/register/[step].ts'
import { requestApi } from '../src/utils.ts'

function isWebAuthnSupported(): boolean {
	return 'credentials' in navigator
}

function RegisterButton({ disabled }: { disabled?: boolean }) {
	return (
		<Button
			label='Enregistrer une PassKey'
			variant='primary'
			onClick={register}
			disabled={disabled}
		>
			Enregistrer une PassKey
		</Button>
	)
}

export default function PassKeyRegister() {
	if (!isWebAuthnSupported()) {
		return (
			<label>
				<span>Erreur: WebAuthn n'est pas supporté par votre navigateur</span>
				<RegisterButton disabled />
			</label>
		)
	}

	return (
		<label>
			<span>Enregistrer une PassKey pour cet appareil</span>
			<RegisterButton />
		</label>
	)
}

async function register() {
	try {
		await webAuthnRegister()
	} catch (cause) {
		console.error(
			new Error('passkey register failed', {
				cause,
			}),
		)
	}
}

async function webAuthnRegister() {
	if (localStorage.getItem('webauthn-registered')) {
		return
	}

	const registrationOptions = await requestApi<
		WebAuthnRegisterStartPayload,
		PublicKeyCredentialCreationOptionsJSON
	>('webauthn/register/start', 'POST')

	// Pass the options to the authenticator and wait for a response
	const registration = await startRegistration(registrationOptions)
		.catch((error) => {
			// Some basic error handling
			if (error.name === 'InvalidStateError') {
				console.error(
					'Authenticator was probably already registered by user',
				)
				return null
			} else {
				throw error
			}
		})

	if (registration === null) return

	// Verify the registration
	try {
		await requestApi<
			WebAuthnRegisterFinishPayload,
			{ verified: boolean }
		>('webauthn/register/finish', 'POST', registration)
		console.log('Success!')
		localStorage.setItem('webauthn-registered', 'true')
	} catch (error) {
		console.error('Oh no, something went wrong! Response:', error)
	}
}
