/**
 * WishlistPage — customer wishlist page.
 *
 * - Fetches /api/wishlist via React Query.
 * - Shows Spinner while loading.
 * - Shows EmptyState with a browse CTA when the list is empty.
 * - Shows a simple deal card list when items are present.
 * - Wraps in WishlistProvider so child components can toggle saved state.
 */

'use client';

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useT } from '@/lib/i18n/react';
import { Container } from '@/components/ui/layout/Container';
import { HydratedIsland } from '@/components/HydratedIsland';
import { AppShell } from '@/components/ui/layout/AppShell';
import { BottomNav, useCustomerNavItems } from '@/components/ui/layout/BottomNav';
import { SiteNav } from '@/components/ui/layout/SiteNav';
import { Spinner } from '@/components/ui/feedback/Spinner';
import { EmptyState } from '@/components/ui/feedback/EmptyState';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import { NoDeals } from '@/components/ui/feedback/EmptyState/illustrations';
import { Button } from '@/components/ui/primitives/Button';
import { Switch } from '@/components/ui/primitives/Switch/Switch';
import { Label } from '@/components/ui/primitives/Label';
import { Icon } from '@/components/ui/icons/Icon';
import { WishlistProvider } from './WishlistContext.js';
import { getCsrfToken } from '@/lib/csrf';
import type { WishlistRow } from '@/server/db/queries/wishlist.js';
import type { Locale } from '@/lib/i18n';

// ─── Props ─────────────────────────────────────────────────────────────────

export interface WishlistPageProps {
  locale: Locale;
  isGuest?: boolean;
  isAdmin?: boolean;
  isVendor?: boolean;
  wishlistedDealIds?: string[];
  initialWishlist?: WishlistRow[];
}

// ─── Inner component (needs QueryClient + i18n context) ────────────────────

