'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import type { ConfirmationResult } from 'firebase/auth';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { getFirebaseAuth } from '@/lib/firebase.js';
import { getCsrfToken } from '@/lib/csrf';
import { normalizeToE164 } from '@/lib/phone';
import { useT } from '@/lib/i18n/react';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import { Icon } from '@/components/ui/icons/Icon';
import { Button } from '@/components/ui/primitives/Button';
import { FormField } from '@/components/ui/primitives/FormField';
import { Input } from '@/components/ui/primitives/Input';
import { PhoneStep } from '@/features/auth-flow/steps/PhoneStep';
import { captureCaught } from '@/lib/observability';
import { buildE2eProofHeaders } from '@/lib/security/e2e-proof';

const RESEND_SECONDS = 60;

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) });
}

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

export interface PhoneVerificationSectionProps {
  isGuest: boolean;
  onVerified: (csrfToken: string) => void;
}

export function PhoneVerificationSection({ isGuest, onVerified }: PhoneVerificationSectionProps) {
  const t = useT('checkout_modal');
  const tAuth = useT('auth_flow');
  const tCommon = useT('common');

  const [step, setStep] = useState<'phone' | 'code'>('phone');
  const [apiError, setApiError] = useState<string | null>(null);
  const [countryIso, setCountryIso] = useState('IL');
  const [sendingCode, setSendingCode] = useState(false);
  const [verifyingCode, setVerifyingCode] = useState(false);
  const [resendSeconds, setResendSeconds] = useState(RESEND_SECONDS);
  const [displayPhone, setDisplayPhone] = useState('');
  const [confirmationResult, setConfirmationResult] = useState<ConfirmationResult | null>(null);

  const recaptchaContainerRef = useRef<HTMLDivElement>(null);
  const [lastPhoneValues, setLastPhoneValues] = useState<PhoneFormValues>({ phone: '' });

  const e2ePhoneAuth =
    import.meta.env.PUBLIC_E2E_PHONE_AUTH === '1' ||
    (typeof window !== 'undefined' &&
      (window as { __E2E_PHONE_AUTH__?: boolean }).__E2E_PHONE_AUTH__ === true);

  const phoneForm = useForm<PhoneFormValues>({ resolver: zodResolver(phoneSchema) });
  const codeForm = useForm<CodeFormValues>({
    resolver: zodResolver(codeSchemaFor(tAuth('invalid_code'))),
  });

  useEffect(() => {
    if (step !== 'code' || resendSeconds <= 0) return;
    const timer = window.setInterval(() => {
      setResendSeconds((prev) => (prev > 0 ? prev - 1 : 0));
    }, 1000);
    return () => window.clearInterval(timer);
  }, [step, resendSeconds]);

  const sendVerificationCode = useCallback(
    async (values: PhoneFormValues) => {
      setSendingCode(true);
      setApiError(null);
      try {
        const e164Phone = normalizeToE164(values.phone, countryIso);
        setLastPhoneValues(values);
        setDisplayPhone(e164Phone);

        if (e2ePhoneAuth) {
          setStep('code');
          setResendSeconds(RESEND_SECONDS);
          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');
        setResendSeconds(RESEND_SECONDS);
      } catch (err) {
        const code = (err as { code?: string }).code ?? '';
        if (code === 'auth/invalid-phone-number') {
          setApiError(tAuth('invalid_phone'));
        } else if (code === 'auth/too-many-requests') {
          setApiError(tAuth('rate_limited'));
        } else {
          setApiError(tCommon('error'));
        }
      } finally {
        setSendingCode(false);
      }
    },
    [countryIso, e2ePhoneAuth, tAuth, tCommon],
  );

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

    try {
      let idToken: string;
      const url = '/api/auth/firebase-verify';
      const headers: Record<string, string> = { 'Content-Type': 'application/json' };

      if (e2ePhoneAuth) {
        idToken = `E2E:${displayPhone}`;
        const bodyStr = JSON.stringify({ idToken });
        const secret = (window as { __E2E_SECRET__?: string }).__E2E_SECRET__;
        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; error?: string };
        if (!data.ok) {
          setApiError(data.error ?? tCommon('error'));
          return;
        }

        onVerified(getCsrfToken());
        return;
      } else {
        if (!confirmationResult) {
          setApiError(tCommon('error'));
          return;
        }
        const userCredential = await confirmationResult.confirm(values.code);
        idToken = await userCredential.user.getIdToken();
      }

      const bodyStr = JSON.stringify({ idToken });
      const res = await fetch(url, {
        method: 'POST',
        headers,
        body: bodyStr,
      });
      const data = (await res.json()) as { ok: boolean; error?: string };
      if (!data.ok) {
        setApiError(data.error ?? tCommon('error'));
        return;
      }

      onVerified(getCsrfToken());
    } catch (err) {
      const code = (err as { code?: string }).code ?? '';
      if (code === 'auth/code-expired') {
        setApiError(tAuth('otp_expired'));
      } else if (code === 'auth/invalid-verification-code') {
        setApiError(tAuth('invalid_code'));
      } else {
        captureCaught(err, {
          scope: 'features.checkout-modal.PhoneVerification',
          severity: 'warning',
        });
        setApiError(tCommon('error'));
      }
    } finally {
      setVerifyingCode(false);
    }
  }

  function onTryAnotherNumber() {
    setStep('phone');
    setApiError(null);
    setResendSeconds(RESEND_SECONDS);
    setConfirmationResult(null);
    codeForm.reset();
  }

  async function onResend() {
    if (resendSeconds > 0 || sendingCode) return;
    await sendVerificationCode(lastPhoneValues);
    codeForm.reset();
  }

  if (!isGuest) {
    return (
      <div className="flex items-center gap-2">
        <Icon name="CheckCircle" size="sm" className="text-success-600" aria-hidden />
        <span className="text-success-700 text-sm font-medium">{t('phone_already_verified')}</span>
      </div>
    );
  }

  return (
    <div className="flex flex-col gap-4">
      <h2 className="text-text-primary text-base font-semibold">{t('phone_section_title')}</h2>

      {apiError && <InlineNotice tone="danger" description={apiError} />}

      {step === 'phone' && (
        <PhoneStep
          form={phoneForm}
          onSubmit={sendVerificationCode}
          sending={sendingCode}
          recaptchaContainerRef={recaptchaContainerRef}
          countryCode={countryIso}
          onCountryCodeChange={setCountryIso}
        />
      )}

      {step === 'code' && (
        <div className="flex flex-col gap-4">
          {displayPhone && (
            <p className="text-text-secondary text-sm">
              {t('code_sent_to').replace('{{phone}}', displayPhone)}
            </p>
          )}

          <form
            onSubmit={codeForm.handleSubmit((v) => void onCodeSubmit(v))}
            className="flex flex-col gap-4"
            noValidate
          >
            <FormField
              label={tAuth('code_label')}
              required
              error={codeForm.formState.errors.code?.message}
              htmlFor="checkout-phone-code"
            >
              <Input
                id="checkout-phone-code"
                type="text"
                inputMode="numeric"
                maxLength={6}
                dir="ltr"
                autoComplete="one-time-code"
                placeholder={tAuth('code_placeholder')}
                {...codeForm.register('code')}
              />
            </FormField>

            <Button
              type="submit"
              variant="primary"
              size="lg"
              loading={verifyingCode}
              className="w-full"
            >
              {tAuth('verify')}
            </Button>
          </form>

          <div className="flex flex-col items-center gap-2">
            {resendSeconds > 0 ? (
              <p className="text-text-secondary text-sm" aria-live="polite">
                {t('resend_in').replace('{{seconds}}', String(resendSeconds))}
              </p>
            ) : (
              <Button
                type="button"
                variant="ghost"
                size="sm"
                onClick={() => void onResend()}
                disabled={sendingCode}
                className="text-text-link hover:text-text-link-hover h-auto p-0 font-medium underline hover:bg-transparent disabled:opacity-50"
              >
                {t('resend_now')}
              </Button>
            )}

            <Button
              type="button"
              variant="ghost"
              size="sm"
              onClick={onTryAnotherNumber}
              className="text-text-link hover:text-text-link-hover h-auto p-0 font-medium underline hover:bg-transparent"
            >
              {t('try_another_number')}
            </Button>
          </div>
        </div>
      )}
    </div>
  );
}
