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

/**
 * GroupDealDetail - React island for the Group Deal detail page (FDS §PKG-7).
 *
 * Extends the DealDetail layout with group-specific blocks:
 *  - GroupDealStatusBadge
 *  - GroupProgressBar
 *  - Tiered pricing table (when enabled)
 *  - Early bird notice (when enabled)
 *  - Bulk pickup notice (when enabled)
 *  - Cancellation policy text
 *  - CTA adapts to group state (join / waitlist / closed)
 *  - Social share button (when enabled)
 *  - "Your reservation" affordance (when user has active reservation)
 *  - Waitlist-position banner (when user is on waitlist)
 *
 * Polls /api/group-deals/[id]/status every 15 s for live participant count +
 * group state updates (refetchInterval).
 */

import { useQuery } from '@tanstack/react-query';
import { AppShell } from '@/components/ui/layout/AppShell';
import { BottomNav, useCustomerNavItems } from '@/components/ui/layout/BottomNav';
import { SiteNav } from '@/components/ui/layout/SiteNav';
import { Container } from '@/components/ui/layout/Container';
import { Breadcrumb } from '@/components/ui/layout/Breadcrumb';
import { GalleryCarousel } from '@/components/ui/domain/GalleryCarousel';
import { CountdownTimer } from '@/components/ui/domain/CountdownTimer';
import { PriceDisplay } from '@/components/ui/domain/PriceDisplay';
import { GroupProgressBar } from '@/components/ui/domain/GroupProgressBar';
import { StatusBadge } from '@/components/ui/domain/StatusBadge';
import type { GroupDealState } from '@/server/schemas/group-deal';
import { ShareButton } from '@/components/ui/domain/ShareButton';
import { Button } from '@/components/ui/primitives/Button';
import { Image } from '@/components/ui/primitives/Image';
import { Icon } from '@/components/ui/icons/Icon';
import { GlobalCartDrawer } from '@/components/ui/domain/cart/GlobalCartDrawer';
import { useT } from '@/lib/i18n/react';
import { HydratedIsland } from '@/components/HydratedIsland';
import { GlassCard } from '@/components/ui/layout/GlassCard';
import { formatImageAlt } from '@/lib/format';
import type { GroupDealDetailData } from './GroupDealDetailDataLoader';
import type { Locale } from '@/lib/i18n';
import type { GalleryImage } from '@/components/ui/domain/GalleryCarousel';

/** Shape returned by GET /api/group-deals/[id]/status */
interface GroupDealStatus {
  groupState: string;
  currentReservationCount: number;
  minGroupSize: number;
  maxGroupSize: number;
  deadline: string | null;
  extendedDeadline: string | null;
}

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

const GROUP_DEAL_STATUS_MAP: Record<
  GroupDealState,
  { tone: 'info' | 'success' | 'warning' | 'danger' | 'neutral'; labelKey: string }
> = {
  COLLECTING: { tone: 'info', labelKey: 'state_collecting' },
  THRESHOLD_MET: { tone: 'success', labelKey: 'state_threshold_met' },
  EXECUTING: { tone: 'warning', labelKey: 'state_executing' },
  PARTIAL_PENDING: { tone: 'warning', labelKey: 'state_partial_pending' },
  SUCCEEDED: { tone: 'success', labelKey: 'state_succeeded' },
  FAILED: { tone: 'danger', labelKey: 'state_failed' },
  VENDOR_HONORED: { tone: 'success', labelKey: 'state_vendor_honored' },
  EXTENDED: { tone: 'info', labelKey: 'state_extended' },
};

export interface GroupDealDetailProps {
  deal: GroupDealDetailData;
  locale: Locale;
  isGuest?: boolean;
  isAdmin?: boolean;
  isVendor?: boolean;
}