function WishlistPageInner({
  isGuest = true,
  isAdmin = false,
  isVendor = false,
  wishlistedDealIds = [],
  initialWishlist,
}: Omit<WishlistPageProps, 'locale'>) {
  const t = useT('wishlist');

  const qc = useQueryClient();

  const {
    data: items = [],
    isLoading,
    isError,
  } = useQuery<WishlistRow[]>({
    queryKey: ['wishlist'],
    queryFn: async () => {
      const res = await fetch('/api/wishlist');
      if (!res.ok) throw new Error('Failed to fetch wishlist');
      const json = (await res.json()) as { ok: boolean; items: WishlistRow[] };
      return json.items;
    },
    initialData: initialWishlist,
    staleTime: 0,
  });

  const toggleMutation = useMutation({
    mutationFn: async (dealId: string) => {
      const csrf = getCsrfToken();
      const res = await fetch('/api/wishlist/toggle', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'x-csrf-token': csrf },
        body: JSON.stringify({ dealId }),
      });
      if (!res.ok) throw new Error('toggle failed');
      return res.json() as Promise<{ ok: boolean; saved: boolean }>;
    },
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: ['wishlist'] });
    },
  });

  const notifyMutation = useMutation({
    mutationFn: async ({ dealId, notify }: { dealId: string; notify: boolean }) => {
      const csrf = getCsrfToken();
      const res = await fetch('/api/wishlist/notify', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json', 'x-csrf-token': csrf },
        body: JSON.stringify({ dealId, notify }),
      });
      if (!res.ok) throw new Error('notify update failed');
    },
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: ['wishlist'] });
    },
  });

  const notifyAllMutation = useMutation({
    mutationFn: async (notify: boolean) => {
      const csrf = getCsrfToken();
      const res = await fetch('/api/wishlist/notify-all', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json', 'x-csrf-token': csrf },
        body: JSON.stringify({ notify }),
      });
      if (!res.ok) throw new Error('notify-all update failed');
    },
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: ['wishlist'] });
    },
  });

  const navItems = useCustomerNavItems('/wishlist');

  return (
    <WishlistProvider initialDealIds={wishlistedDealIds} isAuthenticated>
      <AppShell
        mode="customer"
        topBar={
          <SiteNav
            variant="mobile"
            title={t('page_title')}
            currentPath="/wishlist"
            isGuest={isGuest}
            isAdmin={isAdmin}
            isVendor={isVendor}
          />
        }
        desktopTopBar={
          <SiteNav
            variant="desktop"
            currentPath="/wishlist"
            isGuest={isGuest}
            isAdmin={isAdmin}
            isVendor={isVendor}
          />
        }
        bottomNav={<BottomNav mode="customer" items={navItems} />}
      >
        <Container maxWidth="4xl" px="6">
          <main id="main" className="mx-auto max-w-2xl py-6">
            <h1 className="text-text-primary mb-6 text-2xl font-bold">{t('page_title')}</h1>

            {isError && (
              <div role="alert" className="mb-4">
                <InlineNotice tone="danger" description={t('empty_description')} />
              </div>
            )}

            {isLoading ? (
              <div className="flex justify-center py-12">
                <Spinner size="lg" />
              </div>
            ) : items.length === 0 ? (
              <EmptyState
                illustration={<NoDeals />}
                title={t('empty_title')}
                description={t('empty_description')}
                action={
                  <Button asChild variant="primary" size="md" data-component="ui-button">
                    <a href="/search">{t('browse_deals_cta')}</a>
                  </Button>
                }
              />
            ) : (
              <>
                {/* Notify-all toggle */}
                <div className="mb-4 flex items-center justify-between gap-3">
                  <Label htmlFor="wishlist-notify-all" className="text-text-secondary text-sm">
                    {t('notify_all_label')}
                  </Label>
                  <Switch
                    id="wishlist-notify-all"
                    checked={items.some((i) => i.notify)}
                    onCheckedChange={(v) => notifyAllMutation.mutate(v)}
                    disabled={notifyAllMutation.isPending}
                    aria-label={t('notify_all_label')}
                  />
                </div>
                <ul className="divide-border-subtle divide-y">
                  {items.map((item) => (
                    <li key={item.id} className="py-4">
                      <div className="hover:bg-surface-raised -mx-2 flex items-center justify-between gap-4 rounded-md px-2 py-1">
                        <a
                          href={item.deal.heSlug ? `/deals/${item.deal.heSlug}` : '/deals'}
                          className="focus-visible:ring-brand-primary-500 min-w-0 flex-1 focus-visible:ring-2 focus-visible:ring-offset-2"
                        >
                          <p className="text-text-primary truncate font-medium">
                            {item.deal.title}
                          </p>
                          <p className="text-text-secondary mt-0.5 text-sm">
                            {item.deal.vendorName}
                          </p>
                        </a>
                        <span className="text-brand-primary-700 shrink-0 font-semibold">
                          ₪{item.deal.discountedPrice}
                        </span>
                        <Switch
                          id={`wl-notify-${item.dealId}`}
                          checked={item.notify}
                          onCheckedChange={(v) =>
                            notifyMutation.mutate({ dealId: item.dealId, notify: v })
                          }
                          disabled={notifyMutation.isPending}
                          aria-label={t('notify_label')}
                        />
                        <Button
                          variant="ghost"
                          size="sm"
                          aria-label={t('remove_from_wishlist')}
                          onClick={() => toggleMutation.mutate(item.dealId)}
                          disabled={toggleMutation.isPending}
                        >
                          <Icon name="Heart" size="sm" aria-hidden />
                        </Button>
                      </div>
                    </li>
                  ))}
                </ul>
              </>
            )}
          </main>
        </Container>
      </AppShell>
    </WishlistProvider>
  );
}

// ─── Exported page component ───────────────────────────────────────────────

export function WishlistPage({
  locale,
  isGuest = true,
  isAdmin = false,
  isVendor = false,
  wishlistedDealIds = [],
  initialWishlist,
}: WishlistPageProps) {
  return (
    <HydratedIsland locale={locale}>
      <WishlistPageInner
        isGuest={isGuest}
        isAdmin={isAdmin}
        isVendor={isVendor}
        wishlistedDealIds={wishlistedDealIds}
        initialWishlist={initialWishlist}
      />
    </HydratedIsland>
  );
}
