import { Button, YStack, Text, Paragraph } from '@junwon/aesthetics' import { type Route, useRouterContext } from '../providers/RouterProvider' import { useVisa, type Response } from '../providers/VisaProvider' import { useState, useEffect } from 'react' import { Keyboard } from 'react-native' import { CodeInput } from './CodeInput' const CODE_LENGTH = 6 const RESEND_COOLDOWN = 30 interface VerifyOtpProps { type: 'email' | 'email_change' redirectTo: string onResend: () => Promise } export function VerifyOtp({ type, redirectTo, onResend }: VerifyOtpProps) { const { setRoute } = useRouterContext() const [error, setError] = useState('') const [isSending, setIsSending] = useState(false) const [resendCooldown, setResendCooldown] = useState(30) const [inputValues, setInputValues] = useState(Array(CODE_LENGTH).fill('')) const { verifyOtp, loading, emailToVerify } = useVisa() useEffect(() => { if (!emailToVerify) { setRoute('/') } }, [emailToVerify, type, setRoute]) useEffect(() => { if (inputValues.join('').length === CODE_LENGTH) { handleSubmit() } }, [inputValues]) useEffect(() => { if (resendCooldown > 0) { const timer = setTimeout(() => { setResendCooldown(resendCooldown - 1) }, 1000) return () => clearTimeout(timer) } }, [resendCooldown]) const resetCode = () => { setInputValues(Array(CODE_LENGTH).fill('')) Keyboard.dismiss() } const handleResend = async () => { if (resendCooldown > 0 || loading || !emailToVerify) return setError('') setIsSending(true) try { const result = await onResend() if (result.success) { setResendCooldown(RESEND_COOLDOWN) } else { throw result.error || new Error('Failed to resend code') } } catch (err) { console.log('Resend error:', err) setError('Failed to resend code') } setIsSending(false) } const handleChange = (newValues: string[]) => { if (error && newValues.some((val) => val !== '')) { setError('') } setInputValues(newValues) } const handleSubmit = async () => { const code = inputValues.join('') if (loading || code.length !== CODE_LENGTH) return try { const result = await verifyOtp(code, type, redirectTo) if (result.success) { setRoute(redirectTo as Route) } else { switch (result.error?.message) { case 'Token has expired or is invalid': setError('Code is wrong or has expired.') resetCode() break default: setError('Verification failed. Please try again.') resetCode() } } } catch (err) { console.error('Verification error:', err) setError('Verification failed. Please try again.') resetCode() } } if (!emailToVerify) return null return ( {loading ? 'Verifying...' : error} {emailToVerify} ) }