/**
 * MyPurchases - user's purchase history screen (FDS §4.8).
 *
 * Composes:
 * - AppShell + TopBar (customer)
 * - SummaryBar (saved ₪X · X purchases · X businesses)
 * - Tabs: Active | History
 * - ListRow per purchase
 * - Active rows have a QR button (opens Drawer with QrCodeCard)
 * - History rows show price paid
 */

'use client';

import { useState } from 'react';
import { useT, useLocale } from '@/lib/i18n/react';
import { formatCurrency, formatDate, formatDateTime } from '@/lib/format';
import { AppShell } from '@/components/ui/layout/AppShell';
import { BottomNav, useCustomerNavItems } from '@/components/ui/layout/BottomNav';
import { Container } from '@/components/ui/layout/Container';
import { Breadcrumb } from '@/components/ui/layout/Breadcrumb';
import { Tabs } from '@/components/ui/layout/Tabs';
import { QrCodeCard } from '@/components/ui/domain/QrCodeCard';
import { VoucherCardFan } from '@/components/ui/domain/VoucherCardFan';
import {
  Drawer,
  DrawerTrigger,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerClose,
} from '@/components/ui/overlays/Drawer';
import { Button } from '@/components/ui/primitives/Button';
import { GlassCard } from '@/components/ui/layout/GlassCard';
import { Icon } from '@/components/ui/icons/Icon';
import { IconButton } from '@/components/ui/primitives/IconButton';
import { SiteNav } from '@/components/ui/layout/SiteNav';
import { GlobalCartDrawer } from '@/components/ui/domain/cart/GlobalCartDrawer';
import { Spinner } from '@/components/ui/feedback/Spinner';
import { EmptyState } from '@/components/ui/feedback/EmptyState';
import { NoOrders } from '@/components/ui/feedback/EmptyState/illustrations';
import { ErrorState } from '@/components/ui/feedback/ErrorState';
import { Pagination } from '@/components/ui/primitives/Pagination';
import { Image } from '@/components/ui/primitives/Image';
import { Pill } from '@/components/ui/primitives/Pill';
import { enumLabel } from '@/lib/enums/define-enum';
import { useMyPurchases } from './useMyPurchases';
import type { PurchaseListItem } from './useMyPurchases';

const PAGE_SIZE = 10;

// ─── Active tab row ───────────────────────────────────────────────────────────

interface ActiveRowProps {
  purchase: PurchaseListItem;
}

function ActiveRow({ purchase }: ActiveRowProps) {
  const t = useT('my_purchases');
  const tQr = useT('qr_redeem');
  const { locale } = useLocale();
  const unredeemedVouchers = (purchase.vouchers ?? []).filter((v) => v.state === 'UNREDEEMED');

  return (
    <Drawer>
      <div className="flex items-center gap-3 py-3">
        <DrawerTrigger asChild>
          <Button
            variant="secondary"
            size="sm"
            iconStart={<Icon name="QrCode" size="sm" />}
            aria-label={t('show_qr')}
            className="shrink-0"
          >
            {t('show_qr')}
          </Button>
        </DrawerTrigger>

        <a
          href={`/purchases/${purchase.id}`}
          className="flex min-w-0 flex-1 items-center gap-3"
          aria-label={purchase.dealTitle}
        >
          <div className="bg-surface-raised size-10 shrink-0 overflow-hidden rounded-md">
            {purchase.dealImageUrl ? (
              <Image
                src={purchase.dealImageUrl}
                alt={purchase.dealTitle}
                variant="thumb"
                width={40}
                height={40}
                loading="lazy"
                className="h-full w-full"
              />
            ) : (
              <div className="flex h-full w-full items-center justify-center">
                <Icon name="ShoppingBag" size="sm" color="muted" />
              </div>
            )}
          </div>

          <div className="min-w-0 flex-1">
            <p className="text-text-primary truncate text-sm font-medium">{purchase.dealTitle}</p>
            <p className="text-text-secondary mt-0.5 truncate text-xs">{purchase.businessName}</p>
            {purchase.expiresAt && (
              <p className="text-text-muted mt-0.5 text-xs">
                {t('valid_until')} {formatDate(purchase.expiresAt, locale)}
              </p>
            )}
          </div>

          {purchase.createdAt && (
            <div className="hidden shrink-0 text-end sm:block">
              <p className="text-text-secondary text-xs">
                {formatDateTime(purchase.createdAt, locale)}
              </p>
            </div>
          )}

          <div className="shrink-0 text-end">
            <p className="text-text-primary text-sm font-semibold">
              {formatCurrency(parseFloat(purchase.amountPaid), locale)}
            </p>
            {purchase.createdAt && (
              <p className="text-text-secondary mt-0.5 text-xs sm:hidden">
                {formatDateTime(purchase.createdAt, locale)}
              </p>
            )}
          </div>
        </a>

        <a
          href={`/cases/new?purchase=${purchase.id}`}
          className="text-brand-primary-700 hover:text-brand-primary-900 shrink-0 text-xs font-medium underline"
        >
          {t('report_problem')}
        </a>
      </div>

      <DrawerContent side="bottom">
        <DrawerHeader>
          <DrawerTitle>{tQr('instruction')}</DrawerTitle>
        </DrawerHeader>
        <DrawerClose asChild>
          <IconButton
            variant="ghost"
            size="sm"
            className="text-text-muted absolute end-4 top-4"
            aria-label={tQr('close')}
          >
            <Icon name="X" size="sm" />
          </IconButton>
        </DrawerClose>
        <div className="flex flex-col items-center gap-4 px-6 pb-8">
          {unredeemedVouchers.length > 1 ? (
            <VoucherCardFan vouchers={unredeemedVouchers} className="w-full max-w-sm" />
          ) : (
            <QrCodeCard
              qrPngUrl={purchase.qrPngUrl ?? ''}
              expiryIso={purchase.expiresAt}
              className="w-full max-w-xs"
            />
          )}
        </div>
        <div className="px-6 pb-4 text-center">
          <p className="text-text-primary text-sm font-semibold">{purchase.dealTitle}</p>
          <p className="text-text-secondary mt-0.5 text-xs">{purchase.businessName}</p>
        </div>
      </DrawerContent>
    </Drawer>
  );
}

