import clsx from "clsx";

/* Server-component-friendly skeleton primitives for route loading.tsx files.
   All shimmer comes from the `.skeleton` CSS class in globals.css (the
   existing `shimmer` keyframes) — no client JS, no framer-motion, and the
   global prefers-reduced-motion override collapses it to a static block. */

export interface SkeletonProps {
  className?: string;
  /** CSS width, e.g. "60%" or 120 (px) */
  width?: string | number;
  /** CSS height, e.g. 16 (px) or "2rem" */
  height?: string | number;
}

/**
 * Skeleton — a single shimmering placeholder block.
 * Size it via width/height props or Tailwind classes (h-4 w-32 …).
 */
export function Skeleton({ className, width, height }: SkeletonProps) {
  return (
    <div
      aria-hidden
      className={clsx("skeleton", className)}
      style={{ width, height }}
    />
  );
}

export interface SkeletonTextProps {
  className?: string;
  /** number of text lines, default 3 */
  lines?: number;
  /** width of the trailing line, default "60%" */
  lastLineWidth?: string;
}

/**
 * SkeletonText — a stack of shimmering text lines; the last line is shorter
 * so the block reads like a paragraph.
 */
export function SkeletonText({
  className,
  lines = 3,
  lastLineWidth = "60%",
}: SkeletonTextProps) {
  return (
    <div className={clsx("flex flex-col gap-2", className)}>
      {Array.from({ length: lines }).map((_, i) => (
        <Skeleton
          key={i}
          className="h-3.5"
          width={i === lines - 1 ? lastLineWidth : "100%"}
        />
      ))}
    </div>
  );
}

export interface SkeletonTableProps {
  className?: string;
  /** body rows, default 8 */
  rows?: number;
  /** columns, default 6 */
  columns?: number;
}

/**
 * SkeletonTable — header strip + hairline-separated rows; placeholder for
 * leaderboard-style tables while route data streams in.
 */
export function SkeletonTable({
  className,
  rows = 8,
  columns = 6,
}: SkeletonTableProps) {
  return (
    <div
      aria-hidden
      className={clsx(
        "hairline overflow-hidden rounded-sm bg-surface",
        className,
      )}
    >
      {/* header */}
      <div className="hairline-b flex items-center gap-4 bg-surface-2/60 px-3 py-3">
        {Array.from({ length: columns }).map((_, i) => (
          <Skeleton key={i} className="h-3 flex-1" />
        ))}
      </div>
      {/* rows */}
      {Array.from({ length: rows }).map((_, r) => (
        <div
          key={r}
          className="hairline-b flex items-center gap-4 px-3 py-3.5 last:border-b-0"
        >
          {Array.from({ length: columns }).map((_, c) => (
            <Skeleton
              key={c}
              className="h-3 flex-1"
              // vary line lengths slightly so the table doesn't look stamped
              width={c === 0 ? "70%" : undefined}
            />
          ))}
        </div>
      ))}
    </div>
  );
}

export interface SkeletonCardProps {
  className?: string;
  /** body text lines, default 2 */
  lines?: number;
}

/**
 * SkeletonCard — hairline card with a heading line + body text placeholder.
 */
export function SkeletonCard({ className, lines = 2 }: SkeletonCardProps) {
  return (
    <div
      aria-hidden
      className={clsx("hairline rounded-sm bg-surface p-5", className)}
    >
      <Skeleton className="mb-4 h-4" width="40%" />
      <SkeletonText lines={lines} />
    </div>
  );
}

export interface SkeletonStatsProps {
  className?: string;
  /** number of stat tiles, default 4 */
  count?: number;
}

/**
 * SkeletonStats — grid of MetricCard-shaped stat tiles (big number + label).
 * Compose grid columns via className (e.g. "grid-cols-2 md:grid-cols-4").
 */
export function SkeletonStats({ className, count = 4 }: SkeletonStatsProps) {
  return (
    <div
      aria-hidden
      className={clsx(
        "hairline grid gap-px overflow-hidden rounded-sm bg-line",
        className,
      )}
    >
      {Array.from({ length: count }).map((_, i) => (
        <div key={i} className="flex flex-col gap-2 bg-surface px-4 py-3">
          <Skeleton className="h-3" width="55%" />
          <Skeleton className="h-7" width="45%" />
        </div>
      ))}
    </div>
  );
}
