/**
 * RegisterShell — phone-first registration orchestrator.
 * Routes PhoneStep → CodeStep → EmailOptionalStep → SuccessStep.
 * Owns Firebase + API + E2E bypass. No AppShell/ToastProvider — RegisterPage owns those.
 */

'use client';

import { useState, useRef } from 'react';
import { getFirebaseAuth } from '@/lib/firebase.js';
import type { ConfirmationResult } from 'firebase/auth';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { useT } from '@/lib/i18n/react';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import type { ToastTone } from '@/components/ui/overlays/Toast';
import { useCartMerge } from '@/features/cart/useCartMerge';
import { useWishlistMerge } from '@/features/wishlist/useWishlistMerge';
import { WishlistMergeDialog } from '@/features/wishlist/WishlistMergeDialog';
import { captureCaught } from '@/lib/observability';
import { buildE2eProofHeaders } from '@/lib/security/e2e-proof';
import { broadcastMhEvent } from '@/lib/cross-tab-sync';
import { normalizeToE164 } from '@/lib/phone';
import { PhoneStep } from './steps/PhoneStep';
import { LegalDisclosure } from '@/components/ui/domain/LegalDisclosure/LegalDisclosure';
import { CodeStep } from './steps/CodeStep';
import { SuccessStep } from './steps/SuccessStep';
import { EmailOptionalStep } from './steps/EmailOptionalStep';
import type { EmailOptionalStepValues } from './steps/EmailOptionalStep';

const phoneSchema = z.object({ phone: z.string().min(9, 'Phone number required') });

function codeSchemaFor(invalidCodeMsg: string) {
  return z.object({ code: z.string().regex(/^\d{6}$/, invalidCodeMsg) });
}

const emailOptionalSchema = z.object({
  email: z.union([
    z.literal(''),
    z
      .string()
      .trim()
      .check(z.email({ error: 'Invalid email address' })),
  ]),
  marketingConsent: z.boolean(),
});

type PhoneFormValues = z.infer<typeof phoneSchema>;
type CodeFormValues = { code: string };

export interface RegisterShellProps {
  redirectTo?: string;
  toast: (p: { title: string; tone?: ToastTone; duration?: number; description?: string }) => void;
}

// ─── Shell ───────────────────────────────────────────────────────────────────