// ─── History tab row ──────────────────────────────────────────────────────────

interface HistoryRowProps {
  purchase: PurchaseListItem;
  locale: 'he' | 'en';
}

function HistoryRow({ purchase, locale }: HistoryRowProps) {
  const t = useT('my_purchases');

  const statusParts: string[] = [];
  if (purchase.redeemedAt) {
    statusParts.push(`${t('redeemed_at')} ${formatDate(purchase.redeemedAt, locale)}`);
  } else if (purchase.redemptionStatus === 'CANCELLED') {
    statusParts.push(t('status_cancelled'));
  } else if (purchase.paymentStatus === 'REFUNDED') {
    statusParts.push(t('status_refunded'));
  } else if (purchase.redemptionStatus === 'EXPIRED') {
    statusParts.push(`${t('expired_at')} ${formatDate(purchase.expiresAt, locale)}`);
  }

  return (
    <a
      href={`/purchases/${purchase.id}`}
      className="flex items-center gap-3 py-3"
      aria-label={purchase.dealTitle}
    >
      <div className="bg-surface-raised size-10 shrink-0 overflow-hidden rounded-md">
        {purchase.dealImageUrl ? (
          <Image
            src={purchase.dealImageUrl}
            alt={purchase.dealTitle}
            variant="thumb"
            width={40}
            height={40}
            loading="lazy"
            className="h-full w-full"
          />
        ) : (
          <div className="flex h-full w-full items-center justify-center">
            <Icon name="ShoppingBag" size="sm" color="muted" />
          </div>
        )}
      </div>

      <div className="min-w-0 flex-1">
        <div className="flex flex-wrap items-center gap-2">
          <p className="text-text-primary truncate text-sm font-medium">{purchase.dealTitle}</p>
          {purchase.redemptionStatus === 'CANCELLED' && (
            <Pill tone="neutral" size="sm">
              {enumLabel('purchase_status', 'CANCELLED', locale, 'customer')}
            </Pill>
          )}
        </div>
        <p className="text-text-secondary mt-0.5 truncate text-xs">{purchase.businessName}</p>
        {statusParts.length > 0 && purchase.redemptionStatus !== 'CANCELLED' && (
          <p className="text-text-muted mt-0.5 text-xs">{statusParts.join(' · ')}</p>
        )}
      </div>

      {purchase.createdAt && (
        <div className="hidden shrink-0 text-end sm:block">
          <p className="text-text-secondary text-xs">
            {formatDateTime(purchase.createdAt, locale)}
          </p>
        </div>
      )}

      <div className="shrink-0 text-end">
        <p className="text-text-primary text-sm font-semibold">
          {formatCurrency(parseFloat(purchase.amountPaid), locale)}
        </p>
        {purchase.createdAt && (
          <p className="text-text-secondary mt-0.5 text-xs sm:hidden">
            {formatDateTime(purchase.createdAt, locale)}
          </p>
        )}
      </div>
    </a>
  );
}

// ─── MyPurchases ─────────────────────────────────────────────────────────────

/**
 * MyPurchases - full purchases screen.
 *
 * @example
 * ```tsx
 * <MyPurchases />
 * ```
 */
