/**
 * LoginOtpStep - OTP verification step for login flow
 *
 * Displays OTP input form after credentials are validated.
 * Handles verification, error display, and expiry countdown.
 */

"use client";

import { useState, useCallback, useEffect } from "react";
import { Button, ErrorMessage } from "@/components/atoms";
import { OtpInput } from "@/components/molecules";
import { ArrowLeft, Mail, Clock } from "lucide-react";

interface LoginOtpStepProps {
  sessionToken: string;
  maskedEmail: string;
  expiresAt: string;
  onVerify: (code: string, rememberDevice: boolean) => Promise<void>;
  onBack: () => void;
  loading?: boolean;
  error?: string | null;
}

/**
 * Format remaining time as MM:SS
 */
function formatTimeRemaining(seconds: number): string {
  const mins = Math.floor(seconds / 60);
  const secs = seconds % 60;
  return `${mins}:${secs.toString().padStart(2, "0")}`;
}

export function LoginOtpStep({
  sessionToken: _sessionToken,
  maskedEmail,
  expiresAt,
  onVerify,
  onBack,
  loading = false,
  error,
}: LoginOtpStepProps) {
  const [code, setCode] = useState("");
  const [isVerifying, setIsVerifying] = useState(false);
  const [timeRemaining, setTimeRemaining] = useState<number | null>(null);
  const [rememberDevice, setRememberDevice] = useState(false);

  // Calculate initial time remaining with validation
  useEffect(() => {
    const expiryTime = new Date(expiresAt).getTime();

    // Validate the parsed date
    if (Number.isNaN(expiryTime)) {
      // Invalid date format - treat as expired
      setTimeRemaining(0);
      return;
    }

    // Sanity check: expiry should be within 24 hours from now
    const now = Date.now();
    const maxValidExpiry = now + 24 * 60 * 60 * 1000; // 24 hours
    const clockSkewTolerance = 5 * 1000; // 5 seconds for network latency/clock skew
    if (expiryTime > maxValidExpiry || expiryTime < now - clockSkewTolerance) {
      // Expiry is too far in the future or in the past - something is wrong
      setTimeRemaining(0);
      return;
    }

    const updateTimeRemaining = () => {
      const current = Date.now();
      const remaining = Math.max(0, Math.floor((expiryTime - current) / 1000));
      setTimeRemaining(remaining);
    };

    updateTimeRemaining();
    const interval = setInterval(updateTimeRemaining, 1000);

    return () => clearInterval(interval);
  }, [expiresAt]);

  const handleVerify = useCallback(async () => {
    if (code.length !== 6 || isVerifying || loading) return;

    setIsVerifying(true);
    try {
      await onVerify(code, rememberDevice);
    } finally {
      setIsVerifying(false);
    }
  }, [code, isVerifying, loading, onVerify, rememberDevice]);

  const handleComplete = useCallback(
    (completedCode: string) => {
      setCode(completedCode);
      // Auto-submit when code is complete
      if (completedCode.length === 6 && !isVerifying && !loading) {
        void (async () => {
          setIsVerifying(true);
          try {
            await onVerify(completedCode, rememberDevice);
          } finally {
            setIsVerifying(false);
          }
        })();
      }
    },
    [isVerifying, loading, onVerify, rememberDevice]
  );

  const isExpired = timeRemaining !== null && timeRemaining <= 0;
  const isSubmitting = isVerifying || loading;

  return (
    <div className="w-full space-y-6">
      {/* Header */}
      <div className="text-center space-y-2">
        <div className="mx-auto w-12 h-12 rounded-full bg-primary/10 flex items-center justify-center mb-4">
          <Mail className="w-6 h-6 text-primary" />
        </div>
        <h2 className="text-xl font-semibold text-foreground">Check your email</h2>
        <p className="text-sm text-muted-foreground">
          We sent a verification code to <span className="font-medium">{maskedEmail}</span>
        </p>
      </div>

      {/* OTP Input */}
      <div className="space-y-4">
        <OtpInput
          value={code}
          onChange={setCode}
          onComplete={handleComplete}
          disabled={isSubmitting || isExpired}
          error={error ?? undefined}
          autoFocus
        />

        {/* Expiry countdown */}
        {timeRemaining !== null && !isExpired && (
          <div className="flex items-center justify-center gap-2 text-sm text-muted-foreground">
            <Clock className="w-4 h-4" />
            <span>Code expires in {formatTimeRemaining(timeRemaining)}</span>
          </div>
        )}

        {isExpired && (
          <ErrorMessage className="text-center">
            Code expired. Please go back and try again.
          </ErrorMessage>
        )}
      </div>

      {/* Remember Device Checkbox */}
      <div className="flex items-center justify-center">
        <input
          id="remember-device"
          name="remember-device"
          type="checkbox"
          checked={rememberDevice}
          onChange={e => setRememberDevice(e.target.checked)}
          disabled={isSubmitting || isExpired}
          className="h-4 w-4 text-primary focus:ring-primary border-border rounded transition-colors accent-primary"
        />
        <label htmlFor="remember-device" className="ml-2 block text-sm text-muted-foreground">
          Remember this device for 7 days
        </label>
      </div>

      {/* Verify Button */}
      <Button
        type="button"
        onClick={handleVerify}
        disabled={code.length !== 6 || isSubmitting || isExpired}
        loading={isSubmitting}
        loadingText="Verifying..."
        className="w-full"
      >
        Verify and Sign In
      </Button>

      {/* Back Link */}
      <button
        type="button"
        onClick={onBack}
        disabled={isSubmitting}
        className="flex items-center justify-center gap-2 w-full text-sm text-muted-foreground hover:text-foreground transition-colors duration-200 disabled:opacity-50"
      >
        <ArrowLeft className="w-4 h-4" />
        <span>Back to login</span>
      </button>

      {/* Help text */}
      <p className="text-xs text-center text-muted-foreground">
        Didn&apos;t receive the code? Check your spam folder or go back to try again.
      </p>
    </div>
  );
}
