/**
 * DashboardSkeleton
 *
 * Standardized skeleton loading components for the dashboard.
 * Provides consistent loading states across all dashboard sections.
 *
 * @example
 * // Chart skeleton
 * {isLoading ? <ChartSkeleton /> : <MyChart />}
 *
 * @example
 * // Table skeleton
 * {isLoading ? <TableSkeleton rows={5} columns={4} /> : <MyTable />}
 *
 * @example
 * // Stat card skeleton
 * {isLoading ? <StatCardSkeleton /> : <DashboardStatCard {...props} />}
 */

import React from "react";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { cn } from "@/lib/utils";
import { CARD_STYLES, SCROLL_STYLES } from "@/lib/dashboard/designTokens";

// =============================================================================
// TYPES
// =============================================================================

export type ChartType = "line" | "bar" | "area" | "pie";
export type ChartHeight = "sm" | "md" | "default" | "lg";
export type ColorVariant = "default" | "emerald" | "blue" | "violet" | "orange" | "slate";

const CHART_HEIGHT_MAP: Record<ChartHeight, string> = {
  sm: "h-[200px]",
  md: "h-[300px]",
  default: "h-[400px]",
  lg: "h-[500px]",
};

/**
 * Color variant classes for themed skeletons
 * Used in colored cards like MiniStatCards dialogs
 */
const COLOR_VARIANT_CLASSES: Record<ColorVariant, { bg: string; skeleton: string }> = {
  default: {
    bg: "bg-muted",
    skeleton: "bg-muted",
  },
  emerald: {
    bg: "bg-emerald-200/20",
    skeleton: "bg-emerald-200/30",
  },
  blue: {
    bg: "bg-blue-200/20",
    skeleton: "bg-blue-200/30",
  },
  violet: {
    bg: "bg-violet-200/20",
    skeleton: "bg-violet-200/30",
  },
  orange: {
    bg: "bg-orange-200/20",
    skeleton: "bg-orange-200/30",
  },
  slate: {
    bg: "bg-slate-600",
    skeleton: "bg-slate-500",
  },
};

// =============================================================================
// CHART SKELETON
// =============================================================================

export interface ChartSkeletonProps {
  /** Type of chart to simulate */
  type?: ChartType;
  /** Height variant */
  height?: ChartHeight;
  /** Show card wrapper */
  withCard?: boolean;
  /** Show header placeholder */
  withHeader?: boolean;
  /** Color variant for themed cards */
  colorVariant?: ColorVariant;
  /** Additional className */
  className?: string;
}

