'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import { useT } from '@/lib/i18n/react';
import { Button } from '@/components/ui/primitives/Button';
import { Input } from '@/components/ui/primitives/Input';
import { FormField } from '@/components/ui/primitives/FormField';
import { Spinner } from '@/components/ui/feedback/Spinner';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import { CheckoutShell } from '@/components/ui/layout/CheckoutShell';
import StripePaymentElement from '@/components/ui/checkout/StripePaymentElement';
import { LegalDisclosure } from '@/components/ui/domain/LegalDisclosure/LegalDisclosure';
import type { ClientConfig } from '@/server/payments/provider';
import { captureCaught } from '@/lib/observability';
import { AddToCartButton } from '@/components/ui/domain/DealCTA/AddToCartButton';
import { AnimatedNumber } from '@/components/ui/domain/AnimatedNumber';
import { PromoCodeInput, type PromoApplied } from './PromoCodeInput';
import { VatBreakdown } from '@/components/ui/domain/VatBreakdown/VatBreakdown';
import { formatAgorotShekels } from '@/lib/money';

// ─── Types ────────────────────────────────────────────────────────────────────

export interface CheckoutFlowProps {
  deal: {
    id: string;
    /** Default SKU id for non-variant deals. Used by AddToCartButton. */
    defaultSkuId: string | null;
    title: string;
    businessName: string;
    discountedPrice: number;
  };
  csrfToken: string;
  buyerName?: string | null;
  buyerEmail?: string | null;
  defaultOpen?: boolean;
  vatRatePercent?: number;
}

type FlowState = 'idle' | 'creating' | 'intent' | 'stripe_element' | 'error';

// ─── Component ────────────────────────────────────────────────────────────────

