'use client';

import { useCallback, useEffect, useState } from 'react';
import * as Dialog from '@radix-ui/react-dialog';
import { useCheckoutModalStore } from './checkoutModalStore';
import { Skeleton } from '@/components/ui/feedback/Skeleton';
import type { DealContext, CheckoutModalPreview } from './checkoutModalStore';
import { DealSummaryRow } from './DealSummaryRow';
import { GroupDealStatusRow } from './GroupDealStatusRow';
import { QuantitySelector } from './QuantitySelector';
import { PhoneVerificationSection } from './PhoneVerificationSection';
import { GuestShippingAddressPicker } from './GuestShippingAddressPicker';
import { PickupInstructions } from './PickupInstructions';
import { RedemptionInstructions } from './RedemptionInstructions';
import { CheckoutPriceSummary } from './CheckoutPriceSummary';
import { StoredPaymentMethodSelector } from './StoredPaymentMethodSelector';
import { PromoCodeInput, type PromoApplied } from '@/features/checkout/PromoCodeInput';
import StripePaymentElement from '@/components/ui/checkout/StripePaymentElement';
import { LegalDisclosure } from '@/components/ui/domain/LegalDisclosure/LegalDisclosure';
import { Button } from '@/components/ui/primitives/Button';
import { IconButton } from '@/components/ui/primitives/IconButton';
import { Icon } from '@/components/ui/icons/Icon';
import { useT } from '@/lib/i18n/react';
import { interpolate } from '@/lib/i18n/interpolate';
import { captureCaught } from '@/lib/observability';
import { VariantPicker } from '@/features/deal-detail/VariantPicker';
import type { DealWithSkus, AxisWithOptions, SkuRow } from '@/server/domain/variants/read';

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

type ModalState =
  | 'closed'
  | 'loading'
  | 'error'
  | 'picking_variant'
  | 'ready'
  | 'creating_purchase'
  | 'stripe_element'
  | 'reserving_group'
  | 'group_reserved';

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

function CheckoutModalSkeleton({ preview }: { preview?: CheckoutModalPreview }) {
  const hasFullPreview =
    preview !== undefined &&
    preview.discountedPriceAgorot !== null &&
    preview.originalPriceAgorot !== null;

  return (
    <div className="flex flex-col gap-5">
      {/* Deal summary row */}
      {hasFullPreview ? (
        <DealSummaryRow
          thumbnailUrl={preview!.thumbnailUrl}
          title={preview!.title}
          businessName={preview!.businessName}
          skuLabel={preview!.skuLabel}
          discountedPriceAgorot={preview!.discountedPriceAgorot!}
          originalPriceAgorot={preview!.originalPriceAgorot!}
        />
      ) : (
        <div className="flex items-start gap-3">
          {preview?.thumbnailUrl ? (
            <img
              src={preview.thumbnailUrl}
              alt={preview.title}
              width={72}
              height={72}
              loading="eager"
              className="size-18 shrink-0 rounded-lg object-cover"
            />
          ) : (
            <Skeleton variant="rect" className="size-18 shrink-0 rounded-lg" />
          )}
          <div className="flex min-w-0 flex-col gap-1">
            {preview ? (
              <>
                <p className="text-text-secondary truncate text-sm">{preview.businessName}</p>
                <p className="line-clamp-2 leading-snug font-medium">{preview.title}</p>
              </>
            ) : (
              <>
                <Skeleton variant="text" className="h-4 w-2/3" />
                <Skeleton variant="text" className="mt-1 h-5 w-1/2" />
              </>
            )}
            <Skeleton variant="text" className="mt-1 h-6 w-24" />
          </div>
        </div>
      )}

      {/* Form skeleton */}
      <hr className="border-border-subtle" aria-hidden />
      <div className="flex items-center justify-between">
        <Skeleton variant="text" className="h-5 w-1/3" />
        <Skeleton variant="rect" className="h-8 w-20 rounded-lg" />
      </div>
      <hr className="border-border-subtle" aria-hidden />
      <div className="flex flex-col gap-2">
        <div className="flex items-center justify-between">
          <Skeleton variant="text" className="h-4 w-24" />
          <Skeleton variant="text" className="h-4 w-16" />
        </div>
        <hr className="border-border-subtle" aria-hidden />
        <div className="flex items-center justify-between">
          <Skeleton variant="text" className="h-5 w-32" />
          <Skeleton variant="text" className="h-5 w-20" />
        </div>
      </div>
      <Skeleton variant="rect" className="h-11 w-full rounded-xl" />
    </div>
  );
}