function GroupDealDetailInner({
  deal,
  isGuest = true,
  isAdmin = false,
  isVendor = false,
}: Omit<GroupDealDetailProps, 'locale'>) {
  const t = useT('group_deal');
  const tCommon = useT('common');
  const tNav = useT('nav');
  const tImage = useT('image');

  // ── Live status polling ───────────────────────────────────────────────────
  const {
    data: statusData,
    isError,
    refetch,
  } = useQuery<GroupDealStatus>({
    queryKey: ['groupDealStatus', deal.group.id],
    queryFn: async () => {
      const res = await fetch(`/api/group-deals/${deal.group.id}/status`, {
        credentials: 'same-origin',
      });
      if (!res.ok) throw new Error('status fetch failed');
      const json = (await res.json()) as { ok: boolean } & GroupDealStatus;
      return json;
    },
    refetchInterval: 15_000,
    staleTime: 10_000,
  });

  // ── User reservation / waitlist polling ──────────────────────────────────
  const { data: myData } = useQuery<MyReservationData>({
    queryKey: ['groupDealMyReservation', deal.group.id],
    queryFn: async () => {
      const res = await fetch(`/api/group-deals/${deal.group.id}/my-reservation`, {
        credentials: 'same-origin',
      });
      if (!res.ok) return { reservation: null, waitlist: null };
      const json = (await res.json()) as { ok: boolean } & MyReservationData;
      return { reservation: json.reservation, waitlist: json.waitlist };
    },
    refetchInterval: 15_000,
    staleTime: 10_000,
  });

  // Merge SSR data with live polled status (polled wins when available)
  const { group, tiers } = deal;
  const liveGroupState = statusData?.groupState ?? group.groupState;
  const liveCount = statusData?.currentReservationCount ?? group.currentReservationCount;

  const isFull = liveCount >= group.maxGroupSize;
  const isActive =
    liveGroupState === 'COLLECTING' ||
    liveGroupState === 'THRESHOLD_MET' ||
    liveGroupState === 'EXTENDED';
  const isCompleted = liveGroupState === 'SUCCEEDED' || liveGroupState === 'VENDOR_HONORED';
  const isFailed = liveGroupState === 'FAILED';

  const userReservation = myData?.reservation ?? null;
  const userWaitlist = myData?.waitlist ?? null;

  const images: GalleryImage[] = deal.images.map((img, index) => ({
    id: img.id,
    src: img.url,
    alt: formatImageAlt(deal.title, index, tImage('image_of_deal')),
  }));

  // Effective deadline: extendedDeadline takes priority over windowEnd
  const liveExtendedDeadline = statusData?.extendedDeadline ?? group.extendedDeadline;
  const deadline = liveExtendedDeadline ?? deal.windowEnd;

  // Cancellation policy text
  const cancellationText = (() => {
    switch (group.cancellationPolicy) {
      case 'LEGAL_ONLY':
        return t('cancellation_legal_window');
      case 'FLEXIBLE':
        return t('cancellation_flexible');
      case 'CUSTOM_WINDOW':
        return t('cancellation_custom_window').replace(
          '{{hours}}',
          String(group.cancellationWindowHours ?? 24),
        );
    }
  })();

  // CTA button
  const ctaButton = (() => {
    if (isCompleted) {
      return (
        <Button variant="secondary" size="lg" disabled className="w-full">
          {t('state_succeeded')}
        </Button>
      );
    }
    if (isFailed) {
      return (
        <Button variant="secondary" size="lg" disabled className="w-full">
          {t('state_failed')}
        </Button>
      );
    }
    if (isFull) {
      return (
        <Button
          variant="primary"
          size="lg"
          className="w-full"
          onClick={() => {
            window.location.href = `/group-deal/${deal.id}/buy?waitlist=1`;
          }}
        >
          {t('join_waitlist')}
        </Button>
      );
    }
    if (isActive) {
      return (
        <Button
          variant="primary"
          size="lg"
          className="w-full"
          onClick={() => {
            window.location.href = `/group-deal/${deal.id}/buy`;
          }}
        >
          {t('join_group')}
        </Button>
      );
    }
    return (
      <Button variant="secondary" size="lg" disabled className="w-full">
        {t('deadline_passed')}
      </Button>
    );
  })();

  const navItems = useCustomerNavItems('');

  /** Shared group deal content used in both mobile and desktop layouts. */
  const dealDetails = (
    <div className="flex flex-col gap-4">
      {/* Status badge + timer row */}
      <div className="flex flex-wrap items-center gap-3">
        <StatusBadge
          state={liveGroupState as GroupDealState}
          map={GROUP_DEAL_STATUS_MAP}
          ns="group_deal"
        />
        {deadline && isActive && (
          <div data-countdown className="flex items-center gap-1.5">
            <Icon name="Clock" size="sm" color="muted" />
            <CountdownTimer endIso={deadline} className="text-sm" />
          </div>
        )}
      </div>

      {/* Vendor link */}
      <a
        href={`/business/${deal.vendor.slug}`}
        data-user-content
        className="text-brand-primary-700 hover:text-brand-primary-800 focus-visible:ring-brand-primary-500 text-sm font-medium underline focus-visible:ring-2 focus-visible:outline-none"
      >
        {deal.vendor.displayName}
      </a>

      {/* Deal title */}
      <h1
        data-user-content
        className="text-text-primary text-[length:var(--font-size-display)] leading-tight font-[var(--font-weight-extrabold)]"
      >
        {deal.title}
      </h1>

      {/* Description */}
      {deal.description && (
        <p data-user-content className="text-text-secondary text-base leading-normal">
          {deal.description}
        </p>
      )}

      {/* Early bird notice */}
      {group.earlyBirdEnabled && group.earlyBirdSlots !== null && (
        <div className="bg-surface-raised flex items-center gap-2 rounded-xl px-3 py-2 shadow-md">
          <Icon name="Star" size="sm" />
          <div className="flex flex-col">
            <span className="text-warning-700 text-xs font-bold">{t('early_bird_badge')}</span>
            {group.earlyBirdDiscountPercent !== null && (
              <span className="text-warning-600 text-xs">
                {t('early_bird_discount').replace(
                  '{{percent}}',
                  String(group.earlyBirdDiscountPercent),
                )}
              </span>
            )}
            <span className="text-warning-600 text-xs">
              {t('early_bird_remaining').replace(
                '{{count}}',
                String(Math.max(0, group.earlyBirdSlots - group.currentReservationCount)),
              )}
            </span>
          </div>
        </div>
      )}

      {/* Progress bar */}
      <GroupProgressBar
        current={liveCount}
        minTarget={group.minGroupSize}
        maxTarget={group.maxGroupSize}
        tiers={tiers}
        showMilestones
      />

      {/* Tiered pricing table */}
      {group.tieredPricingEnabled && tiers.length > 0 && (
        <div className="bg-surface-raised rounded-xl p-4 shadow-md">
          <p className="text-text-primary mb-3 text-sm font-semibold">{t('tier_pricing_header')}</p>
          <div className="flex flex-col gap-2">
            {tiers.map((tier, i) => (
              <div
                key={tier.id}
                className={[
                  'flex items-center justify-between rounded-md px-3 py-2',
                  liveCount >= tier.minParticipants ? 'bg-brand-primary-50' : 'bg-surface-base',
                ].join(' ')}
              >
                <span className="text-text-secondary text-xs">
                  {t('tier_row')
                    .replace('{{participants}}', String(tier.minParticipants))
                    .replace('{{price}}', String(tier.pricePerUnit))}
                </span>
                {i === 0 && (
                  <span className="text-brand-primary-700 text-xs font-medium">
                    {t('current_tier')}
                  </span>
                )}
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Price display */}
      <PriceDisplay
        original={deal.originalPrice}
        discounted={deal.discountedPrice}
        size="lg"
        layout="inline"
      />

      {/* Hold notice */}
      {isActive && (
        <div className="bg-surface-raised flex items-start gap-2 rounded-xl px-3 py-2 shadow-md">
          <Icon name="Info" size="sm" color="muted" className="mt-0.5 shrink-0" />
          <p className="text-text-secondary text-xs">{t('hold_notice')}</p>
        </div>
      )}

      {/* Bulk pickup notice */}
      {group.bulkPickupEnabled && group.bulkPickupDetails && (
        <div className="bg-surface-raised flex items-start gap-2 rounded-xl px-3 py-2 shadow-md">
          <Icon name="ShoppingBag" size="sm" color="muted" className="mt-0.5 shrink-0" />
          <p data-user-content className="text-text-secondary text-xs">
            {t('bulk_pickup_notice').replace('{{details}}', group.bulkPickupDetails)}
          </p>
        </div>
      )}

      {/* Cancellation policy */}
      <p className="text-text-muted text-xs">{cancellationText}</p>

      {/* "Your reservation" affordance — shown when user has active reservation */}
      {userReservation && userReservation.status !== 'CANCELLED' && (
        <div className="bg-brand-primary-50 flex items-center gap-3 rounded-xl px-4 py-3 shadow-sm">
          <Icon name="Check" size="sm" color="primary" className="shrink-0" />
          <div className="flex min-w-0 flex-1 flex-col gap-0.5">
            <p className="text-brand-primary-800 text-sm font-semibold">{t('your_reservation')}</p>
            <a
              href={`/group-deal/${deal.id}/buy`}
              className="text-brand-primary-700 text-xs underline"
            >
              {t('view_reservation')}
            </a>
          </div>
        </div>
      )}

      {/* Waitlist-position banner */}
      {userWaitlist && (
        <div className="bg-surface-raised flex items-center gap-3 rounded-xl px-4 py-3 shadow-sm">
          <Icon name="Clock" size="sm" color="muted" className="shrink-0" />
          <p className="text-text-secondary text-sm">
            {t('waitlist_position').replace('{{position}}', String(userWaitlist.position))}
          </p>
        </div>
      )}

      {/* CTA */}
      {ctaButton}

      {/* Social sharing */}
      {group.socialSharingEnabled && (
        <div className="flex flex-col gap-2">
          <ShareButton
            shareParams={{
              targetUrl:
                typeof window !== 'undefined' ? window.location.href : `/group-deal/${deal.id}`,
              dealId: deal.id,
            }}
            title={deal.title}
          />
          {group.socialSharingReward && (
            <p className="text-text-muted text-center text-xs">
              {t('social_share_reward').replace('{{reward}}', group.socialSharingReward)}
            </p>
          )}
        </div>
      )}
    </div>
  );

  if (isError) {
    return (
      <ErrorState
        title={tCommon('error_loading')}
        action={
          <Button variant="secondary" size="sm" onClick={() => refetch()}>
            {tCommon('retry')}
          </Button>
        }
      />
    );
  }
  return (
    <AppShell
      mode="customer"
      desktopTopBar={
        <SiteNav
          variant="desktop"
          currentPath={`/group-deal/${deal.id}`}
          isGuest={isGuest}
          isAdmin={isAdmin}
          isVendor={isVendor}
        />
      }
      topBar={
        <SiteNav
          variant="mobile"
          title={deal.title}
          currentPath={`/group-deal/${deal.id}`}
          isGuest={isGuest}
          isAdmin={isAdmin}
          isVendor={isVendor}
        />
      }
      bottomNav={<BottomNav mode="customer" items={navItems} />}
      pageOverlays={<GlobalCartDrawer />}
    >
      <div>
        <Breadcrumb
          items={[
            { label: tNav('home'), href: '/' },
            { label: tNav('group_deals'), href: '/deals/group' },
            { label: deal.vendor.displayName, href: `/business/${deal.vendor.slug}` },
            { label: deal.title },
          ]}
        />
        {/* Mobile layout: stacked */}
        <div className="lg:hidden">
          {images.length > 0 && (
            <GalleryCarousel images={images} variant="vendor" className="w-full" prioritizeFirst />
          )}
          <div className="px-4 py-4">{dealDetails}</div>
        </div>

        {/* Desktop layout: two-column */}
        <div className="hidden lg:block">
          <Container maxWidth="4xl" px="8" className="py-8">
            <div className="flex items-start gap-10">
              {/* Left: vertical image stack */}
              {images.length > 0 && (
                <div className="flex w-2/5 shrink-0 flex-col gap-3">
                  {images.map((img, i) => (
                    <Image
                      key={img.id}
                      src={img.src}
                      alt={img.alt}
                      loading={i === 0 ? 'eager' : 'lazy'}
                      fetchpriority={i === 0 ? 'high' : 'auto'}
                      className="w-full rounded-xl object-cover"
                    />
                  ))}
                </div>
              )}

              {/* Right: deal info in glass panel */}
              <div className="min-w-0 flex-1">
                <GlassCard tone="surface" padding="lg" align="start" className="rounded-2xl">
                  {dealDetails}
                </GlassCard>
              </div>
            </div>
          </Container>
        </div>
      </div>
    </AppShell>
  );
}

/**
 * GroupDealDetail - top-level React island.
 *
 * Provides its own QueryClientProvider via HydratedIsland (the canonical
 * SSR-hydrated island wrapper). HydratedIsland composes:
 * QueryClientProvider + HydrationBoundary + LocaleProvider + ErrorBoundary.
 */
export function GroupDealDetail({
  deal,
  locale,
  isGuest,
  isAdmin,
  isVendor,
}: GroupDealDetailProps) {
  return (
    <HydratedIsland locale={locale}>
      <GroupDealDetailInner deal={deal} isGuest={isGuest} isAdmin={isAdmin} isVendor={isVendor} />
    </HydratedIsland>
  );
}
