﻿"use client";

import { useState, useEffect } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import {
  otpConfirmationSchema,
  type OtpConfirmationInput,
} from "@/lib/validations/auth";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { useToastEnhanced } from "@/hooks/use-toast-enhanced";
import { Loader2, Shield, Eye, EyeOff, Copy, Check } from "lucide-react";
import { useRouter } from "next/navigation";
import { clientRateLimit } from "@/core/security/rate-limit";
import {
  verifyOTPAction,
  resendOTPAction,
  getStoredOTPAction,
} from "@/features/auth/actions/auth-actions";

interface OTPVerificationFormProps {
  email: string;
}

export function OTPVerificationForm({ email }: OTPVerificationFormProps) {
  const [isLoading, setIsLoading] = useState(false);
  const [resending, setResending] = useState(false);
  const [showOTP, setShowOTP] = useState(false);
  const [storedOTP, setStoredOTP] = useState<string | null>(null);
  const [copied, setCopied] = useState(false);
  const toast = useToastEnhanced();
  const router = useRouter();

  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<OtpConfirmationInput>({
    resolver: zodResolver(otpConfirmationSchema),
  });

  useEffect(() => {
    async function fetchOTP() {
      try {
        const result = await getStoredOTPAction(email);
        if (result.success && result.otp) {
          setStoredOTP(result.otp);
        }
      } catch {
        // OTP fetch failed silently - user can still enter manually
      }
    }
    fetchOTP();
  }, [email]);

  const copyOTP = async () => {
    if (storedOTP) {
      await navigator.clipboard.writeText(storedOTP);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
      toast.success({
        title: "OTP Copied",
        description: "OTP has been copied to clipboard",
      });
    }
  };

  const onSubmit = async (data: OtpConfirmationInput) => {
    const rateCheck = clientRateLimit("otp_verify", 5, 300000); // 5 attempts per 5 minutes
    if (!rateCheck.allowed) {
      const waitTime = Math.ceil(rateCheck.resetIn / 60000);
      toast.error({
        title: "Too many attempts",
        description: `Please wait ${waitTime} minute(s) before trying again`,
      });
      return;
    }

    setIsLoading(true);

    try {
      const result = await verifyOTPAction(email, data.otp);

      if (!result.success) {
        throw new Error(result.error || "Invalid or expired OTP code");
      }

      toast.success({
        title: "OTP verified successfully",
        description: "You can now reset your password",
      });

      // Redirect to reset password page
      router.push("/reset-password");
    } catch (error) {
      toast.error({
        title: "Verification failed",
        description:
          error instanceof Error ? error.message : "Invalid OTP code",
      });
    } finally {
      setIsLoading(false);
    }
  };

  const handleResendOTP = async () => {
    const rateCheck = clientRateLimit("otp_resend", 3, 300000); // 3 resends per 5 minutes
    if (!rateCheck.allowed) {
      const waitTime = Math.ceil(rateCheck.resetIn / 60000);
      toast.error({
        title: "Too many resend attempts",
        description: `Please wait ${waitTime} minute(s) before requesting again`,
      });
      return;
    }

    setResending(true);
    try {
      const result = await resendOTPAction(email);

      if (!result.success) {
        throw new Error(result.error || "Failed to resend OTP");
      }

      const otpResult = await getStoredOTPAction(email);
      if (otpResult.success && otpResult.otp) {
        setStoredOTP(otpResult.otp);
      }

      toast.success({
        title: "OTP resent",
        description: "Please check your email for the new verification code",
        duration: 5000,
      });
    } catch {
      toast.error({
        title: "Failed to resend",
        description: "Please try again",
      });
    } finally {
      setResending(false);
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-5">
      {storedOTP && (
        <div className="p-4 rounded-lg bg-primary/10 border border-primary/20 space-y-2">
          <div className="flex items-center justify-between">
            <p className="text-sm font-medium text-primary">
              Your OTP Code (for testing):
            </p>
            <div className="flex items-center gap-2">
              <Button
                type="button"
                variant="ghost"
                size="sm"
                onClick={() => setShowOTP(!showOTP)}
                className="h-8 px-2 text-primary hover:text-primary/80"
              >
                {showOTP ? (
                  <EyeOff className="h-4 w-4" />
                ) : (
                  <Eye className="h-4 w-4" />
                )}
              </Button>
              <Button
                type="button"
                variant="ghost"
                size="sm"
                onClick={copyOTP}
                className="h-8 px-2 text-primary hover:text-primary/80"
              >
                {copied ? (
                  <Check className="h-4 w-4" />
                ) : (
                  <Copy className="h-4 w-4" />
                )}
              </Button>
            </div>
          </div>
          <p className="text-2xl font-mono font-bold tracking-widest text-center text-primary">
            {showOTP ? storedOTP : "******"}
          </p>
        </div>
      )}

      <div className="space-y-2">
        <Label htmlFor="otp">Verification Code</Label>
        <div className="relative">
          <Shield
            className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"
            aria-hidden="true"
          />
          <Input
            id="otp"
            type="text"
            placeholder="000000"
            maxLength={6}
            autoComplete="one-time-code"
            disabled={isLoading}
            className="pl-10 text-center tracking-widest text-lg font-mono"
            aria-invalid={errors.otp ? "true" : "false"}
            aria-describedby={errors.otp ? "otp-error" : undefined}
            {...register("otp")}
          />
        </div>
        {errors.otp && (
          <p id="otp-error" className="text-sm text-destructive" role="alert">
            {errors.otp.message}
          </p>
        )}
      </div>

      <Button
        type="submit"
        className="w-full frontend-btn"
        size="lg"
        disabled={isLoading}
        aria-label="Verify OTP code"
      >
        {isLoading && (
          <Loader2 className="mr-2 h-4 w-4 animate-spin" aria-hidden="true" />
        )}
        {isLoading ? "Verifying..." : "Verify Code"}
      </Button>

      <div className="text-center pt-2">
        <Button
          type="button"
          variant="link"
          size="sm"
          onClick={handleResendOTP}
          disabled={resending || isLoading}
          className="text-sm text-muted-foreground hover:text-primary"
        >
          {resending ? "Resending..." : "Didn't receive the code? Resend"}
        </Button>
      </div>
    </form>
  );
}
