// @design-system: domain/admin/AdminDetailPage

'use client';

/**
 * AdminDetailPage - 2-column detail layout for admin drill-down pages.
 *
 * Desktop: sticky summary card on the start side + tabbed content panel on the end side.
 * Mobile: stacked - summary card on top, tab strip below, active tab content below that.
 *
 * Tab state is driven by the URL hash (#profile, #purchases, etc.) with a
 * fallback to `defaultTab` (or the first tab).
 *
 * @example
 * ```tsx
 * <AdminDetailPage
 *   summary={<VendorSummaryCard vendor={vendor} />}
 *   tabs={[
 *     { key: 'profile', label: t('tab_profile'), content: <ProfileTab /> },
 *     { key: 'purchases', label: t('tab_purchases'), content: <PurchasesTab /> },
 *   ]}
 *   defaultTab="profile"
 * />
 * ```
 */

import { useSyncExternalStore, type ReactNode } from 'react';
import { cn } from '@/lib/cn';
import { Skeleton } from '@/components/ui/feedback/Skeleton/Skeleton';
import { Tabs } from '@/components/ui/layout/Tabs';
import { useT } from '@/lib/i18n/react';

// ─── Types ────────────────────────────────────────────────────────────────────

export interface TabDef {
  /** URL-hash key (no `#`). Also used as React key. */
  key: string;
  /** Tab label shown in the strip. */
  label: string;
  /** Content rendered when this tab is active. */
  content: ReactNode;
}

export interface AdminDetailPageProps {
  /** Summary card rendered in the start (sidebar) column. */
  summary: ReactNode;
  /** Tab definitions. */
  tabs: TabDef[];
  /** Which tab to show by default (falls back to first tab). */
  defaultTab?: string;
  /** Optional extra className on the outer wrapper. */
  className?: string;
  /** When true, renders skeleton rows in place of content. */
  loading?: boolean;
  /** When set, renders an error message in place of content. */
  error?: string;
}

// ─── Hook: hash-driven tab state ──────────────────────────────────────────────

function subscribeHash(cb: () => void): () => void {
  window.addEventListener('hashchange', cb);
  return () => window.removeEventListener('hashchange', cb);
}

function getHashSnapshot(): string {
  return window.location.hash.slice(1);
}

function getHashServerSnapshot(): string {
  return '';
}

function useHashTab(tabs: TabDef[], defaultTab?: string): [string, (key: string) => void] {
  const fallback = defaultTab ?? tabs[0]?.key ?? '';
  const rawHash = useSyncExternalStore(subscribeHash, getHashSnapshot, getHashServerSnapshot);
  const activeTab = tabs.some((t) => t.key === rawHash) ? rawHash : fallback;

  const setTab = (key: string) => {
    window.location.hash = key;
  };

  return [activeTab, setTab];
}

// ─── Component ────────────────────────────────────────────────────────────────

export function AdminDetailPage({
  summary,
  tabs,
  defaultTab,
  className,
  loading = false,
  error,
}: AdminDetailPageProps) {
  const t = useT('common');
  const [activeTab, setTab] = useHashTab(tabs, defaultTab);

  const tabPanels =
    !loading && !error ? Object.fromEntries(tabs.map((tab) => [tab.key, tab.content])) : undefined;

  return (
    <div className={cn('flex flex-col gap-6 p-6', 'lg:flex-row lg:items-start', className)}>
      {/* ── Summary card (start column) ────────────────────────────────── */}
      <aside
        className={cn('w-full', 'lg:sticky lg:top-6 lg:w-72 lg:shrink-0')}
        aria-label={t('aria_label_summary')}
      >
        {loading ? (
          <div className="flex flex-col gap-3">
            <Skeleton className="h-20 w-20 rounded-full" variant="circle" />
            <Skeleton className="h-5 w-40" />
            <Skeleton className="h-4 w-28" />
            <Skeleton className="h-4 w-32" />
          </div>
        ) : (
          summary
        )}
      </aside>

      {/* ── Tab panel (end column) ─────────────────────────────────────── */}
      <div className="flex min-w-0 flex-1 flex-col gap-4">
        {/* Tab strip */}
        <Tabs
          items={tabs.map((tab) => ({ value: tab.key, label: tab.label }))}
          value={activeTab}
          onValueChange={setTab}
          ariaLabel={t('aria_label_detail_tabs')}
          panels={tabPanels}
        />

        {loading ? (
          <div className="flex flex-col gap-3 pt-2" aria-busy="true" aria-live="polite">
            <Skeleton className="h-6 w-48" />
            <Skeleton className="h-4 w-full" />
            <Skeleton className="h-4 w-5/6" />
            <Skeleton className="h-4 w-4/6" />
            <Skeleton className="mt-4 h-24 w-full" />
            <Skeleton className="h-4 w-full" />
            <Skeleton className="h-4 w-3/4" />
          </div>
        ) : error ? (
          <div
            role="alert"
            className={cn(
              'rounded-lg border p-4',
              'border-[var(--color-status-error-border,var(--color-border-default))]',
              'bg-[var(--color-status-error-subtle,var(--color-surface-subtle))]',
              'text-[var(--color-status-error,var(--color-text-primary))]',
              'text-sm',
            )}
          >
            {error}
          </div>
        ) : null}
      </div>
    </div>
  );
}
