'use client';
import { useEffect, useRef } from 'react';

interface OTPCredential extends Credential {
  code: string;
}

interface OtpCredentialRequestOptions extends CredentialRequestOptions {
  otp: { transport: string[] };
}

/**
 * WebOTP autofill (web.dev/articles/web-otp): on a supporting Android/Chrome browser, reads the
 * SMS-delivered code once the server's template ends with the origin-bound `@<domain> #<code>`
 * line (REQ-039) and feeds it through `onCode` — the caller wires this into the same
 * onChange/onComplete path manual entry uses. Feature-detects `OTPCredential`; unsupported
 * browsers (desktop, iOS Safari, Firefox) silently no-op — no error, no UI difference. Aborted on
 * unmount and whenever `active` turns false (manual verification starts), so a late resolution
 * never overwrites a fresher code.
 */
export function useWebOtp(onCode: (code: string) => void, active: boolean): void {
  const onCodeRef = useRef(onCode);
  // Keep the ref current without adding `onCode` (a fresh closure every render) to the effect
  // below's dependency array — that would abort and re-issue the WebOTP read on every render.
  useEffect(() => {
    onCodeRef.current = onCode;
  });

  useEffect(() => {
    if (!active || typeof window === 'undefined' || !('OTPCredential' in window)) return;

    const controller = new AbortController();
    navigator.credentials
      .get({ otp: { transport: ['sms'] }, signal: controller.signal } as OtpCredentialRequestOptions)
      .then((credential) => {
        const code = (credential as OTPCredential | null)?.code;
        if (code) onCodeRef.current(code);
      })
      .catch(() => {
        // Aborted, unsupported, or dismissed by the user — manual entry remains available.
      });

    return () => controller.abort();
  }, [active]);
}