export const ChartSkeleton: React.FC<ChartSkeletonProps> = ({
  type = "line",
  height = "default",
  withCard = true,
  withHeader = false,
  colorVariant = "default",
  className,
}) => {
  const heightClass = CHART_HEIGHT_MAP[height];
  const colors = COLOR_VARIANT_CLASSES[colorVariant];

  const renderChartContent = () => {
    switch (type) {
      case "bar":
        return (
          <div className="h-full flex items-end justify-between gap-1 px-8 pb-6">
            {[...Array(12)].map((_, i) => (
              <div
                key={i}
                className={cn("flex-1 rounded-t animate-pulse", colors.bg)}
                style={{ height: `${15 + Math.random() * 70}%` }}
              />
            ))}
          </div>
        );

      case "pie":
        return (
          <div className="h-full flex items-center justify-center">
            <div className={cn("w-40 h-40 rounded-full animate-pulse", colors.bg)} />
          </div>
        );

      case "area":
      case "line":
      default:
        return (
          <div className="h-full w-full relative">
            {/* Grid lines */}
            {[...Array(5)].map((_, i) => (
              <div
                key={i}
                className={cn("absolute w-full h-px", colors.bg)}
                style={{ top: `${(i + 1) * 20}%` }}
              />
            ))}
            {/* Y-axis labels */}
            <div className="absolute left-0 top-0 bottom-0 w-10 flex flex-col justify-between py-4">
              {[...Array(5)].map((_, i) => (
                <Skeleton key={i} className={cn("h-3 w-8", colors.skeleton)} />
              ))}
            </div>
            {/* X-axis labels */}
            <div className="absolute left-12 right-4 bottom-0 flex justify-between">
              {[...Array(6)].map((_, i) => (
                <Skeleton key={i} className={cn("h-3 w-10", colors.skeleton)} />
              ))}
            </div>
            {/* Chart area */}
            <div
              className={cn("absolute inset-x-12 bottom-6 top-4 animate-pulse rounded", colors.bg, "opacity-30")}
              style={{
                clipPath:
                  type === "area"
                    ? "polygon(0 60%, 20% 40%, 40% 55%, 60% 30%, 80% 45%, 100% 25%, 100% 100%, 0 100%)"
                    : undefined,
              }}
            />
            {/* Line for line charts */}
            {type === "line" && (
              <svg
                className="absolute inset-x-12 bottom-6 top-4"
                preserveAspectRatio="none"
                viewBox="0 0 100 100"
              >
                <path
                  d="M0 60 L20 40 L40 55 L60 30 L80 45 L100 25"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="2"
                  className={cn("animate-pulse", colorVariant === "default" ? "text-muted" : colors.skeleton.replace("bg-", "text-").replace("/30", ""))}
                />
              </svg>
            )}
          </div>
        );
    }
  };

  const content = (
    <div className={cn(heightClass, "w-full p-4", className)}>
      {withHeader && (
        <div className="flex justify-between items-center mb-4">
          <Skeleton className="h-5 w-32 bg-muted" />
          <Skeleton className="h-8 w-24 bg-muted" />
        </div>
      )}
      <div className={cn("h-full", withHeader && "h-[calc(100%-48px)]")}>
        {renderChartContent()}
      </div>
    </div>
  );

  if (withCard) {
    return <Card className={CARD_STYLES.base}>{content}</Card>;
  }

  return content;
};

// =============================================================================
// TABLE SKELETON
// =============================================================================

export type TableSkeletonVariant = "simple" | "detailed";

export interface TableSkeletonProps {
  /** Number of rows to show */
  rows?: number;
  /** Number of columns or array of column widths */
  columns?: number | string[];
  /** Show card wrapper */
  withCard?: boolean;
  /** Show header placeholder */
  withHeader?: boolean;
  /** Color variant for themed cards */
  colorVariant?: ColorVariant;
  /** Additional className */
  className?: string;
  /** Make container scrollable */
  scrollable?: boolean;
  /** Max height for scrollable (uses SCROLL_STYLES keys) */
  maxHeight?: "sm" | "md" | "lg" | "xl";
  /**
   * Cell layout variant:
   * - "simple": single-line cells (default)
   * - "detailed": multi-line cells with icon in first column and value+sublabel in others
   */
  variant?: TableSkeletonVariant;
  /** Show icon placeholder in first column (only for detailed variant) */
  hasIcon?: boolean;
}