function MyPurchasesInner({
  isAdmin = false,
  isVendor = false,
  userName,
}: {
  isAdmin?: boolean;
  isVendor?: boolean;
  userName?: string;
}) {
  const t = useT('my_purchases');
  const tError = useT('error');
  const tCommon = useT('common');
  const tNav = useT('nav');
  const { locale } = useLocale();
  const { data, isLoading, isError, refetch } = useMyPurchases();

  const [activePage, setActivePage] = useState(1);
  const [historyPage, setHistoryPage] = useState(1);

  const navItems = useCustomerNavItems('/purchases');

  const desktopTopBar = (
    <SiteNav
      variant="desktop"
      currentPath="/purchases"
      isGuest={false}
      isAdmin={isAdmin}
      userName={userName}
    />
  );
  const mobileTopBar = (
    <SiteNav
      variant="mobile"
      title={t('title')}
      currentPath="/purchases"
      isGuest={false}
      isAdmin={isAdmin}
      isVendor={isVendor}
    />
  );

  if (isLoading) {
    return (
      <AppShell
        mode="customer"
        desktopTopBar={desktopTopBar}
        topBar={mobileTopBar}
        bottomNav={<BottomNav mode="customer" items={navItems} />}
        pageOverlays={<GlobalCartDrawer />}
      >
        <div className="flex items-center justify-center py-20">
          <Spinner size="lg" label={tCommon('loading')} />
        </div>
      </AppShell>
    );
  }

  if (isError || !data) {
    return (
      <AppShell
        mode="customer"
        desktopTopBar={desktopTopBar}
        topBar={mobileTopBar}
        bottomNav={<BottomNav mode="customer" items={navItems} />}
        pageOverlays={<GlobalCartDrawer />}
      >
        <div className="px-4 py-8">
          <ErrorState
            title={tError('title')}
            description={tError('description')}
            action={
              <Button variant="primary" size="sm" onClick={() => void refetch()}>
                {tCommon('retry')}
              </Button>
            }
          />
        </div>
      </AppShell>
    );
  }

  const { active, history, totalSavings, businessCount } = data;
  const hasBusinessCount = Number.isInteger(businessCount);

  const activeTotalPages = Math.max(1, Math.ceil(active.length / PAGE_SIZE));
  const historyTotalPages = Math.max(1, Math.ceil(history.length / PAGE_SIZE));
  const activeSlice = active.slice((activePage - 1) * PAGE_SIZE, activePage * PAGE_SIZE);
  const historySlice = history.slice((historyPage - 1) * PAGE_SIZE, historyPage * PAGE_SIZE);

  const tabs = [
    { value: 'active', label: t('tab_active'), count: active.length },
    { value: 'history', label: t('tab_history'), count: history.length },
  ];

  const panels = {
    active:
      active.length === 0 ? (
        <EmptyState
          illustration={<NoOrders />}
          title={t('empty_active_title')}
          description={t('empty_active_description')}
          className="py-16"
          action={
            <Button
              variant="primary"
              size="sm"
              onClick={() => {
                window.location.href = '/';
              }}
            >
              {t('browse_deals')}
            </Button>
          }
        />
      ) : (
        <>
          <ul className="divide-border-default divide-y px-4" aria-label={t('tab_active')}>
            {activeSlice.map((p) => (
              <li key={p.id}>
                <ActiveRow purchase={p} />
              </li>
            ))}
          </ul>
          <Pagination
            page={activePage}
            totalPages={activeTotalPages}
            onPageChange={setActivePage}
            className="py-6"
          />
        </>
      ),
    history:
      history.length === 0 ? (
        <EmptyState
          illustration={<NoOrders />}
          title={t('empty_history_title')}
          description={t('empty_history_description')}
          className="py-16"
        />
      ) : (
        <>
          <ul className="divide-border-default divide-y px-4" aria-label={t('tab_history')}>
            {historySlice.map((p) => (
              <li key={p.id}>
                <HistoryRow purchase={p} locale={locale} />
              </li>
            ))}
          </ul>
          <Pagination
            page={historyPage}
            totalPages={historyTotalPages}
            onPageChange={setHistoryPage}
            className="py-6"
          />
        </>
      ),
  };

  return (
    <AppShell
      mode="customer"
      desktopTopBar={desktopTopBar}
      topBar={mobileTopBar}
      bottomNav={<BottomNav mode="customer" items={navItems} />}
    >
      {/* Desktop hero */}
      <div className="hidden lg:block">
        <style>{`
          @keyframes multideal-fade-up {
            from { opacity: 0; transform: translateY(14px); }
            to   { opacity: 1; transform: translateY(0); }
          }
          .multideal-stat-card {
            transition: transform var(--duration-fast) ease;
          }
          .multideal-stat-card:hover {
            transform: translateY(-4px);
          }
          @media (prefers-reduced-motion: reduce) {
            .multideal-no-motion { animation: none !important; }
            .multideal-stat-card { transition: none !important; }
          }
        `}</style>
        <div className="bg-brand-primary-700 relative flex min-h-56 items-end overflow-hidden">
          <Container maxWidth="4xl" px="8" className="relative w-full py-8">
            <h1
              className="text-text-inverse text-[length:var(--font-size-display)] leading-tight font-[var(--font-weight-extrabold)]"
              style={{ animation: 'multideal-fade-up 0.5s ease-out both' }}
            >
              {t('title')}
            </h1>
            <div className={`mt-6 grid gap-4 ${hasBusinessCount ? 'grid-cols-3' : 'grid-cols-2'}`}>
              {[
                {
                  value: formatCurrency(totalSavings, locale),
                  label: t('summary_saved'),
                  delay: '0.1s',
                },
                {
                  value: String(active.length + history.length),
                  label: t('summary_count'),
                  delay: '0.2s',
                },
                ...(hasBusinessCount
                  ? [
                      {
                        value: String(businessCount),
                        label: t('summary_businesses'),
                        delay: '0.3s',
                      },
                    ]
                  : []),
              ].map(({ value, label, delay }) => (
                <GlassCard
                  key={label}
                  padding="md"
                  align="center"
                  className="multideal-no-motion multideal-stat-card hover:shadow-[var(--shadow-elevation-3)]"
                  style={{
                    animation: `multideal-fade-up 0.5s ease-out ${delay} both`,
                  }}
                >
                  <p className="text-text-inverse text-2xl font-bold">{value}</p>
                  <p className="text-brand-primary-200 mt-1 text-sm">{label}</p>
                </GlassCard>
              ))}
            </div>
          </Container>
        </div>
      </div>

      <div>
        <Breadcrumb items={[{ label: tNav('home'), href: '/' }, { label: tNav('purchases') }]} />
        {/* Mobile layout */}
        <div className="lg:hidden" data-purchases-layout="mobile">
          <div
            className={`border-border-default bg-surface-raised mx-4 mt-4 grid gap-2 rounded-xl border px-3 py-3 ${hasBusinessCount ? 'grid-cols-3' : 'grid-cols-2'}`}
          >
            <div className="text-center">
              <p className="text-text-primary text-sm font-bold">
                {formatCurrency(totalSavings, locale)}
              </p>
              <p className="text-text-muted mt-0.5 text-xs">{t('summary_saved')}</p>
            </div>
            <div className="text-center">
              <p className="text-text-primary text-sm font-bold">
                {active.length + history.length}
              </p>
              <p className="text-text-muted mt-0.5 text-xs">{t('summary_count')}</p>
            </div>
            {hasBusinessCount && (
              <div className="text-center">
                <p className="text-text-primary text-sm font-bold">{businessCount}</p>
                <p className="text-text-muted mt-0.5 text-xs">{t('summary_businesses')}</p>
              </div>
            )}
          </div>
          <Tabs
            items={tabs}
            defaultValue="active"
            mode="customer"
            panels={panels}
            className="mt-4"
          />
        </div>

        {/* Desktop layout */}
        <div className="hidden lg:block" data-purchases-layout="desktop">
          <Container maxWidth="4xl" px="8" className="py-8">
            <Tabs items={tabs} defaultValue="active" mode="customer" panels={panels} />
          </Container>
        </div>
      </div>
    </AppShell>
  );
}

import { HydratedIsland } from '@/components/HydratedIsland';
import type { DehydratedState } from '@tanstack/react-query';
import type { Locale } from '@/lib/i18n';

/**
 * MyPurchases - exported island component.
 * Self-wraps with HydratedIsland so that useQuery inside MyPurchasesInner
 * is always called within a QueryClientProvider, even during Astro SSR
 * slot serialization with client:only="react".
 *
 * `locale` (server-resolved from Astro frontmatter) seeds LocaleProvider so
 * SSR + first hydration render use the same locale dictionary as the page
 * shell — prevents React #418 hydration mismatch when the user's cookie
 * locale differs from the store default ('he').
 */
export function MyPurchases({
  isAdmin = false,
  isVendor = false,
  userName,
  dehydratedState,
  locale,
}: {
  isAdmin?: boolean;
  isVendor?: boolean;
  userName?: string;
  dehydratedState?: DehydratedState;
  locale?: Locale;
} = {}) {
  return (
    <HydratedIsland dehydratedState={dehydratedState} locale={locale}>
      <MyPurchasesInner isAdmin={isAdmin} isVendor={isVendor} userName={userName} />
    </HydratedIsland>
  );
}
