/**
 * OtpStep - Enter 6-digit OTP verification code
 *
 * Features:
 * - Auto-submit on complete
 * - 60s resend cooldown with countdown (via store)
 * - Code expiry countdown timer
 * - Max 3 resend attempts before forcing restart
 */

"use client";

import { useState, useCallback, useEffect, useRef } from "react";
import { Button } from "@/components/atoms";
import { OtpInput, OtpExpiryDisplay } from "@/components/molecules";
import { useEligibilityCheckStore } from "../../../stores/eligibility-check.store";

const MAX_RESENDS = 3;
const CODE_TTL_MS = 10 * 60 * 1000;

function useExpiryTimer() {
  const [timeRemaining, setTimeRemaining] = useState<number | null>(null);
  const expiryRef = useRef<number>(Date.now() + CODE_TTL_MS);

  const resetExpiry = useCallback(() => {
    expiryRef.current = Date.now() + CODE_TTL_MS;
  }, []);

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

    update();
    const interval = setInterval(update, 1000);
    return () => clearInterval(interval);
  }, []);

  const isExpired = timeRemaining !== null && timeRemaining <= 0;
  return { timeRemaining, isExpired, resetExpiry };
}

function OtpActions({
  loading,
  resendDisabled,
  resendCountdown,
  resendCount,
  onChangeEmail,
  onResend,
}: {
  loading: boolean;
  resendDisabled: boolean;
  resendCountdown: number;
  resendCount: number;
  onChangeEmail: () => void;
  onResend: () => void;
}) {
  const maxedOut = resendCount >= MAX_RESENDS;

  let resendLabel = "Resend code";
  if (maxedOut) resendLabel = "Max resends reached";
  else if (resendDisabled && resendCountdown > 0) resendLabel = `Resend in ${resendCountdown}s`;

  return (
    <div className="flex items-center justify-between">
      <Button
        type="button"
        variant="ghost"
        onClick={onChangeEmail}
        disabled={loading}
        className="text-sm"
      >
        Change email
      </Button>

      <Button
        type="button"
        variant="ghost"
        onClick={onResend}
        disabled={loading || resendDisabled || maxedOut}
        className="text-sm"
      >
        {resendLabel}
      </Button>
    </div>
  );
}

export function OtpStep() {
  const {
    formData,
    verifyOtp,
    resendOtp,
    goToStep,
    loading,
    otpError,
    clearOtpError,
    attemptsRemaining,
    resendDisabled,
    resendCountdown,
  } = useEligibilityCheckStore();

  const [otpValue, setOtpValue] = useState("");
  const [resendCount, setResendCount] = useState(0);
  const { timeRemaining, isExpired, resetExpiry } = useExpiryTimer();

  // Clear input whenever a new error appears
  useEffect(() => {
    if (otpError) setOtpValue("");
  }, [otpError]);

  const handleCodeChange = useCallback(
    (value: string) => {
      setOtpValue(value);
      clearOtpError();
    },
    [clearOtpError]
  );

  const handleComplete = useCallback(
    async (code: string) => {
      if (isExpired) return;
      clearOtpError(); // Ensure null→error transition so the effect always fires
      try {
        await verifyOtp(code);
      } catch {
        // error is set by store; effect above clears the input
      }
    },
    [verifyOtp, isExpired, clearOtpError]
  );

  const handleVerify = () => {
    if (otpValue.length === 6 && !isExpired) void handleComplete(otpValue);
  };

  const handleResend = async () => {
    if (resendCount >= MAX_RESENDS) return;
    setOtpValue("");
    const success = await resendOtp();
    if (success) {
      setResendCount(prev => prev + 1);
      resetExpiry();
    }
  };

  return (
    <div className="space-y-6">
      <p className="text-sm text-muted-foreground text-center">
        We sent a 6-digit code to{" "}
        <span className="font-medium text-foreground">{formData.email}</span>
      </p>

      <div className="py-4">
        <OtpInput
          length={6}
          value={otpValue}
          onChange={handleCodeChange}
          onComplete={handleComplete}
          disabled={loading || isExpired}
          {...(otpError && { error: otpError })}
          autoFocus
        />
      </div>

      {attemptsRemaining !== null && attemptsRemaining < 3 && (
        <p className="text-sm text-warning text-center">
          {attemptsRemaining} attempt{attemptsRemaining === 1 ? "" : "s"} remaining
        </p>
      )}

      <OtpExpiryDisplay timeRemaining={timeRemaining} isExpired={isExpired} />

      <Button
        type="button"
        onClick={handleVerify}
        disabled={loading || otpValue.length !== 6 || isExpired}
        loading={loading}
        className="w-full h-11"
      >
        {loading ? "Verifying..." : "Verify & Continue"}
      </Button>

      <OtpActions
        loading={loading}
        resendDisabled={resendDisabled}
        resendCountdown={resendCountdown}
        resendCount={resendCount}
        onChangeEmail={() => goToStep("form")}
        onResend={handleResend}
      />
    </div>
  );
}
