"use client"

import { useEffect, useRef, useState } from "react"
import { useRouter } from "next/navigation"
import { Loader2Icon } from "lucide-react"

import { Button } from "@/src/components/ui/button"
import {
  InputOTP,
  InputOTPGroup,
  InputOTPSlot,
} from "@/src/components/ui/input-otp"
import { useVerifyEmailOtpMutation } from "@/src/state/auth"

const RESEND_COUNTDOWN = 20

interface OTPFormProps {
  email: string
  onResend: () => Promise<void>
}

export default function OTPForm({ email, onResend }: OTPFormProps) {
  const router = useRouter()
  const [verifyEmailOtp] = useVerifyEmailOtpMutation()

  const [otp, setOtp] = useState("")
  const [isVerifying, setIsVerifying] = useState(false)
  const [isResending, setIsResending] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [countdown, setCountdown] = useState(RESEND_COUNTDOWN)
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)

  useEffect(() => {
    startCountdown()
    return () => clearInterval(intervalRef.current ?? undefined)
  }, [])

  function startCountdown() {
    if (intervalRef.current) clearInterval(intervalRef.current)
    setCountdown(RESEND_COUNTDOWN)
    intervalRef.current = setInterval(() => {
      setCountdown((prev) => {
        if (prev <= 1) {
          clearInterval(intervalRef.current!)
          return 0
        }
        return prev - 1
      })
    }, 1000)
  }

  async function handleVerify() {
    if (otp.length !== 6) return
    setIsVerifying(true)
    setError(null)
    try {
      await verifyEmailOtp({ email, otpCode: otp }).unwrap()
      router.push("/")
    } catch (err: unknown) {
      const message =
        (err as { data?: { message?: string } })?.data?.message ?? "Code invalide. Veuillez réessayer."
      setError(message)
    } finally {
      setIsVerifying(false)
    }
  }

  async function handleResend() {
    setIsResending(true)
    setError(null)
    try {
      await onResend()
      startCountdown()
    } catch {
      setError("Impossible de renvoyer le code. Veuillez réessayer.")
    } finally {
      setIsResending(false)
    }
  }

  const canResend = countdown === 0 && !isResending

  return (
    <div className="flex flex-col items-center gap-6">
      <p className="text-sm text-muted-foreground text-center">
        Code envoyé à <span className="font-medium text-foreground">{email}</span>
      </p>

      <InputOTP maxLength={6} value={otp} onChange={setOtp} disabled={isVerifying}>
        <InputOTPGroup>
          <InputOTPSlot index={0} />
          <InputOTPSlot index={1} />
          <InputOTPSlot index={2} />
          <InputOTPSlot index={3} />
          <InputOTPSlot index={4} />
          <InputOTPSlot index={5} />
        </InputOTPGroup>
      </InputOTP>

      {error && <p className="text-destructive text-xs text-center">{error}</p>}

      <Button
        className="w-full"
        size="lg"
        disabled={otp.length !== 6 || isVerifying}
        onClick={handleVerify}
      >
        {isVerifying && <Loader2Icon className="animate-spin" />}
        Vérifier
      </Button>

      <p className="text-sm text-muted-foreground text-center">
        Vous n&apos;avez pas reçu de code ?{" "}
        {canResend ? (
          <button
            type="button"
            onClick={handleResend}
            className="font-medium text-primary hover:underline"
          >
            {isResending ? "Envoi…" : "Renvoyer"}
          </button>
        ) : (
          <span className="text-muted-foreground">
            Renvoyer dans <span className="font-medium tabular-nums">{countdown}s</span>
          </span>
        )}
      </p>
    </div>
  )
}
