import { useState } from 'react'; import { WalletType } from 'rnwalletman'; export interface OTPBindCallbacks { onRequestOTP: (walletType: WalletType, params: any) => Promise; onVerifyOTP: (walletType: WalletType, params: any) => Promise; onSuccess: (result: any) => void; onError: (error: string) => void; isDebug?: boolean; } export interface OTPBindState { mobile: string; otp: string; step: 'mobile' | 'otp' | 'processing'; loading: boolean; otpData: any; errorMessage: string; } export interface OTPBindActions { setMobile: (mobile: string) => void; setOtp: (otp: string) => void; requestOTP: () => Promise; verifyOTP: () => Promise; resetToMobile: () => void; clearError: () => void; } export function useOTPBind( walletType: WalletType, callbacks: OTPBindCallbacks, config?: { otpLength?: number; mobileLength?: number; additionalParams?: any; } ): [OTPBindState, OTPBindActions] { const [mobile, setMobile] = useState(''); const [otp, setOtp] = useState(''); const [step, setStep] = useState<'mobile' | 'otp' | 'processing'>('mobile'); const [loading, setLoading] = useState(false); const [otpData, setOtpData] = useState(null); const [errorMessage, setErrorMessage] = useState(''); const { onRequestOTP, onVerifyOTP, onSuccess, onError, isDebug = false } = callbacks; const { otpLength = 6, mobileLength = 10, additionalParams = {} } = config || {}; const clearError = () => setErrorMessage(''); const log = (...args: any[]) => { if (isDebug) console.log(`[${walletType}]`, ...args); }; const error = (...args: any[]) => { if (isDebug) console.error(`[${walletType}]`, ...args); }; const requestOTP = async () => { if (!mobile || mobile.length !== mobileLength) { const msg = 'Invalid mobile number'; setErrorMessage(msg); onError(msg); return; } setLoading(true); setErrorMessage(''); log('Requesting OTP for:', mobile); try { const response = await onRequestOTP(walletType, { mobile, ...additionalParams, }); log('OTP response:', response); if (response.success) { setOtpData(response.data); setStep('otp'); setErrorMessage(''); } else { error('OTP request failed:', response.message); const msg = response.message || 'Failed to request OTP'; setErrorMessage(msg); onError(msg); } } catch (e) { error('Request OTP error:', e); const msg = e instanceof Error ? e.message : 'Failed to request OTP'; setErrorMessage(msg); onError(msg); } finally { setLoading(false); } }; const verifyOTP = async () => { if (!otp || otp.length !== otpLength) { const msg = `请输入 ${otpLength} 位验证码`; setErrorMessage(msg); onError(msg); return; } setLoading(true); setErrorMessage(''); setStep('processing'); log('Verifying OTP:', otp); try { const response = await onVerifyOTP(walletType, { mobile, otp, ...additionalParams, ...(otpData || {}), }); log('Verify response:', response); if (response.success) { setErrorMessage(''); onSuccess(response.data); } else { error('Verify failed:', response.message); const msg = response.message || 'Failed to verify OTP'; setStep('otp'); setErrorMessage(msg); onError(msg); } } catch (e) { error('Verify OTP error:', e); const msg = e instanceof Error ? e.message : 'Failed to verify OTP'; setStep('otp'); setErrorMessage(msg); onError(msg); } finally { setLoading(false); } }; const resetToMobile = () => { setStep('mobile'); setOtp(''); setErrorMessage(''); }; return [ { mobile, otp, step, loading, otpData, errorMessage }, { setMobile, setOtp, requestOTP, verifyOTP, resetToMobile, clearError }, ]; }