'use client';
import { ErrorState } from '@/components/ui/feedback/ErrorState';

/**
 * GroupReservationFlow - checkout-style reservation form for group deals (FDS §PKG-7).
 *
 * Shows:
 *  - Hold notice (amount held, only charged on success)
 *  - Quantity picker (1 to perCustomerLimit)
 *  - Price display (unit × quantity)
 *  - If tiered: "price could drop to" notice
 *  - Payment method selector (stored cards from API)
 *  - Submit button: "Reserve Your Spot"
 *  - Loading state during API call
 *  - Success state: reservation confirmation
 */

import { useState, useEffect } from 'react';
import { Controller } from 'react-hook-form';
import { useQuery } from '@tanstack/react-query';
import { AppShell } from '@/components/ui/layout/AppShell';
import { TopBar } from '@/components/ui/layout/TopBar';
import { BottomNav, useCustomerNavItems } from '@/components/ui/layout/BottomNav';
import { Container } from '@/components/ui/layout/Container';
import { Spinner } from '@/components/ui/feedback/Spinner';
import { PriceDisplay } from '@/components/ui/domain/PriceDisplay';
import { Button } from '@/components/ui/primitives/Button';
import { Label } from '@/components/ui/primitives/Label';
import { NumberInput } from '@/components/ui/primitives/NumberInput';
import { FormField } from '@/components/ui/primitives/FormField';
import { RadioGroup, RadioCard } from '@/components/ui/primitives/RadioGroup';
import { Icon } from '@/components/ui/icons/Icon';
import { IconButton } from '@/components/ui/primitives/IconButton';
import { CartNavButton } from '@/components/ui/domain/cart/CartNavButton';
import { GlobalCartDrawer } from '@/components/ui/domain/cart/GlobalCartDrawer';
import { useT } from '@/lib/i18n/react';
import { HydratedIsland } from '@/components/HydratedIsland';
import { useGroupReservation } from './useGroupReservation';
import type { Locale } from '@/lib/i18n';
import type { GroupTierData } from '@/features/group-deal-detail/GroupDealDetailDataLoader';
import { captureCaught } from '@/lib/observability';
import { AuthGateModal } from '@/features/auth-flow/AuthGateModal';
import { formatPaymentMethodLabel } from '@/lib/format';
import { authenticatedFetch } from '@/lib/authenticated-fetch';

/** A stored payment method (minimal shape from /api/payment-methods). */
interface StoredPaymentMethod {
  id: string;
  last4: string;
  brand: string;
}

/** Shape returned by /api/group-deals/[id]/my-reservation */
interface MyReservationData {
  reservation: { id: string; status: string; quantity: number } | null;
  waitlist: { id: string; position: number } | null;
}

export interface GroupReservationFlowProps {
  /** The group deal id. */
  groupDealId: string;
  /** Deal title for display. */
  dealTitle: string;
  /** Unit price (current discounted price). */
  unitPrice: number;
  /** Original price for PriceDisplay. */
  originalPrice: number;
  /** Maximum units this customer can reserve. */
  perCustomerLimit: number;
  /** Whether tiered pricing is enabled. */
  tieredPricingEnabled?: boolean;
  /** All tiers (sorted by minParticipants). */
  tiers?: GroupTierData[];
  /** Locale for LocaleProvider. */
  locale: Locale;
}

