import { ComponentType, FC, useCallback, useEffect, useMemo, useRef, useState } from "react" // eslint-disable-next-line no-restricted-imports import { TextInput, TextStyle, View, ViewStyle } from "react-native" import { useFocusEffect } from "@react-navigation/native" import { Button } from "@/components/Button" import { PressableIcon } from "@/components/Icon" import { Screen } from "@/components/Screen" import { Text } from "@/components/Text" import { TextField, type TextFieldAccessoryProps } from "@/components/TextField" import { useAuth } from "@/context/AuthContext" import type { AppStackScreenProps } from "@/navigators/navigationTypes" import { useAppTheme } from "@/theme/context" import type { ThemedStyle } from "@/theme/types" import { s } from "@/utils/responsive" interface ForgotPasswordScreenProps extends AppStackScreenProps<"ForgotPassword"> {} export const ForgotPasswordScreen: FC = ({ navigation }) => { const emailInput = useRef(null) const verificationCodeInput = useRef(null) const newPasswordInput = useRef(null) const [email, setEmail] = useState("") const [verificationCode, setVerificationCode] = useState("") const [newPassword, setNewPassword] = useState("") const [isPasswordHidden, setIsPasswordHidden] = useState(true) const [resendCountdown, setResendCountdown] = useState(0) const { forgotPasswordStep, pendingEmail, isLoading, error, forgotPassword, resendForgotPasswordCode, resetPassword, resetForgotPasswordStep, clearError, } = useAuth() const { themed, theme: { colors }, } = useAppTheme() // Email validation const emailError = useMemo(() => { if (!email || email.length === 0) return "" if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) return "Please enter a valid email" return "" }, [email]) // New password validation - requires uppercase, lowercase, number, and special character const newPasswordError = useMemo(() => { if (!newPassword || newPassword.length === 0) return "" if (newPassword.length < 8) return "Password must be at least 8 characters" if (!/[A-Z]/.test(newPassword)) return "Password must contain an uppercase letter" if (!/[a-z]/.test(newPassword)) return "Password must contain a lowercase letter" if (!/[0-9]/.test(newPassword)) return "Password must contain a number" if (!/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(newPassword)) return "Password must contain a special character" return "" }, [newPassword]) // Countdown timer for resend button useEffect(() => { if (resendCountdown > 0) { const timer = setTimeout(() => setResendCountdown(resendCountdown - 1), 1000) return () => clearTimeout(timer) } return undefined }, [resendCountdown]) // Clear error when screen comes into focus useFocusEffect( useCallback(() => { clearError() }, [clearError]), ) // Clear error when inputs change (not when error changes) const prevInputsRef = useRef({ email, verificationCode, newPassword }) useEffect(() => { const prev = prevInputsRef.current // Only clear error if one of the input fields actually changed if ( prev.email !== email || prev.verificationCode !== verificationCode || prev.newPassword !== newPassword ) { if (error) clearError() prevInputsRef.current = { email, verificationCode, newPassword } } }, [email, verificationCode, newPassword, error, clearError]) // Handle forgot password (step 1) const handleForgotPassword = useCallback(async () => { if (!email || emailError) return const success = await forgotPassword(email) if (success) { setResendCountdown(60) } }, [email, emailError, forgotPassword]) // Handle reset password (step 2) const handleResetPassword = useCallback(async () => { if (!verificationCode || verificationCode.length !== 6 || !newPassword || newPasswordError) return const success = await resetPassword(verificationCode, newPassword) if (success) { // Reset state and navigate back to login resetForgotPasswordStep() navigation.navigate("Login") } }, [ verificationCode, newPassword, newPasswordError, resetPassword, resetForgotPasswordStep, navigation, ]) // Handle resend code const handleResendCode = useCallback(async () => { if (resendCountdown > 0) return const success = await resendForgotPasswordCode() if (success) { setResendCountdown(60) } }, [resendCountdown, resendForgotPasswordCode]) // Handle back to email step const handleBackToEmail = useCallback(() => { resetForgotPasswordStep() setVerificationCode("") setNewPassword("") }, [resetForgotPasswordStep]) // Navigate to login const handleGoToLogin = useCallback(() => { resetForgotPasswordStep() navigation.navigate("Login") }, [navigation, resetForgotPasswordStep]) // Password visibility toggle const PasswordRightAccessory: ComponentType = useMemo( () => function PasswordRightAccessory(props: TextFieldAccessoryProps) { return ( setIsPasswordHidden(!isPasswordHidden)} /> ) }, [isPasswordHidden, colors.palette.neutral800], ) // Render email step (step 1) const renderEmailStep = () => ( <> {error ? : null}