export function CheckoutModal() {
  const t = useT('checkout_modal');
  const payload = useCheckoutModalStore((s) => s.payload);
  const close = useCheckoutModalStore((s) => s.close);

  const [state, setState] = useState<ModalState>('closed');
  const [deal, setDeal] = useState<DealContext | null>(null);
  const [isGuest, setIsGuest] = useState(true);
  const [csrfToken, setCsrfToken] = useState<string | null>(null);
  const [publishableKey, setPublishableKey] = useState<string | null>(null);
  const [quantity, setQuantity] = useState(1);
  const [promoApplied, setPromoApplied] = useState<PromoApplied | null>(null);
  const [promoOpen, setPromoOpen] = useState(false);
  const [selectedAddressId, setSelectedAddressId] = useState<string | null>(null);
  const [selectedPaymentMethodId, setSelectedPaymentMethodId] = useState<string | null>(null);
  const [clientSecret, setClientSecret] = useState<string | null>(null);
  const [purchaseId, setPurchaseId] = useState<string | null>(null);
  const [errorMsg, setErrorMsg] = useState<string | null>(null);
  const [retryCount, setRetryCount] = useState(0);
  const [variantData, setVariantData] = useState<DealWithSkus | null>(null);
  const [pendingSkuId, setPendingSkuId] = useState<string | null>(null);

  // ── Load deal context when payload arrives ─────────────────────────────────
  useEffect(() => {
    if (!payload) {
      const resetTimer = setTimeout(() => {
        setState('closed');
        setDeal(null);
        setQuantity(1);
        setPromoApplied(null);
        setPromoOpen(false);
        setClientSecret(null);
        setPurchaseId(null);
        setPublishableKey(null);
        setVariantData(null);
        setPendingSkuId(null);
      }, 0);
      return () => clearTimeout(resetTimer);
    }

    let cancelled = false;
    queueMicrotask(() => {
      if (!cancelled) setState('loading');
    });
    const url =
      '/api/deals/' +
      payload.dealId +
      '/checkout-context' +
      (payload.skuId ? '?skuId=' + payload.skuId : '');
    const skusUrl = payload.skuId === null ? '/api/deals/' + payload.dealId + '/skus' : null;

    // Use in-flight prefetch when available (started on onPointerDown)
    const ctxPromise: Promise<{ ok: boolean; deal?: DealContext }> =
      payload.pendingContextFetch && retryCount === 0
        ? payload.pendingContextFetch
        : (fetch(url).then((r) => r.json()) as Promise<{
            ok: boolean;
            deal?: DealContext;
          }>);

    void (async () => {
      try {
        const [ctxJson, cfgRes, skusRes] = await Promise.all([
          ctxPromise,
          fetch('/api/payments/client-config'),
          skusUrl ? fetch(skusUrl) : Promise.resolve(null),
        ]);
        const cfgJson = (await cfgRes.json()) as {
          ok: boolean;
          publishableKey?: string;
          data?: { publishableKey?: string };
        };
        // IMPORTANT: respondOk spreads data flat, so skus response is { ok, axes, skus } NOT { ok, data: {...} }
        const skusJson = skusRes
          ? ((await skusRes.json()) as {
              ok: boolean;
              axes?: AxisWithOptions[];
              skus?: SkuRow[];
            })
          : null;

        if (cancelled) return;

        const stripeKey = cfgJson.publishableKey ?? cfgJson.data?.publishableKey;
        if (cfgJson.ok && stripeKey) {
          setPublishableKey(stripeKey);
        }

        if (!ctxJson.ok || !ctxJson.deal) {
          setState('error');
          return;
        }

        const d = ctxJson.deal;
        setDeal(d);
        setIsGuest(d.isGuest);
        setCsrfToken(d.csrfToken);

        // Multi-variant path: show VariantPicker before proceeding to checkout (not GROUP)
        if (skusJson?.ok && skusJson.axes && skusJson.axes.length > 0 && d.dealType !== 'GROUP') {
          setVariantData({
            dealId: payload.dealId,
            axes: skusJson.axes,
            skus: skusJson.skus ?? [],
          });
          setState('picking_variant');
          return;
        }

        setState(d.dealType === 'GROUP' ? 'reserving_group' : 'ready');
      } catch (err) {
        if (cancelled) return;
        captureCaught(err, {
          scope: 'checkout-modal.load',
          severity: 'warning',
        });
        setState('error');
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [payload, retryCount]);

  // ── Max quantity calculation ───────────────────────────────────────────────
  const maxAvail = deal
    ? deal.dealType === 'GROUP'
      ? (deal.group?.perCustomerLimit ?? 1)
      : Math.min(deal.stockRemaining ?? 99, deal.maxPerUser ?? 99)
    : 1;

  const mode = deal?.fulfillment?.mode ?? 'none';
  const isDelivery = mode === 'delivery';

  // ── Continue after variant selection ─────────────────────────────────────
  const handleContinueFromVariantPick = useCallback(async () => {
    if (!pendingSkuId || !payload) return;
    setState('loading');
    try {
      const [ctxRes, cfgRes] = await Promise.all([
        fetch('/api/deals/' + payload.dealId + '/checkout-context?skuId=' + pendingSkuId),
        fetch('/api/payments/client-config'),
      ]);
      const ctxJson = (await ctxRes.json()) as {
        ok: boolean;
        deal?: DealContext;
      };
      const cfgJson = (await cfgRes.json()) as {
        ok: boolean;
        publishableKey?: string;
        data?: { publishableKey?: string };
      };
      const stripeKey = cfgJson.publishableKey ?? cfgJson.data?.publishableKey;
      if (cfgJson.ok && stripeKey) {
        setPublishableKey(stripeKey);
      }
      if (!ctxJson.ok || !ctxJson.deal) {
        setState('error');
        return;
      }
      const d = ctxJson.deal;
      setDeal(d);
      setIsGuest(d.isGuest);
      setCsrfToken(d.csrfToken);
      setState(d.dealType === 'GROUP' ? 'reserving_group' : 'ready');
    } catch (err) {
      captureCaught(err, {
        scope: 'checkout-modal.pick-variant',
        severity: 'warning',
      });
      setState('error');
    }
  }, [pendingSkuId, payload]);

  // ── Proceed to payment (ITEM/SERVICE/VOUCHER) ─────────────────────────────
  const handleProceedToPayment = useCallback(
    async (csrfTokenOverride?: string) => {
      const paymentCsrfToken = csrfTokenOverride ?? csrfToken;
      if (!deal || !paymentCsrfToken || state === 'creating_purchase') return;
      setState('creating_purchase');
      setErrorMsg(null);
      try {
        const idempotencyKey = crypto.randomUUID();
        const pendingRes = await fetch('/api/purchases/pending', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'x-csrf-token': paymentCsrfToken,
          },
          body: JSON.stringify({
            dealId: deal.id,
            skuId: pendingSkuId ?? payload?.skuId ?? deal.defaultSkuId,
            quantity,
            idempotencyKey,
            ...(promoApplied ? { promoCode: promoApplied.code } : {}),
            ...(isDelivery && selectedAddressId ? { shippingAddressId: selectedAddressId } : {}),
          }),
        });
        const pendingJson = (await pendingRes.json()) as {
          ok: boolean;
          purchaseId?: string;
          code?: string;
        };
        if (!pendingRes.ok || !pendingJson.ok || !pendingJson.purchaseId) {
          if (pendingJson.code === 'PROMO_REJECTED') setPromoApplied(null);
          setState('ready');
          setErrorMsg(
            pendingJson.code
              ? interpolate(t('error_with_code'), { code: pendingJson.code })
              : t('error_generic'),
          );
          return;
        }
        const pid = pendingJson.purchaseId;
        setPurchaseId(pid);

        const intentRes = await fetch('/api/checkout/intent', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'x-csrf-token': paymentCsrfToken,
          },
          body: JSON.stringify({ purchaseId: pid }),
        });
        const intentJson = (await intentRes.json()) as {
          ok: boolean;
          clientSecret?: string;
          finalized?: boolean;
          code?: string;
        };
        if (!intentRes.ok || !intentJson.ok) {
          setState('ready');
          setErrorMsg(
            intentJson.code
              ? interpolate(t('error_with_code'), { code: intentJson.code })
              : t('error_generic'),
          );
          return;
        }
        if (intentJson.finalized) {
          window.location.href = `/purchases/${pid}/confirmation`;
          return;
        }
        setClientSecret(intentJson.clientSecret ?? null);
        setState('stripe_element');
      } catch (err) {
        captureCaught(err, {
          scope: 'checkout-modal.proceed',
          severity: 'warning',
        });
        setState('ready');
        setErrorMsg(t('error_generic'));
      }
    },
    [
      deal,
      csrfToken,
      state,
      payload,
      pendingSkuId,
      quantity,
      promoApplied,
      isDelivery,
      selectedAddressId,
      t,
    ],
  );

  // ── OTP verified callback ─────────────────────────────────────────────────
  const handleVerified = useCallback(
    (newCsrfToken: string) => {
      setCsrfToken(newCsrfToken);
      setIsGuest(false);
      if (deal && deal.dealType !== 'GROUP' && (!isDelivery || selectedAddressId)) {
        void handleProceedToPayment(newCsrfToken);
      }
    },
    [deal, handleProceedToPayment, isDelivery, selectedAddressId],
  );

  // ── Reserve spot (GROUP) ─────────────────────────────────────────────────
  const handleReserveSpot = useCallback(async () => {
    if (!deal || !csrfToken || !selectedPaymentMethodId) return;
    const groupDealId = deal.groupDealId;
    if (!groupDealId) {
      setState('reserving_group');
      setErrorMsg(t('error_generic'));
      return;
    }
    setState('creating_purchase');
    setErrorMsg(null);
    try {
      const res = await fetch(`/api/group-deals/${groupDealId}/reserve`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-csrf-token': csrfToken,
        },
        body: JSON.stringify({
          paymentMethodId: selectedPaymentMethodId,
          quantity,
          idempotencyKey: crypto.randomUUID(),
        }),
      });
      const json = (await res.json()) as { ok: boolean; code?: string };
      if (!res.ok || !json.ok) {
        setState('reserving_group');
        setErrorMsg(t('error_generic'));
        return;
      }
      setState('group_reserved');
    } catch (err) {
      captureCaught(err, {
        scope: 'checkout-modal.reserve',
        severity: 'warning',
      });
      setState('reserving_group');
      setErrorMsg(t('error_generic'));
    }
  }, [deal, csrfToken, selectedPaymentMethodId, quantity, t]);

  const open = !!payload;
  const discountAgorot = promoApplied?.totalDiscountAgorot ?? 0;
  const isGroupFlow = deal?.dealType === 'GROUP';

  return (
    <Dialog.Root
      open={open}
      onOpenChange={(v) => {
        if (!v) close();
      }}
    >
      <Dialog.Portal>
        <Dialog.Overlay className="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm" />
        <Dialog.Content
          className="bg-surface-default fixed inset-x-4 top-[5dvh] bottom-[5dvh] z-50 mx-auto max-w-lg overflow-y-auto rounded-2xl p-5 shadow-xl focus:outline-none"
          aria-label={t('title')}
        >
          {/* Header */}
          <div className="mb-4 flex items-center justify-between">
            <Dialog.Title className="text-lg font-semibold">{t('title')}</Dialog.Title>
            <Dialog.Close asChild>
              <IconButton variant="ghost" size="sm" aria-label={t('close')}>
                <Icon name="X" size="sm" />
              </IconButton>
            </Dialog.Close>
          </div>

          {/* Loading */}
          {state === 'loading' && <CheckoutModalSkeleton preview={payload?.preview} />}

          {/* Error */}
          {state === 'error' && (
            <div className="flex flex-col items-center gap-4 py-10">
              <p className="text-text-secondary">{t('error_load')}</p>
              <Button
                variant="secondary"
                size="md"
                onClick={() => {
                  if (payload) setRetryCount((c) => c + 1);
                }}
              >
                {t('try_again')}
              </Button>
            </div>
          )}

          {/* Variant picker — shown for multi-variant cards before checkout */}
          {state === 'picking_variant' && variantData && deal && (
            <div className="flex flex-col gap-5">
              <DealSummaryRow
                thumbnailUrl={deal.thumbnailUrl}
                title={deal.title}
                businessName={deal.businessName}
                skuLabel={null}
                discountedPriceAgorot={deal.discountedPriceAgorot}
                originalPriceAgorot={deal.originalPriceAgorot}
              />
              <VariantPicker
                axes={variantData.axes}
                skus={variantData.skus}
                onSelect={setPendingSkuId}
              />
              <Button
                variant="primary"
                size="lg"
                className="w-full"
                disabled={!pendingSkuId}
                onClick={() => void handleContinueFromVariantPick()}
              >
                {t('choose_variant_continue')}
              </Button>
            </div>
          )}

          {/* Main content */}
          {deal &&
            (state === 'ready' ||
              state === 'creating_purchase' ||
              state === 'stripe_element' ||
              state === 'reserving_group') && (
              <div className="flex flex-col gap-5">
                <DealSummaryRow
                  thumbnailUrl={deal.thumbnailUrl}
                  title={deal.title}
                  businessName={deal.businessName}
                  skuLabel={deal.skuLabel}
                  discountedPriceAgorot={deal.discountedPriceAgorot}
                  originalPriceAgorot={deal.originalPriceAgorot}
                />

                {deal.dealType === 'GROUP' && deal.group && (
                  <GroupDealStatusRow group={deal.group} />
                )}

                <QuantitySelector quantity={quantity} maxAvail={maxAvail} onChange={setQuantity} />

                <PhoneVerificationSection isGuest={isGuest} onVerified={handleVerified} />

                {deal &&
                  (mode === 'delivery' ? (
                    <GuestShippingAddressPicker
                      isGuest={isGuest}
                      onAddressSelected={setSelectedAddressId}
                    />
                  ) : mode === 'pickup' ? (
                    <PickupInstructions info={deal.fulfillment} />
                  ) : mode === 'voucher' ? (
                    <RedemptionInstructions info={deal.fulfillment} />
                  ) : null)}

                {!isGroupFlow && (
                  <div className="flex flex-col gap-1">
                    <Button
                      type="button"
                      variant="ghost"
                      size="sm"
                      className="text-text-primary ms-auto flex h-auto items-center gap-1.5 p-0 font-medium hover:bg-transparent disabled:cursor-not-allowed disabled:opacity-40"
                      onClick={() => setPromoOpen((o) => !o)}
                      disabled={state === 'stripe_element'}
                      aria-expanded={promoOpen}
                    >
                      <span aria-hidden className="text-base leading-none">
                        {promoOpen ? '−' : '+'}
                      </span>
                      {t('promo_toggle_open')}
                      {promoApplied && (
                        <span className="bg-success/10 text-success rounded px-1.5 py-0.5 text-xs font-normal">
                          {promoApplied.code}
                        </span>
                      )}
                    </Button>
                    {promoOpen && (
                      <div className="mt-2">
                        <PromoCodeInput applied={promoApplied} onApplied={setPromoApplied} />
                      </div>
                    )}
                  </div>
                )}

                <CheckoutPriceSummary
                  unitPriceAgorot={deal.discountedPriceAgorot}
                  quantity={quantity}
                  discountAgorot={discountAgorot}
                  shippingAgorot={0}
                  vatRatePercent={deal.vatRatePercent}
                />

                {errorMsg && <p className="text-destructive text-sm">{errorMsg}</p>}

                {/* Group deal payment: stored cards / inline setup */}
                {state === 'reserving_group' && csrfToken && (
                  <StoredPaymentMethodSelector
                    selectedId={selectedPaymentMethodId}
                    onSelect={setSelectedPaymentMethodId}
                    csrfToken={csrfToken}
                    purchaseId={purchaseId}
                  />
                )}

                {/* Action buttons */}
                {(state === 'ready' || state === 'creating_purchase') && !isGroupFlow && (
                  <>
                    <LegalDisclosure context="checkout" />
                    <Button
                      variant="primary"
                      size="lg"
                      className="w-full"
                      loading={state === 'creating_purchase'}
                      disabled={
                        state === 'creating_purchase' ||
                        !csrfToken ||
                        (isDelivery && !selectedAddressId)
                      }
                      onClick={() => void handleProceedToPayment()}
                    >
                      {t('buy_now')}
                    </Button>
                  </>
                )}

                {/* Stripe payment element (ITEM/SERVICE/VOUCHER) — inline below Buy Now */}
                {state === 'stripe_element' &&
                  clientSecret &&
                  purchaseId &&
                  publishableKey &&
                  !isGroupFlow && (
                    <StripePaymentElement
                      publishableKey={publishableKey}
                      clientSecret={clientSecret}
                      purchaseId={purchaseId}
                      returnUrlPath={`/checkout/${purchaseId}/complete`}
                    />
                  )}

                {(state === 'reserving_group' ||
                  (state === 'creating_purchase' && isGroupFlow)) && (
                  <Button
                    variant="primary"
                    size="lg"
                    className="w-full"
                    loading={state === 'creating_purchase'}
                    disabled={isGuest || !selectedPaymentMethodId}
                    onClick={() => void handleReserveSpot()}
                  >
                    {t('reserve_spot')}
                  </Button>
                )}
              </div>
            )}

          {/* Group reserved confirmation */}
          {state === 'group_reserved' && (
            <div className="flex flex-col items-center gap-4 py-6 text-center">
              <Icon name="CheckCircle" size="xl" className="text-success" />
              <p className="text-lg font-semibold">{t('group_reserved_title')}</p>
              <p className="text-text-secondary text-sm">{t('group_reserved_body')}</p>
              <Button variant="secondary" size="md" onClick={close}>
                {t('close')}
              </Button>
            </div>
          )}
        </Dialog.Content>
      </Dialog.Portal>
    </Dialog.Root>
  );
}