function GroupReservationFlowInner({
  groupDealId,
  dealTitle,
  unitPrice,
  originalPrice,
  perCustomerLimit,
  tieredPricingEnabled = false,
  tiers = [],
}: Omit<GroupReservationFlowProps, 'locale'>) {
  const t = useT('group_deal');
  const tCommon = useT('common');
  const tPurchase = useT('purchase_flow');

  const [quantity, setQuantity] = useState(1);
  const [paymentMethods, setPaymentMethods] = useState<StoredPaymentMethod[]>([]);
  const [loadingMethods, setLoadingMethods] = useState(true);

  const { form, serverError, successId, onSubmit } = useGroupReservation({
    groupDealId,
    maxQuantity: perCustomerLimit,
    onSuccess: () => {
      // success state is handled by successId branch below
    },
  });

  const {
    control,
    setValue,
    formState: { errors, isSubmitting },
  } = form;

  // Keep form quantity in sync with local state
  useEffect(() => {
    setValue('quantity', quantity);
  }, [quantity, setValue]);

  // Load stored payment methods
  useEffect(() => {
    let cancelled = false;
    fetch('/api/payment-methods', { credentials: 'same-origin' })
      .then((r) => r.json() as Promise<{ ok: boolean; methods: StoredPaymentMethod[] }>)
      .then(({ ok, methods }) => {
        if (cancelled) return;
        if (ok && methods.length > 0) {
          setPaymentMethods(methods);
          const firstMethod = methods[0];
          if (firstMethod) {
            setValue('paymentMethodId', firstMethod.id);
          }
        }
      })
      .catch((err) => {
        captureCaught(err, {
          scope: 'features.group-reservation-flow.GroupReservationFlow',
          severity: 'info',
        });
        // non-fatal - user can still proceed if they enter method manually
      })
      .finally(() => {
        if (!cancelled) setLoadingMethods(false);
      });
    return () => {
      cancelled = true;
    };
  }, [setValue]);

  // Waitlist mode: check ?waitlist=1 in URL
  const [isWaitlistMode] = useState<boolean>(
    () =>
      typeof window !== 'undefined' &&
      new URLSearchParams(window.location.search).get('waitlist') === '1',
  );

  // Cancel state
  const [cancellingId, setCancellingId] = useState<string | null>(null);
  const [cancelError, setCancelError] = useState<string | null>(null);
  const [cancelDone, setCancelDone] = useState(false);

  // Poll my-reservation for existing reservation + waitlist
  const {
    data: myData,
    isError,
    refetch,
  } = useQuery<MyReservationData>({
    queryKey: ['groupReservationFlowMyReservation', groupDealId],
    queryFn: async () => {
      const res = await fetch(`/api/group-deals/${groupDealId}/my-reservation`, {
        credentials: 'same-origin',
      });
      const json = (await res.json()) as { ok: boolean } & MyReservationData;
      if (!json.ok) return { reservation: null, waitlist: null };
      return { reservation: json.reservation, waitlist: json.waitlist };
    },
    refetchInterval: 15_000,
    staleTime: 10_000,
  });

  const existingReservation = myData?.reservation ?? null;

  const handleCancelReservation = async (reservationId: string) => {
    setCancellingId(reservationId);
    setCancelError(null);
    try {
      const res = await authenticatedFetch(
        `/api/group-deals/${groupDealId}/reservations/${reservationId}`,
        {
          method: 'DELETE',
          credentials: 'same-origin',
        },
      );
      const json = (await res.json()) as { ok: boolean; error?: string };
      if (!json.ok) {
        setCancelError(json.error ?? 'Failed to cancel reservation');
      } else {
        setCancelDone(true);
      }
    } catch (err) {
      captureCaught(err, {
        scope: 'features.group-reservation-flow.GroupReservationFlow.cancel',
        severity: 'warning',
      });
      setCancelError('Failed to cancel reservation');
    } finally {
      setCancellingId(null);
    }
  };

  const navItems = useCustomerNavItems('');

  const totalAmount = unitPrice * quantity;

  // Best possible tiered price (lowest tier with most participants)
  const lastTier = tiers.at(-1);
  const bestTierPrice =
    tieredPricingEnabled && lastTier !== undefined ? lastTier.pricePerUnit : null;

  // ── Success state ──────────────────────────────────────────────────────────
  if (successId) {
    return (
      <AppShell
        mode="customer"
        topBar={<TopBar variant="customer" title={t('reserve_spot')} endSlot={<CartNavButton />} />}
        bottomNav={<BottomNav mode="customer" items={navItems} />}
        pageOverlays={<GlobalCartDrawer />}
      >
        <div>
          <Container maxWidth="sm" px="4" className="py-8">
            <div className="flex flex-col items-center gap-6 text-center">
              <div
                className="bg-success-50 flex h-16 w-16 items-center justify-center rounded-full"
                aria-hidden="true"
              >
                <Icon name="Check" size="lg" />
              </div>
              <div>
                <h1 className="text-text-primary text-[length:var(--font-size-display)] leading-tight font-[var(--font-weight-extrabold)]">
                  {t('reserve_spot')}
                </h1>
                <p className="text-text-secondary mt-2 text-sm">{t('hold_notice')}</p>
              </div>
              <PriceDisplay
                original={originalPrice * quantity}
                discounted={totalAmount}
                size="lg"
                layout="stacked"
              />
              <Button
                variant="primary"
                size="lg"
                className="w-full"
                onClick={() => {
                  window.location.href = `/group-deal/${groupDealId}`;
                }}
              >
                {tCommon('done')}
              </Button>
            </div>
          </Container>
        </div>
      </AppShell>
    );
  }

  // ── Waitlist mode: show waitlist join notice ──────────────────────────────
  if (isWaitlistMode) {
    return (
      <AppShell
        mode="customer"
        topBar={
          <TopBar
            variant="customer"
            title={dealTitle}
            startSlot={
              <IconButton
                variant="on-brand"
                size="md"
                aria-label={tCommon('back')}
                onClick={() => window.history.back()}
              >
                <Icon name="ChevronRight" size="md" mirror />
              </IconButton>
            }
            endSlot={<CartNavButton />}
          />
        }
        bottomNav={<BottomNav mode="customer" items={navItems} />}
        pageOverlays={<GlobalCartDrawer />}
      >
        <div>
          <Container maxWidth="sm" px="4" className="py-6">
            <h1 className="text-text-primary mb-4 text-[length:var(--font-size-display)] leading-tight font-[var(--font-weight-extrabold)]">
              {t('waitlist_join_title')}
            </h1>
            <div className="bg-surface-raised flex items-start gap-3 rounded-xl px-4 py-3 shadow-md">
              <Icon name="Clock" size="sm" color="muted" className="mt-0.5 shrink-0" />
              <p className="text-text-secondary text-sm">{t('join_waitlist')}</p>
            </div>
            <div className="mt-6">
              <Button
                variant="primary"
                size="lg"
                className="w-full"
                onClick={() => {
                  window.location.href = `/group-deal/${groupDealId}`;
                }}
              >
                {tCommon('back')}
              </Button>
            </div>
          </Container>
        </div>
      </AppShell>
    );
  }

  // ── Cancel-done state ─────────────────────────────────────────────────────
  if (cancelDone) {
    return (
      <AppShell
        mode="customer"
        topBar={<TopBar variant="customer" title={dealTitle} endSlot={<CartNavButton />} />}
        bottomNav={<BottomNav mode="customer" items={navItems} />}
        pageOverlays={<GlobalCartDrawer />}
      >
        <div>
          <Container maxWidth="sm" px="4" className="py-8">
            <div className="flex flex-col items-center gap-6 text-center">
              <div
                className="bg-surface-raised flex h-16 w-16 items-center justify-center rounded-full"
                aria-hidden="true"
              >
                <Icon name="Check" size="lg" />
              </div>
              <p className="text-text-primary text-sm font-medium">
                {t('cancel_reservation_success')}
              </p>
              <Button
                variant="primary"
                size="lg"
                className="w-full"
                onClick={() => {
                  window.location.href = `/group-deal/${groupDealId}`;
                }}
              >
                {tCommon('done')}
              </Button>
            </div>
          </Container>
        </div>
      </AppShell>
    );
  }

  // ── Reservation form ───────────────────────────────────────────────────────
  if (isError) {
    return (
      <ErrorState
        title={tCommon('error_loading')}
        action={
          <Button variant="secondary" size="sm" onClick={() => refetch()}>
            {tCommon('retry')}
          </Button>
        }
      />
    );
  }
  return (
    <>
      <AppShell
        mode="customer"
        topBar={
          <TopBar
            variant="customer"
            title={dealTitle}
            startSlot={
              <IconButton
                variant="on-brand"
                size="md"
                aria-label={tCommon('back')}
                onClick={() => window.history.back()}
              >
                <Icon name="ChevronRight" size="md" mirror />
              </IconButton>
            }
            endSlot={<CartNavButton />}
          />
        }
        bottomNav={<BottomNav mode="customer" items={navItems} />}
        pageOverlays={<GlobalCartDrawer />}
      >
        <div>
          <Container maxWidth="sm" px="4" className="py-6">
            <h1 className="sr-only">{t('reserve_spot')}</h1>
            {/* Hold notice */}
            <div className="bg-surface-raised mb-6 flex items-start gap-3 rounded-xl px-4 py-3 shadow-md">
              <Icon name="Info" size="sm" color="muted" className="mt-0.5 shrink-0" />
              <p className="text-text-secondary text-sm">{t('hold_notice')}</p>
            </div>

            {/* Existing reservation: show cancel affordance */}
            {existingReservation && existingReservation.status === 'HELD' && (
              <div className="mb-6 flex flex-col gap-3">
                <div className="bg-brand-primary-50 flex items-center gap-3 rounded-xl px-4 py-3">
                  <Icon name="Check" size="sm" color="primary" className="shrink-0" />
                  <p className="text-brand-primary-800 text-sm font-semibold">
                    {t('your_reservation')}
                  </p>
                </div>
                {cancelError && (
                  <p role="alert" className="text-danger-600 text-xs">
                    {cancelError}
                  </p>
                )}
                <Button
                  variant="secondary"
                  size="md"
                  className="w-full"
                  loading={cancellingId === existingReservation.id}
                  onClick={() => void handleCancelReservation(existingReservation.id)}
                >
                  {t('cancel_reservation')}
                </Button>
              </div>
            )}

            <form onSubmit={onSubmit} noValidate className="flex flex-col gap-6">
              {/* Quantity picker */}
              <div className="flex flex-col gap-1.5">
                <Label htmlFor="reservation-qty">{t('quantity')}</Label>
                <NumberInput
                  id="reservation-qty"
                  min={1}
                  max={perCustomerLimit}
                  value={quantity}
                  onChange={setQuantity}
                  invalid={!!errors.quantity}
                />
                {quantity >= perCustomerLimit && (
                  <p role="alert" className="text-warning-700 text-xs">
                    {t('qty_at_limit').replace('{{max}}', String(perCustomerLimit))}
                  </p>
                )}
                {errors.quantity && (
                  <p role="alert" className="text-danger-600 text-xs">
                    {errors.quantity.message}
                  </p>
                )}
              </div>

              {/* Price display */}
              <div className="bg-surface-raised rounded-xl px-4 py-4 shadow-md">
                <div className="flex items-center justify-between gap-4">
                  <span className="text-text-secondary text-sm">
                    {quantity} × ₪{unitPrice.toFixed(2)}
                  </span>
                  <PriceDisplay
                    original={originalPrice * quantity}
                    discounted={totalAmount}
                    size="md"
                    layout="inline"
                  />
                </div>

                {/* Best possible tiered price */}
                {bestTierPrice !== null && bestTierPrice < unitPrice && (
                  <p className="text-brand-primary-600 mt-2 text-xs">
                    {t('tier_pricing_header')} (₪{bestTierPrice.toFixed(2)})
                  </p>
                )}
              </div>

              {/* Payment method selector */}
              <FormField
                htmlFor="reservation-payment"
                label={tPurchase('payment_method')}
                error={errors.paymentMethodId?.message}
              >
                {loadingMethods ? (
                  <div className="flex h-10 items-center justify-center">
                    <Spinner size="sm" />
                  </div>
                ) : paymentMethods.length === 0 ? (
                  <a href="/profile" className="text-brand-primary-700 text-sm underline">
                    {tPurchase('add_payment_method')}
                  </a>
                ) : (
                  <Controller
                    name="paymentMethodId"
                    control={control}
                    render={({ field }) => (
                      <RadioGroup
                        value={field.value ?? ''}
                        onValueChange={field.onChange}
                        aria-label={tPurchase('payment_method')}
                      >
                        {paymentMethods.map((method) => (
                          <RadioCard
                            key={method.id}
                            value={method.id}
                            label={formatPaymentMethodLabel(method.brand, method.last4)}
                            icon={<Icon name="CreditCard" size="sm" color="muted" />}
                          />
                        ))}
                      </RadioGroup>
                    )}
                  />
                )}
              </FormField>

              {/* Server error */}
              {serverError && (
                <p role="alert" className="text-danger-600 text-sm">
                  {serverError}
                </p>
              )}

              {/* Submit */}
              <Button
                type="submit"
                variant="primary"
                size="lg"
                loading={isSubmitting}
                className="w-full"
              >
                {t('reserve_spot')}
              </Button>
            </form>
          </Container>
        </div>
      </AppShell>
      <AuthGateModal />
    </>
  );
}

/**
 * GroupReservationFlow - top-level React island.
 *
 * Provides its own QueryClientProvider via HydratedIsland (the canonical
 * SSR-hydrated island wrapper). HydratedIsland composes:
 * QueryClientProvider + HydrationBoundary + LocaleProvider + ErrorBoundary.
 */
export function GroupReservationFlow({ locale, ...rest }: GroupReservationFlowProps) {
  return (
    <HydratedIsland locale={locale}>
      <GroupReservationFlowInner {...rest} />
    </HydratedIsland>
  );
}
