/**
 * usePhoneVerification — Firebase phone-OTP client flow for vendor onboarding.
 *
 * Mirrors the proven customer-login mechanics (OtpLoginShell): invisible
 * reCAPTCHA → signInWithPhoneNumber → confirm(code) → exchange the Firebase
 * idToken at `verifyEndpoint`. Two consumers:
 *   - VendorLanding (guest registration) → POST /api/auth/firebase-verify
 *     (find-or-create phone-keyed user + session; reads the vendor-reg cookie).
 *   - VendorUpgradeFormShell (authenticated, no phone) → POST /api/auth/attach-phone
 *     (bind verified phone to the current session user).
 *
 * Supports the Playwright E2E bypass (window.__E2E_PHONE_AUTH__ / __E2E_SECRET__):
 * skips Firebase and posts an "E2E:+<phone>" token with a time-bound, body-bound proof.
 */

'use client';

import { useRef, useState } from 'react';
import { getFirebaseAuth } from '@/lib/firebase.js';
import type { ConfirmationResult } from 'firebase/auth';
import { normalizeToE164 } from '@/lib/phone';
import { getCsrfToken } from '@/lib/csrf';
import { captureCaught } from '@/lib/observability';
import { buildE2eProofHeaders } from '@/lib/security/e2e-proof';

export interface PhoneOtpResult {
  ok: boolean;
  /** Firebase error code (e.g. 'auth/invalid-verification-code') when ok=false. */
  code?: string;
  /** Server error string from verifyEndpoint when ok=false. */
  error?: string;
}

export function usePhoneVerification(verifyEndpoint: string) {
  const recaptchaContainerRef = useRef<HTMLDivElement>(null);
  const [sending, setSending] = useState(false);
  const [verifying, setVerifying] = useState(false);
  const [confirmationResult, setConfirmationResult] = useState<ConfirmationResult | null>(null);
  const storedPhoneRef = useRef<string>('');

  const e2ePhoneAuth =
    typeof window !== 'undefined' &&
    (window as { __E2E_PHONE_AUTH__?: boolean }).__E2E_PHONE_AUTH__ === true;

  /** Trigger a Firebase SMS send for `phone` (E.164-normalized for `countryIso`). */
  async function sendCode(phone: string, countryIso = 'IL'): Promise<PhoneOtpResult> {
    setSending(true);
    try {
      const e164Phone = normalizeToE164(phone, countryIso);
      storedPhoneRef.current = e164Phone;
      if (e2ePhoneAuth) return { ok: true };
      const { RecaptchaVerifier, signInWithPhoneNumber } = await import('firebase/auth');
      const auth = await getFirebaseAuth();
      const recaptchaVerifier = new RecaptchaVerifier(auth, recaptchaContainerRef.current!, {
        size: 'invisible',
      });
      const result = await signInWithPhoneNumber(auth, e164Phone, recaptchaVerifier);
      setConfirmationResult(result);
      return { ok: true };
    } catch (err) {
      captureCaught(err, {
        scope: 'features.vendor-onboarding.usePhoneVerification.send',
        severity: 'warning',
      });
      return { ok: false, code: (err as { code?: string }).code ?? '' };
    } finally {
      setSending(false);
    }
  }

  /** Confirm the SMS `code` and exchange the resulting idToken at verifyEndpoint. */
  async function verifyCode(code: string): Promise<PhoneOtpResult> {
    setVerifying(true);
    try {
      let idToken: string;
      const headers: Record<string, string> = { 'Content-Type': 'application/json' };
      if (e2ePhoneAuth) {
        idToken = `E2E:${storedPhoneRef.current}`;
        const payload = JSON.stringify({ idToken });
        const secret = (window as { __E2E_SECRET__?: string }).__E2E_SECRET__;
        if (secret) {
          Object.assign(
            headers,
            await buildE2eProofHeaders(secret, 'POST', verifyEndpoint, payload),
          );
        }
        const res = await fetch(verifyEndpoint, {
          method: 'POST',
          headers,
          body: payload,
        });
        const data = (await res.json()) as { ok: boolean; error?: string };
        if (!data.ok) return { ok: false, error: data.error };
        return { ok: true };
      } else {
        if (!confirmationResult) return { ok: false, code: 'no-confirmation' };
        const cred = await confirmationResult.confirm(code);
        idToken = await cred.user.getIdToken();
        // firebase-verify is CSRF-exempt (no session yet); attach-phone requires it.
        headers['x-csrf-token'] = getCsrfToken();
      }
      const payload = JSON.stringify({ idToken });
      const res = await fetch(verifyEndpoint, {
        method: 'POST',
        headers,
        body: payload,
      });
      const data = (await res.json()) as { ok: boolean; error?: string };
      if (!data.ok) return { ok: false, error: data.error };
      return { ok: true };
    } catch (err) {
      captureCaught(err, {
        scope: 'features.vendor-onboarding.usePhoneVerification.verify',
        severity: 'warning',
      });
      return { ok: false, code: (err as { code?: string }).code ?? '' };
    } finally {
      setVerifying(false);
    }
  }

  return { recaptchaContainerRef, sending, verifying, sendCode, verifyCode };
}
