/**
 * CaseList — shows customer's or vendor's transaction cases.
 *
 * Renders inside the standard customer chrome (AppShell + SiteNav + BottomNav)
 * so /cases gets the same top navigation header as /favorites and /profile.
 */

'use client';

import { useQuery } from '@tanstack/react-query';
import { useT, useLocale } from '@/lib/i18n/react';
import type { StringBundle } from '@/lib/i18n/types';
import { AppShell } from '@/components/ui/layout/AppShell';
import { BottomNav, useCustomerNavItems } from '@/components/ui/layout/BottomNav';
import { SiteNav } from '@/components/ui/layout/SiteNav';
import { TableSkeleton, SkeletonGuard } from '@/components/ui/feedback/Skeleton';
import { EmptyState } from '@/components/ui/feedback/EmptyState';
import { ErrorState } from '@/components/ui/feedback/ErrorState';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import { Badge } from '@/components/ui/primitives/Badge';
import { Button } from '@/components/ui/primitives/Button';
import type { CaseSummaryView } from '@/server/support/types';
import { ErrorBoundary } from '@/components/ui/feedback/ErrorBoundary';
import { HydratedIsland } from '@/components/HydratedIsland';
import { qk } from '@/lib/query/keys';
import { formatDate, formatRelative } from '@/lib/format';
import { fetchMyPurchases } from '@/features/my-purchases/useMyPurchases';
import { Icon } from '@/components/ui/icons/Icon';
import { getCaseStatusTone } from './caseStatusTone';
import type { Locale } from '@/lib/i18n';

export interface CaseListProps {
  locale?: Locale;
  viewerRole: 'customer' | 'vendor';
  /** Base path to navigate to on row click. Defaults to "/cases". */
  basePath?: string;
  onSelect?: (caseId: string) => void;
  /** SiteNav auth/role props (forwarded from the Astro route). */
  isGuest?: boolean;
  isAdmin?: boolean;
  isVendor?: boolean;
  userName?: string;
}

async function fetchCases(viewerRole: string): Promise<CaseSummaryView[]> {
  const res = await fetch(`/api/cases?role=${viewerRole}`);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  const body = (await res.json()) as { cases?: CaseSummaryView[] };
  return body.cases ?? [];
}

function caseDeadlineAt(c: CaseSummaryView): string | null {
  const vendorWindowStatuses = new Set(['opened', 'vendor_review', 'reopened']);
  if (c.vendorWindowExpiresAt && vendorWindowStatuses.has(c.status)) {
    return c.vendorWindowExpiresAt;
  }
  return c.autocloseAt ?? c.vendorWindowExpiresAt;
}

export function CaseList(props: CaseListProps) {
  return (
    <HydratedIsland locale={props.locale}>
      <CaseListInner {...props} />
    </HydratedIsland>
  );
}

