import * as React from "react";
import { cn } from "@admin/lib/utils"

type SkeletonBaseProps = React.ComponentProps<"div"> & {
  /** visual style of the skeleton */
  variant?: "rect" | "text" | "circle";
  /** width (px number or CSS string) */
  width?: number | string;
  /** height (px number or CSS string) */
  height?: number | string;
  /** toggle animation */
  animated?: boolean;
  /** accessible label for screen readers */
  srLabel?: string;
};

/**
 * Small, highly-configurable Skeleton block used for placeholders.
 * Examples: <Skeleton width={120} height={16} variant="text" />
 */
function Skeleton({
  className,
  variant = "rect",
  width,
  height,
  animated = true,
  srLabel = "Loading",
  ...props
}: SkeletonBaseProps) {
  const sizeStyle: React.CSSProperties = {};
  if (width !== undefined) sizeStyle.width = typeof width === "number" ? `${width}px` : width;
  if (height !== undefined) sizeStyle.height = typeof height === "number" ? `${height}px` : height;

  const baseClasses = cn(
    "bg-primary/10",
    animated ? "animate-pulse" : "",
    variant === "text" ? "h-3 rounded-sm" : "rounded-md",
    className
  );

  const variantClass = variant === "circle" ? "rounded-full aspect-square" : undefined;

  return (
    <div
      role="status"
      aria-label={srLabel}
      data-slot="skeleton"
      className={cn(baseClasses, variantClass)}
      style={sizeStyle}
      {...props}
    />
  );
}

type DataTableSkeletonProps = React.HTMLAttributes<HTMLDivElement> & {
  rows?: number;
  columns?: number;
  /** height for each row in px or css string */
  rowHeight?: number | string;
  /** optional per-column widths */
  columnWidths?: (number | string)[];
  /** render a header row */
  header?: boolean;
  /** header height */
  headerHeight?: number | string;
  gap?: number | string;
  /** toggle animation */
  animated?: boolean;
  /** cell extra classes */
  cellClassName?: string;
  /** overall table classes */
  tableClassName?: string;
};

/**
 * DataTableSkeleton renders a configurable placeholder table with a header
 * and N rows x M columns. Use it when data table content is loading.
 * It's intentionally lightweight and customizable for reuse across the app.
 */
function DataTableSkeleton({
  rows = 5,
  columns = 5,
  rowHeight = 40,
  columnWidths = [],
  header = true,
  headerHeight = 28,
  gap = 8,
  animated = true,
  cellClassName,
  tableClassName,
  ...props
}: DataTableSkeletonProps) {
  const colArray = Array.from({ length: columns });

  // Helper to convert number -> px string or leave CSS string
  const toSize = (v: number | string | undefined) => (v === undefined ? undefined : typeof v === "number" ? `${v}px` : v);

  return (
    <div
      role="status"
      aria-live="polite"
      className={cn("w-full overflow-x-auto", tableClassName)}
      {...props}
    >
      <div className="w-full space-y-2">
        {header && (
          <div className="flex items-center gap-2 px-2">
            {colArray.map((_, ci) => (
              <Skeleton
                key={`h-${ci}`}
                animated={animated}
                variant="text"
                height={toSize(headerHeight)}
                width={columnWidths[ci] ? toSize(columnWidths[ci]) : `${100 / Math.max(columns, 1)}%`}
                className={cn("flex-1", cellClassName)}
              />
            ))}
          </div>
        )}

        <div className="space-y-2 px-2">
          {Array.from({ length: rows }).map((_, ri) => (
            <div key={`r-${ri}`} className="flex items-center gap-2">
              {colArray.map((_, ci) => (
                <Skeleton
                  key={`r-${ri}-c-${ci}`}
                  animated={animated}
                  variant="rect"
                  height={toSize(rowHeight)}
                  width={columnWidths[ci] ? toSize(columnWidths[ci]) : `${100 / Math.max(columns, 1)}%`}
                  className={cn("flex-1", cellClassName)}
                />
              ))}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

export { Skeleton, DataTableSkeleton }