export default function CheckoutFlow({
  deal,
  csrfToken,
  buyerName,
  buyerEmail: _buyerEmail,
  defaultOpen = false,
  vatRatePercent,
}: CheckoutFlowProps) {
  const t = useT('checkout');
  const tCommon = useT('common');
  const tPromo = useT('promo_codes');
  const tShell = useT('checkout_shell');

  const [state, setState] = useState<FlowState>(defaultOpen ? 'creating' : 'idle');
  const [purchaseId, setPurchaseId] = useState<string | null>(null);
  const [clientSecret, setClientSecret] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [nameInput, setNameInput] = useState(buyerName ?? '');
  const [appliedPromo, setAppliedPromo] = useState<PromoApplied | null>(null);

  const idempotencyKeyRef = useRef<string>(crypto.randomUUID());

  const [clientConfig, setClientConfig] = useState<ClientConfig | null>(null);
  const [configError, setConfigError] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const res = await fetch('/api/payments/client-config');
        const data = (await res.json()) as { ok: boolean } & Partial<ClientConfig>;
        if (cancelled) return;
        if (!res.ok || !data.ok) {
          setConfigError('CONFIG_LOAD_FAILED');
          return;
        }
        const { ok: _ok, ...config } = data as { ok: true } & ClientConfig;
        setClientConfig(config as ClientConfig);
      } catch (err) {
        captureCaught(err, {
          scope: 'features.checkout.CheckoutFlow.configFetch',
          severity: 'warning',
        });
        if (!cancelled) setConfigError('CONFIG_LOAD_FAILED');
      }
    })();
    return () => {
      cancelled = true;
    };
  }, []);

  // ── Create pending purchase, then create intent ───────────────────────────

  const startCheckout = useCallback(
    async (createIntentFn: (pId: string) => Promise<void>) => {
      setState('creating');
      setError(null);
      try {
        const res = await fetch('/api/purchases/pending', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'x-csrf-token': csrfToken,
          },
          body: JSON.stringify({
            dealId: deal.id,
            idempotencyKey: idempotencyKeyRef.current,
            ...(appliedPromo ? { promoCode: appliedPromo.code } : {}),
          }),
        });
        const data = (await res.json()) as { ok: boolean; purchaseId?: string; code?: string };
        if (!res.ok || !data.ok) {
          if (data.code === 'PROMO_REJECTED') {
            setAppliedPromo(null);
          }
          setError(data.code ?? 'FAILED');
          setState('error');
          return;
        }
        const pId = data.purchaseId!;
        setPurchaseId(pId);
        await createIntentFn(pId);
      } catch (err) {
        captureCaught(err, { scope: 'features.checkout.CheckoutFlow', severity: 'warning' });
        setError('NETWORK_ERROR');
        setState('error');
      }
    },
    [appliedPromo, csrfToken, deal],
  );

  // ── Create Stripe PaymentIntent ───────────────────────────────────────────

  const createIntent = useCallback(
    async (pId: string) => {
      setState('intent');
      try {
        const res = await fetch('/api/checkout/intent', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'x-csrf-token': csrfToken,
          },
          body: JSON.stringify({ purchaseId: pId }),
        });
        // defineApi spreads result.data into the top-level body:
        // { ok: true, clientSecret: '...', providerPaymentId: '...' } — no `data` wrapper
        const data = (await res.json()) as {
          ok: boolean;
          clientSecret?: string;
          providerPaymentId?: string;
          finalized?: true;
          code?: string;
          error?: string;
        };
        if (!res.ok || !data.ok) {
          setError(data.code ?? data.error ?? 'INTENT_FAILED');
          setState('error');
          return;
        }
        if (data.finalized) {
          window.location.href = `/purchases/${pId}/confirmation`;
          return;
        }
        setClientSecret(data.clientSecret!);
        setState('stripe_element');
      } catch (err) {
        captureCaught(err, { scope: 'features.checkout.CheckoutFlow.intent', severity: 'warning' });
        setError('NETWORK_ERROR');
        setState('error');
      }
    },
    [csrfToken],
  );

  const startCheckoutRef = useRef(startCheckout);
  const createIntentRef = useRef(createIntent);
  useEffect(() => {
    startCheckoutRef.current = startCheckout;
    createIntentRef.current = createIntent;
  }, [startCheckout, createIntent]);

  // ── Auto-start when defaultOpen=true ──────────────────────────────────────

  useEffect(() => {
    if (!defaultOpen) return;
    const timer = setTimeout(() => void startCheckoutRef.current(createIntentRef.current), 0);
    return () => clearTimeout(timer);
  }, [defaultOpen]);

  // ── Reset to idle ─────────────────────────────────────────────────────────

  const handleReset = () => {
    setError(null);
    setPurchaseId(null);
    setClientSecret(null);
    setState('idle');
  };

  // ── Render ────────────────────────────────────────────────────────────────

  if (state === 'error') {
    return (
      <div className="flex flex-col gap-4">
        <InlineNotice
          tone="danger"
          title={t('error_title')}
          description={error ?? t('error_generic')}
        />
        <Button variant="primary" size="lg" className="w-full" onClick={handleReset}>
          {t('try_again')}
        </Button>
      </div>
    );
  }

  if (state === 'idle') {
    return (
      <div className="flex flex-col gap-3">
        <PromoCodeInput applied={appliedPromo} onApplied={setAppliedPromo} />
        <LegalDisclosure context="checkout" />
        <div className="flex gap-2">
          <Button
            variant="primary"
            size="md"
            className="flex-1"
            onClick={() => {
              void startCheckout(createIntent);
            }}
          >
            {t('buy_now')}
          </Button>
          <AddToCartButton dealSkuId={deal.defaultSkuId} size="md" title={deal.title} />
        </div>
      </div>
    );
  }

  if (configError) {
    return (
      <InlineNotice tone="danger" title={t('error_title')} description={t('payment_unavailable')} />
    );
  }

  if (state === 'creating' || state === 'intent') {
    return (
      <div className="flex items-center justify-center gap-3 py-4">
        <Spinner variant="bar" size="sm" label={tCommon('loading')} />
        <span className="text-text-secondary text-sm">{t('preparing_checkout')}</span>
      </div>
    );
  }

  if (
    state === 'stripe_element' &&
    clientConfig &&
    clientConfig.provider === 'stripe' &&
    clientSecret &&
    purchaseId
  ) {
    const checkoutSteps = [
      { id: 'details', label: tShell('step_details') },
      { id: 'payment', label: tShell('step_payment') },
    ];
    const basePriceAgorot = Math.round(Number(deal.discountedPrice) * 100);
    const savingsAgorot = appliedPromo?.totalDiscountAgorot ?? 0;
    const netPayAgorot = Math.max(0, basePriceAgorot - savingsAgorot);

    return (
      <CheckoutShell
        steps={checkoutSteps}
        activeStepId="payment"
        onBack={handleReset}
        backLabel={tShell('back_to_previous_step')}
      >
        <div className="flex flex-col gap-4">
          <div className="bg-surface-inset rounded-xl px-4 py-3 shadow-md">
            <p className="text-text-secondary text-xs font-semibold tracking-wide uppercase">
              {t('paying_for')}
            </p>
            <p className="text-text-primary mt-0.5 text-sm font-medium">{deal.title}</p>
            <p className="text-text-muted text-xs">{deal.businessName}</p>
            {appliedPromo && (
              <div className="border-border-default mt-2 flex flex-col gap-1 border-t pt-2">
                <div className="flex items-center justify-between gap-2">
                  <span className="text-success-700 text-xs font-medium">
                    {String(tPromo('discount_line')).replace('{{code}}', appliedPromo.code)}
                  </span>
                  <AnimatedNumber
                    value={savingsAgorot}
                    formatValue={(value) => `−${formatAgorotShekels(Math.round(value))}`}
                    className="text-success-700 text-xs font-medium"
                    ariaLabel={t('savings_ticker_aria').replace(
                      '{{amount}}',
                      formatAgorotShekels(savingsAgorot),
                    )}
                    testId="checkout-savings-ticker"
                    reserveValue={savingsAgorot}
                  />
                </div>
                <div className="flex items-center justify-between gap-2 font-semibold">
                  <span className="text-text-primary text-sm">{t('savings_ticker_label')}</span>
                  <span className="text-success-700 text-sm font-semibold">
                    {formatAgorotShekels(savingsAgorot)}
                  </span>
                </div>
                <div className="flex items-center justify-between gap-2 font-semibold">
                  <span className="text-text-primary text-sm">{t('paying_for')}</span>
                  <span className="text-text-primary text-sm">
                    {formatAgorotShekels(netPayAgorot)}
                  </span>
                </div>
              </div>
            )}
            {vatRatePercent !== undefined && (
              <VatBreakdown
                totalAgorot={netPayAgorot}
                vatRatePercent={vatRatePercent}
                className="mt-2"
              />
            )}
          </div>

          {!buyerName && (
            <FormField label={t('buyer_name')} htmlFor="checkout-buyer-name" required>
              <Input
                id="checkout-buyer-name"
                type="text"
                autoComplete="name"
                value={nameInput}
                onChange={(e) => setNameInput(e.target.value)}
              />
            </FormField>
          )}

          <LegalDisclosure context="checkout" />

          <StripePaymentElement
            publishableKey={clientConfig.publishableKey}
            clientSecret={clientSecret}
            purchaseId={purchaseId}
            returnUrlPath={`/checkout/${purchaseId}/complete`}
          />
        </div>
      </CheckoutShell>
    );
  }

  return (
    <div className="flex items-center justify-center py-4">
      <Spinner variant="bar" size="sm" label={tCommon('loading')} />
    </div>
  );
}