export const TableSkeleton: React.FC<TableSkeletonProps> = ({
  rows = 5,
  columns = 4,
  withCard = false,
  withHeader = false,
  colorVariant = "default",
  className,
  scrollable = false,
  maxHeight = "md",
  variant = "simple",
  hasIcon = true,
}) => {
  const columnCount = Array.isArray(columns) ? columns.length : columns;
  const columnWidths = Array.isArray(columns)
    ? columns
    : Array(columnCount).fill("w-24");
  const colors = COLOR_VARIANT_CLASSES[colorVariant];

  // Simple variant - single line cells
  const renderSimpleCell = (colIndex: number) => (
    <Skeleton
      className={cn(
        "h-4",
        colors.skeleton,
        colIndex === 0 ? "w-32" : columnWidths[colIndex]
      )}
    />
  );

  // Detailed variant - first column has icon + stacked text, others have value + sublabel
  const renderDetailedFirstCell = () => (
    <div className="flex items-center gap-2">
      {hasIcon && <Skeleton className={cn("h-4 w-4", colors.skeleton)} />}
      <div className="space-y-2">
        <Skeleton className={cn("h-4 w-48", colors.skeleton)} />
        <Skeleton className={cn("h-3 w-64", colors.skeleton)} />
        <Skeleton className={cn("h-3 w-32", colors.skeleton)} />
      </div>
    </div>
  );

  const renderDetailedMetricCell = () => (
    <div className="flex flex-col items-center gap-1">
      <Skeleton className={cn("h-4 w-16", colors.skeleton)} />
      <Skeleton className={cn("h-3 w-24", colors.skeleton)} />
    </div>
  );

  const tableContent = (
    <Table>
      <TableHeader>
        <TableRow className="hover:bg-transparent">
          {Array.from({ length: columnCount }).map((_, i) => (
            <TableHead key={i} className={i === 0 ? "text-left" : "text-center"}>
              <Skeleton
                className={cn(
                  variant === "detailed" ? "h-8" : "h-4",
                  colors.skeleton,
                  i === 0 ? "w-24" : "w-20",
                  i !== 0 && "mx-auto"
                )}
              />
            </TableHead>
          ))}
        </TableRow>
      </TableHeader>
      <TableBody>
        {Array.from({ length: rows }).map((_, rowIndex) => (
          <TableRow key={rowIndex} className="hover:bg-muted/50 transition-colors">
            {Array.from({ length: columnCount }).map((_, colIndex) => (
              <TableCell key={colIndex} className={colIndex !== 0 ? "text-center" : ""}>
                {variant === "detailed" ? (
                  colIndex === 0 ? renderDetailedFirstCell() : renderDetailedMetricCell()
                ) : (
                  renderSimpleCell(colIndex)
                )}
              </TableCell>
            ))}
          </TableRow>
        ))}
      </TableBody>
    </Table>
  );

  const content = (
    <div className={className}>
      {withHeader && (
        <div className="flex justify-between items-center mb-4 px-4 pt-4">
          <Skeleton className="h-5 w-32 bg-muted" />
          <Skeleton className="h-8 w-24 bg-muted" />
        </div>
      )}
      {scrollable ? (
        <div className={SCROLL_STYLES[maxHeight]}>{tableContent}</div>
      ) : (
        tableContent
      )}
    </div>
  );

  if (withCard) {
    return <Card className={CARD_STYLES.base}>{content}</Card>;
  }

  return content;
};

// =============================================================================
// STAT CARD SKELETON (re-exported from DashboardStatCard)
// =============================================================================

export interface StatCardSkeletonProps {
  /** Card size variant */
  size?: "default" | "compact" | "large";
  /** Show icon placeholder */
  hasIcon?: boolean;
  /** Show subtitle placeholder */
  hasSubtitle?: boolean;
  /** Additional className */
  className?: string;
}

export const StatCardSkeleton: React.FC<StatCardSkeletonProps> = ({
  size = "default",
  hasIcon = true,
  hasSubtitle = true,
  className,
}) => {
  const sizeStyles = {
    default: {
      header: CARD_STYLES.header,
      content: CARD_STYLES.content,
      valueHeight: "h-8",
      valueWidth: "w-32",
    },
    compact: {
      header: CARD_STYLES.headerCompact,
      content: "px-4 pt-0 pb-3",
      valueHeight: "h-6",
      valueWidth: "w-24",
    },
    large: {
      header: CARD_STYLES.header,
      content: CARD_STYLES.contentPadded,
      valueHeight: "h-10",
      valueWidth: "w-36",
    },
  };

  const styles = sizeStyles[size];

  return (
    <Card className={cn(CARD_STYLES.base, className)}>
      <CardHeader className={cn(styles.header, "space-y-0")}>
        <Skeleton className="h-4 w-24 bg-muted" />
        {hasIcon && <Skeleton className="h-8 w-8 bg-muted rounded-lg" />}
      </CardHeader>
      <CardContent className={styles.content}>
        <Skeleton className={cn(styles.valueHeight, styles.valueWidth, "bg-muted mb-2")} />
        {hasSubtitle && <Skeleton className="h-4 w-20 bg-muted" />}
      </CardContent>
    </Card>
  );
};

