"use client"

import { useCallback, useEffect, useMemo, useState } from "react"
import { Loader2 } from "lucide-react"
import { AuthCard } from "@/components/auth/auth-card"
import { AuthConnectButton } from "@/components/auth/auth-connect-button"
import { FlowChallengeForm } from "@/components/auth/flow-challenge-form"
import {
  AUTH_FLOW_SLUGS,
  flowComponent,
  flowRedirectUrl,
  flowTitle,
  flowValidationErrors,
  isRecoveryEmailSent,
  respondAuthFlow,
  startAuthFlow,
  type AuthFlowSlug,
  type FlowChallenge,
} from "@/lib/auth/flow-api"

type AuthFlowPageProps = {
  slug: AuthFlowSlug
  defaultTitle: string
  defaultDescription: string
  successTitle: string
  successDescription: string
  successActionLabel: string
  successHref: string
  /** Full document navigation required (OIDC login routes). */
  successExternal?: boolean
  footer: React.ReactNode
  onSuccess?: () => void
}

export function AuthFlowPage({
  slug,
  defaultTitle,
  defaultDescription,
  successTitle,
  successDescription,
  successActionLabel,
  successHref,
  successExternal = false,
  footer,
  onSuccess,
}: AuthFlowPageProps) {
  const [sessionId, setSessionId] = useState<string | null>(null)
  const [challenge, setChallenge] = useState<FlowChallenge | null>(null)
  const [loading, setLoading] = useState(true)
  const [submitting, setSubmitting] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [done, setDone] = useState(false)
  const [denied, setDenied] = useState(false)

  const bootstrap = useCallback(async () => {
    setLoading(true)
    setError(null)
    try {
      const step = await startAuthFlow(slug)
      setSessionId(step.sessionId)
      setChallenge(step.challenge)
      setDone(step.done)
      setDenied(step.denied)
      if (step.done && !step.denied) {
        onSuccess?.()
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : "Impossible de démarrer le parcours")
    } finally {
      setLoading(false)
    }
  }, [onSuccess, slug])

  useEffect(() => {
    void bootstrap()
  }, [bootstrap])

  const validationErrors = useMemo(() => flowValidationErrors(challenge), [challenge])
  const formError = error ?? validationErrors._form ?? null

  const title = useMemo(() => {
    if ((done && !denied) || isRecoveryEmailSent(slug, challenge)) return successTitle
    if (denied) return "Accès refusé"
    return flowTitle(challenge) || defaultTitle
  }, [challenge, defaultTitle, denied, done, slug, successTitle])

  const description = useMemo(() => {
    if ((done && !denied) || isRecoveryEmailSent(slug, challenge)) return successDescription
    if (denied) {
      return "Ce parcours a été refusé. Vérifiez vos informations ou contactez le support."
    }
    return defaultDescription
  }, [challenge, defaultDescription, denied, done, slug, successDescription])

  async function handleSubmit(payload: Record<string, unknown>) {
    if (!sessionId) return
    setSubmitting(true)
    setError(null)
    try {
      const step = await respondAuthFlow(slug, payload)
      setSessionId(step.sessionId)
      setChallenge(step.challenge)
      setDone(step.done)
      setDenied(step.denied)
      if (step.done && !step.denied) {
        onSuccess?.()
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : "Échec de l'étape")
    } finally {
      setSubmitting(false)
    }
  }

  const component = flowComponent(challenge)
  const redirectUrl = flowRedirectUrl(challenge)
  const recoveryEmailSent = isRecoveryEmailSent(slug, challenge)
  const showSuccess = (done && !denied) || recoveryEmailSent

  return (
    <AuthCard title={title} description={description} error={formError} footer={footer}>
      {loading ? (
        <div className="flex justify-center py-8">
          <Loader2 className="size-6 animate-spin text-muted-foreground" aria-hidden />
          <span className="sr-only">Chargement…</span>
        </div>
      ) : showSuccess ? (
        <div className="flex flex-col items-center gap-4">
          {redirectUrl ? (
            <p className="text-center text-sm text-muted-foreground">
              Redirection en cours…
            </p>
          ) : null}
          {successExternal ? (
            <AuthConnectButton href={successHref}>
              {successActionLabel}
            </AuthConnectButton>
          ) : (
            <AuthConnectButton as="link" href={successHref}>
              {successActionLabel}
            </AuthConnectButton>
          )}
        </div>
      ) : (
        <FlowChallengeForm
          challenge={challenge}
          component={component}
          submitting={submitting}
          fieldErrors={validationErrors}
          onSubmit={handleSubmit}
        />
      )}
    </AuthCard>
  )
}

export { AUTH_FLOW_SLUGS }