function CaseListInner({
  viewerRole,
  basePath = '/cases',
  onSelect,
  isGuest = false,
  isAdmin = false,
  isVendor = false,
  userName,
}: CaseListProps) {
  const t = useT('cases');
  const tList = t('list') as unknown as StringBundle['cases']['list'];
  const tCategories = t('categories') as unknown as StringBundle['cases']['categories'];
  const tStatus = t('status') as unknown as StringBundle['cases']['status'];
  const { locale } = useLocale();

  const navItems = useCustomerNavItems('/cases');

  const {
    data: cases,
    isLoading,
    isError,
  } = useQuery({
    queryKey: qk.cases(viewerRole),
    queryFn: () => fetchCases(viewerRole),
  });

  const { data: purchasesData } = useQuery({
    queryKey: qk.purchases(),
    queryFn: fetchMyPurchases,
    enabled: viewerRole === 'customer',
    staleTime: 60_000,
  });

  const purchaseById = new Map(
    [...(purchasesData?.active ?? []), ...(purchasesData?.history ?? [])].map((p) => [p.id, p]),
  );

  let body: React.ReactNode;
  if (isLoading && !cases) {
    body = (
      <section aria-label={tList.title} aria-busy="true" role="status">
        <SkeletonGuard delay={0}>
          <TableSkeleton rows={5} />
        </SkeletonGuard>
      </section>
    );
  } else if (isError) {
    body = (
      <section aria-label={tList.title}>
        <ErrorState title={tList.error_title} description={tList.error_description} />
      </section>
    );
  } else if (!cases || cases.length === 0) {
    body = (
      <section aria-label={tList.title}>
        <EmptyState
          title={viewerRole === 'customer' ? tList.empty_customer : tList.empty_vendor}
          description={viewerRole === 'customer' ? tList.empty_description : undefined}
          action={
            viewerRole === 'customer' ? (
              <Button
                variant="primary"
                size="sm"
                onClick={() => {
                  window.location.href = '/purchases';
                }}
              >
                {tList.empty_cta}
              </Button>
            ) : undefined
          }
        />
      </section>
    );
  } else {
    body = (
      <section aria-label={tList.title}>
        <ul className="divide-border divide-y">
          {cases.map((c) => {
            const purchase = purchaseById.get(c.purchaseId);
            const href = `${basePath}/${c.id}`;
            const categoryLabel =
              tCategories[c.category as keyof StringBundle['cases']['categories']] ?? c.category;
            const statusLabel =
              tStatus[c.status as keyof StringBundle['cases']['status']] ?? tList.status_fallback;
            const primaryLine =
              purchase?.dealTitle ?? `${tList.col_purchase} #${c.purchaseId.slice(0, 8)}`;
            const secondaryLine = purchase
              ? [categoryLabel, purchase.businessName].filter(Boolean).join(' · ')
              : categoryLabel;
            const deadlineAt = caseDeadlineAt(c);

            return (
              <li key={c.id}>
                <a
                  href={href}
                  onClick={(e) => {
                    if (onSelect) {
                      e.preventDefault();
                      onSelect(c.id);
                    }
                  }}
                  className="hover:bg-surface-hover focus-visible:ring-border-focus-primary flex w-full items-center gap-2 px-4 py-3 text-start transition-colors focus-visible:ring-2 focus-visible:outline-none"
                >
                  <div className="min-w-0 flex-1">
                    <div className="flex items-center justify-between gap-2">
                      <span className="text-text-primary truncate text-sm font-medium">
                        {primaryLine}
                      </span>
                      <Badge tone={getCaseStatusTone(c.status)} size="sm" className="shrink-0">
                        {statusLabel}
                      </Badge>
                    </div>
                    <p className="text-text-secondary mt-0.5 truncate text-xs">{secondaryLine}</p>
                    <time
                      className="text-text-muted mt-0.5 text-xs"
                      dateTime={c.updatedAt}
                      title={formatDate(c.updatedAt, locale)}
                    >
                      {tList.col_updated}: {formatRelative(c.updatedAt, locale)}
                    </time>
                    {deadlineAt && (
                      <time
                        className="text-text-muted mt-0.5 block text-xs"
                        dateTime={deadlineAt}
                        title={formatDate(deadlineAt, locale)}
                      >
                        {tList.col_deadline}: {formatRelative(deadlineAt, locale)}
                      </time>
                    )}
                  </div>
                  <Icon name="ChevronLeft" size="sm" className="text-text-muted shrink-0" mirror />
                </a>
              </li>
            );
          })}
        </ul>
      </section>
    );
  }

  return (
    <ErrorBoundary>
      <AppShell
        mode="customer"
        topBar={
          <SiteNav
            variant="mobile"
            title={tList.title}
            currentPath="/cases"
            isGuest={isGuest}
            isAdmin={isAdmin}
            isVendor={isVendor}
          />
        }
        desktopTopBar={
          <SiteNav
            variant="desktop"
            currentPath="/cases"
            isGuest={isGuest}
            isAdmin={isAdmin}
            isVendor={isVendor}
            userName={userName}
          />
        }
        bottomNav={<BottomNav mode="customer" items={navItems} />}
      >
        <main id="main" className="relative z-0 mx-auto w-full max-w-2xl px-4 py-6">
          <h1 className="text-text-primary mb-6 text-2xl leading-tight font-bold">{tList.title}</h1>
          {viewerRole === 'customer' && (
            <div className="relative z-0 mb-6 flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
              <InlineNotice
                tone="info"
                description={t('cross_link_to_tickets')}
                className="flex-1"
              />
              <a
                href="/support/tickets/new"
                className="text-brand-primary-700 hover:text-brand-primary-900 shrink-0 text-sm font-semibold underline"
              >
                {t('open_ticket_cta')} →
              </a>
            </div>
          )}
          {body}
        </main>
      </AppShell>
    </ErrorBoundary>
  );
}