// =============================================================================
// GRID SKELETON (for multiple stat cards)
// =============================================================================

export interface GridSkeletonProps {
  /** Number of cards to show */
  count?: number;
  /** Grid columns */
  columns?: 2 | 3 | 4 | 6;
  /** Card size */
  cardSize?: "default" | "compact" | "large";
  /** Additional className */
  className?: string;
}

export const GridSkeleton: React.FC<GridSkeletonProps> = ({
  count = 4,
  columns = 4,
  cardSize = "default",
  className,
}) => {
  const gridClass = {
    2: "grid-cols-1 sm:grid-cols-2",
    3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
    4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4",
    6: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-6",
  };

  return (
    <div className={cn("grid gap-4", gridClass[columns], className)}>
      {Array.from({ length: count }).map((_, i) => (
        <StatCardSkeleton key={i} size={cardSize} />
      ))}
    </div>
  );
};

// =============================================================================
// LIST SKELETON (for feeds, events, etc.)
// =============================================================================

export interface ListSkeletonProps {
  /** Number of items to show */
  items?: number;
  /** Show avatar/icon placeholder */
  hasAvatar?: boolean;
  /** Show timestamp placeholder */
  hasTimestamp?: boolean;
  /** Show card wrapper */
  withCard?: boolean;
  /** Additional className */
  className?: string;
}

export const ListSkeleton: React.FC<ListSkeletonProps> = ({
  items = 5,
  hasAvatar = true,
  hasTimestamp = true,
  withCard = false,
  className,
}) => {
  const content = (
    <div className={cn("divide-y divide-border/50", className)}>
      {Array.from({ length: items }).map((_, i) => (
        <div key={i} className="flex items-center gap-3 p-4">
          {hasAvatar && (
            <Skeleton className="h-10 w-10 rounded-full bg-muted shrink-0" />
          )}
          <div className="flex-1 min-w-0 space-y-2">
            <Skeleton className="h-4 w-3/4 bg-muted" />
            <Skeleton className="h-3 w-1/2 bg-muted" />
          </div>
          {hasTimestamp && (
            <Skeleton className="h-3 w-16 bg-muted shrink-0" />
          )}
        </div>
      ))}
    </div>
  );

  if (withCard) {
    return <Card className={CARD_STYLES.base}>{content}</Card>;
  }

  return content;
};

// =============================================================================
// SECTION SKELETON (card with header and content area)
// =============================================================================

export interface SectionSkeletonProps {
  /** Height of the content area */
  contentHeight?: string;
  /** Show header with title and action button */
  withHeader?: boolean;
  /** Additional className */
  className?: string;
}

export const SectionSkeleton: React.FC<SectionSkeletonProps> = ({
  contentHeight = "h-[400px]",
  withHeader = true,
  className,
}) => {
  return (
    <Card className={cn(CARD_STYLES.base, className)}>
      {withHeader && (
        <CardHeader className={CARD_STYLES.header}>
          <Skeleton className="h-5 w-32 bg-muted" />
          <Skeleton className="h-9 w-28 bg-muted rounded-md" />
        </CardHeader>
      )}
      <CardContent className={CARD_STYLES.content}>
        <Skeleton className={cn("w-full bg-muted rounded-lg", contentHeight)} />
      </CardContent>
    </Card>
  );
};

// =============================================================================
// EXPORTS
// =============================================================================

export default {
  Chart: ChartSkeleton,
  Table: TableSkeleton,
  StatCard: StatCardSkeleton,
  Grid: GridSkeleton,
  List: ListSkeleton,
  Section: SectionSkeleton,
};
