import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue' import type { FormInstance } from 'ant-design-vue' import { message } from 'ant-design-vue' import type SmsOtpField from '@/components/SmsOtpField.vue' import type { Login } from '@/models/login' import { authenticateWithFingerprint, getToken, loading, setToken, } from '@/utils' import useCountdownTimer from '@/utils/useCountdownTimer' import { loginCustomer, verifyToken } from '@/api/login' import { useUserStore } from '@/store/userStore' import { useWalletStore } from '@/store/walletStore' import { useSettingsStore } from '@/store/settingsStore' import { setTruth } from '@/app/authBoot' import { completeLoginNavigation } from '@/layouts/composables/useMobileScrollReset' import { normalizeAuthFormFields, persianToEnglishDigits } from '@/utils/persianDigits' import { beginSmsOtpCapture, clearPendingSmsOtp } from '@/utils/webOtp' import { usePwaInstall } from '@/composables/usePwaInstall' import { canRequestBrowserNotification, requestBrowserNotificationPermission, } from '@/utils/browserNotification' export function useLoginForm() { const { time, onFinish, reset } = useCountdownTimer('00:02:00', 'mm:ss') const enableSendAgainCode = ref(false) const stepTwoVerify = ref(false) const formRef = ref() const userStore = useUserStore() const walletStore = useWalletStore() const refOtpInput = ref | null>(null) const isSMS = ref(true) const isRegister = ref() const { tryInstallOrOpenGuide, completeGuide } = usePwaInstall() const userFormState = reactive({ provider: 'customer', }) onFinish(() => { enableSendAgainCode.value = true }) onBeforeUnmount(() => { // SmsOtpField cleans its own listener }) async function reSendCode() { userFormState.token = undefined clearPendingSmsOtp() refOtpInput.value?.clearInput?.() enableSendAgainCode.value = false normalizeAuthFormFields(userFormState) beginSmsOtpCapture() await loginCustomer(userFormState) refOtpInput.value?.startWebOtp?.() refOtpInput.value?.focusInput?.() reset() } function setIsSMS(val: boolean) { isSMS.value = val if (!val) stepTwoVerify.value = false userFormState.token = '' userFormState.password = '' } async function enterFingerPrint() { const fingerPrint = await authenticateWithFingerprint() if (fingerPrint) { setTruth() await completeLoginNavigation() } else { message.error('خطا در اعتبارسنجی') } } function handleOnChange(value: string) { userFormState.token = persianToEnglishDigits(String(value ?? '')) normalizeAuthFormFields(userFormState) } async function handleOnComplete(value: string) { userFormState.token = persianToEnglishDigits(String(value ?? '')) normalizeAuthFormFields(userFormState) phoneVerification() } async function login(accessToken: string | undefined) { setToken(accessToken) await userStore.getMyInfo() if (!userStore.userInfo) { message.error('ورود انجام شد ولی دریافت اطلاعات کاربر ممکن نشد. اتصال سرور را بررسی کنید.') return } await walletStore.getMyWallet() setTruth() await completeLoginNavigation() } function phoneVerification() { return formRef.value?.validateFields().then(async () => { try { loading.value = true normalizeAuthFormFields(userFormState) if (isSMS.value) { if (!stepTwoVerify.value) { userFormState.token = undefined userFormState.password = undefined userFormState.provider = 'customer' beginSmsOtpCapture() const { id } = await loginCustomer(userFormState) userFormState.id = id stepTwoVerify.value = true reset() } else { // نوتیف را در gesture شروع کن؛ await نکن تا ورود بلاک نشود if (canRequestBrowserNotification()) { void requestBrowserNotificationPermission() } const { access_token } = await verifyToken(userFormState) await login(access_token) } } else { userFormState.token = undefined if (canRequestBrowserNotification()) { void requestBrowserNotificationPermission() } const { access_token } = await loginCustomer(userFormState) await login(access_token) } } catch (e) { console.log(e) } finally { loading.value = false } }) } function editPhoneNumber() { stepTwoVerify.value = false } async function isOpenRegister() { const settingsStore = useSettingsStore() await settingsStore.fetchSettings() isRegister.value = settingsStore.settings.find( (s) => s?.key === 'open_register' && s?.is_active === true, ) } function installWebApp() { void tryInstallOrOpenGuide() } function proceedWithInstall() { void completeGuide() } const submitLabel = computed(() => { if (!isSMS.value) return 'ورود' return stepTwoVerify.value ? 'ورود' : 'ارسال کد' }) const showFingerprint = computed( () => Boolean(getToken() && userStore.userInfo?.finger_print), ) onMounted(async () => { await isOpenRegister() }) return { time, enableSendAgainCode, stepTwoVerify, formRef, refOtpInput, isSMS, isRegister, userFormState, loading, submitLabel, showFingerprint, setIsSMS, reSendCode, enterFingerPrint, handleOnChange, handleOnComplete, phoneVerification, editPhoneNumber, installWebApp, proceedWithInstall, } }