export function RegisterShell({ redirectTo = '/', toast }: RegisterShellProps) {
  const t = useT('auth_flow');
  const tCart = useT('cart');
  const tCommon = useT('common');
  const { mergeFromLocalStorage } = useCartMerge();
  const wishlistMerge = useWishlistMerge();
  const [step, setStep] = useState<'phone' | 'code' | 'email' | 'success'>('phone');
  const [apiError, setApiError] = useState<string | null>(null);

  const phoneForm = useForm<PhoneFormValues>({ resolver: zodResolver(phoneSchema) });
  const codeForm = useForm<CodeFormValues>({
    resolver: zodResolver(codeSchemaFor(t('invalid_code'))),
  });
  const emailForm = useForm<EmailOptionalStepValues>({
    resolver: zodResolver(emailOptionalSchema),
    defaultValues: { email: '', marketingConsent: false },
  });

  const [countryIso, setCountryIso] = useState('IL');
  const [sendingCode, setSendingCode] = useState(false);
  const [verifyingCode, setVerifyingCode] = useState(false);
  const [submittingEmail, setSubmittingEmail] = useState(false);
  const [confirmationResult, setConfirmationResult] = useState<ConfirmationResult | null>(null);
  const [pendingIdToken, setPendingIdToken] = useState<string | null>(null);
  const recaptchaContainerRef = useRef<HTMLDivElement>(null);

  // E2E bypass (Playwright sets window.__E2E_PHONE_AUTH__ via addInitScript).
  const e2ePhoneAuth =
    typeof window !== 'undefined' &&
    (window as { __E2E_PHONE_AUTH__?: boolean }).__E2E_PHONE_AUTH__ === true;
  const storedPhoneRef = useRef<string>('');

  async function onPhoneSubmit(values: PhoneFormValues) {
    setSendingCode(true);
    setApiError(null);
    try {
      const e164Phone = normalizeToE164(values.phone, countryIso);
      if (e2ePhoneAuth) {
        storedPhoneRef.current = e164Phone;
        setStep('code');
        return;
      }
      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);
      setStep('code');
    } catch (err) {
      const code = (err as { code?: string }).code ?? '';
      if (code === 'auth/invalid-phone-number') {
        setApiError(t('invalid_phone'));
      } else if (code === 'auth/too-many-requests') {
        setApiError(t('rate_limited'));
      } else {
        setApiError(tCommon('error'));
      }
    } finally {
      setSendingCode(false);
    }
  }

  async function onCodeSubmit(values: CodeFormValues) {
    setVerifyingCode(true);
    setApiError(null);

    if (e2ePhoneAuth) {
      const idToken = `E2E:${storedPhoneRef.current}`;
      setPendingIdToken(idToken);
      setStep('email');
      setVerifyingCode(false);
      return;
    }

    if (!confirmationResult) {
      setApiError(tCommon('error'));
      setVerifyingCode(false);
      return;
    }
    try {
      const userCredential = await confirmationResult.confirm(values.code);
      const idToken = await userCredential.user.getIdToken();
      setPendingIdToken(idToken);
      setStep('email');
    } catch (err) {
      const code = (err as { code?: string }).code ?? '';
      if (code === 'auth/code-expired') {
        setApiError(t('otp_expired'));
      } else if (code === 'auth/invalid-verification-code') {
        setApiError(t('invalid_code'));
      } else {
        setApiError(tCommon('error'));
      }
    } finally {
      setVerifyingCode(false);
    }
  }

  async function doFirebaseVerify(email?: string, marketingConsent = false) {
    if (!pendingIdToken) {
      setApiError(tCommon('error'));
      return;
    }
    setSubmittingEmail(true);
    setApiError(null);
    try {
      const url = '/api/auth/firebase-verify';
      const bodyStr = JSON.stringify({
        idToken: pendingIdToken,
        ...(email ? { email } : {}),
        marketingConsent,
      });
      const headers: Record<string, string> = { 'Content-Type': 'application/json' };
      const secret =
        typeof window !== 'undefined'
          ? (window as { __E2E_SECRET__?: string }).__E2E_SECRET__
          : undefined;
      if (secret) {
        Object.assign(headers, await buildE2eProofHeaders(secret, 'POST', url, bodyStr));
      }

      const res = await fetch(url, {
        method: 'POST',
        headers,
        body: bodyStr,
      });
      const data = (await res.json()) as { ok: boolean; code?: string; error?: string };

      if (!data.ok) {
        if (res.status === 409 && data.code === 'EMAIL_TAKEN') {
          setApiError(t('register_email_taken'));
          return;
        }
        setApiError(data.error ?? tCommon('error'));
        return;
      }

      try {
        const mergeResult = await mergeFromLocalStorage();
        if (mergeResult.merged.length > 0 || mergeResult.removed.length > 0)
          toast({ title: tCart('mergeToast'), tone: 'success' });
        if (mergeResult.removed.length > 0)
          toast({ title: tCart('mergeRemovedToast'), tone: 'warning' });
      } catch (err) {
        captureCaught(err, {
          scope: 'features.auth-flow.RegisterShell.merge',
          severity: 'warning',
        });
      }
      setSubmittingEmail(false);
      await wishlistMerge.run();
      broadcastMhEvent({ kind: 'login' });
      setStep('success');
      setTimeout(() => window.location.assign(redirectTo), 600);
    } catch (err) {
      captureCaught(err, { scope: 'features.auth-flow.RegisterShell', severity: 'warning' });
      setApiError(tCommon('error'));
    } finally {
      setSubmittingEmail(false);
    }
  }

  function onCodeBack() {
    setStep('phone');
    setApiError(null);
    codeForm.reset();
  }

  async function onEmailSubmit(values: EmailOptionalStepValues) {
    await doFirebaseVerify(values.email || undefined, values.marketingConsent ?? false);
  }

  async function onEmailSkip() {
    await doFirebaseVerify(undefined, false);
  }

  const title = step === 'email' ? t('register_email_step_title') : t('register_phone_step_title');

  return (
    <>
      <div className="flex flex-col gap-6">
        <h1 className="text-text-primary text-center text-[length:var(--font-size-display)] leading-tight font-[var(--font-weight-extrabold)]">
          {title}
        </h1>

        {apiError && step !== 'email' && <InlineNotice tone="danger" description={apiError} />}

        {step === 'success' && <SuccessStep />}

        {step === 'phone' && (
          <>
            <PhoneStep
              form={phoneForm}
              onSubmit={onPhoneSubmit}
              sending={sendingCode}
              recaptchaContainerRef={recaptchaContainerRef}
              countryCode={countryIso}
              onCountryCodeChange={setCountryIso}
            />
            <LegalDisclosure context="register" />
          </>
        )}

        {step === 'code' && (
          <CodeStep
            form={codeForm}
            onSubmit={onCodeSubmit}
            verifying={verifyingCode}
            onBack={onCodeBack}
          />
        )}

        {step === 'email' && (
          <EmailOptionalStep
            form={emailForm}
            onSubmit={onEmailSubmit}
            onSkip={onEmailSkip}
            submitting={submittingEmail}
            apiError={apiError}
          />
        )}
      </div>

      <WishlistMergeDialog {...wishlistMerge.dialogProps} />
    </>
  );
}
