/**
 * DashboardStatCard
 *
 * A reusable stat/metric card component for the dashboard.
 * Supports icons, trend indicators, tooltips, and multiple size variants.
 *
 * @example
 * // Basic usage
 * <DashboardStatCard
 *   title="Total Revenue"
 *   value="$12,345"
 *   subtitle="Last 30 days"
 * />
 *
 * @example
 * // With icon and trend
 * <DashboardStatCard
 *   title="Orders"
 *   value={1234}
 *   trend={{ value: 12.5, label: "vs last month" }}
 *   icon={ShoppingCart}
 *   iconColor="blue"
 * />
 *
 * @example
 * // With prefix/suffix and tooltip
 * <DashboardStatCard
 *   title="Average Order Value"
 *   value={85.50}
 *   valuePrefix="$"
 *   valueSuffix="/order"
 *   tooltip="Calculated as total revenue divided by number of orders"
 * />
 */

import React from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Tooltip,
  TooltipContent,
  TooltipTrigger,
} from "@/components/ui/tooltip";
import { ArrowUp, ArrowDown, Minus, Info, type LucideIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import {
  CARD_STYLES,
  TYPOGRAPHY,
  STAT_ICON_STYLES,
  getTrendColor,
} from "@/lib/dashboard/designTokens";

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

export type TrendDirection = "up" | "down" | "neutral";
export type CardSize = "default" | "compact" | "large";
export type IconColor = keyof typeof STAT_ICON_STYLES.colors;

export interface TrendProps {
  /** The percentage or absolute change value */
  value: number;
  /** Optional label to show after the trend (e.g., "vs last month") */
  label?: string;
  /** Whether a higher value is better (affects color). Defaults to true. */
  moreIsBetter?: boolean;
  /** Suffix for the trend value (defaults to "%"). Use "" for no suffix. */
  suffix?: string;
}

export interface DashboardStatCardProps {
  /** Card title/label */
  title: string;
  /** The main value to display (can be string for formatted values or number) */
  value: string | number;
  /** Optional prefix for the value (e.g., "$") */
  valuePrefix?: string;
  /** Optional suffix for the value (e.g., "/day", "%") */
  valueSuffix?: string;
  /** Optional subtitle or description (can be string or JSX) */
  subtitle?: React.ReactNode;
  /** Optional trend indicator */
  trend?: TrendProps;
  /** Optional icon component */
  icon?: LucideIcon;
  /** Icon color variant */
  iconColor?: IconColor;
  /** Card size variant */
  size?: CardSize;
  /** Additional className for the card */
  className?: string;
  /** Click handler for interactive cards */
  onClick?: () => void;
  /** Loading state */
  loading?: boolean;
  /** Tooltip text shown via info icon next to title */
  tooltip?: string;
  /** Additional content to render below the main value */
  children?: React.ReactNode;
}

// =============================================================================
// HELPER COMPONENTS
// =============================================================================

interface TrendIndicatorProps {
  value: number;
  label?: string;
  moreIsBetter?: boolean;
  suffix?: string;
  size?: CardSize;
}

const TrendIndicator: React.FC<TrendIndicatorProps> = ({
  value,
  label,
  moreIsBetter = true,
  suffix = "%",
  size = "default",
}) => {
  const colors = getTrendColor(value, moreIsBetter);
  const direction: TrendDirection =
    value > 0 ? "up" : value < 0 ? "down" : "neutral";

  const IconComponent =
    direction === "up"
      ? ArrowUp
      : direction === "down"
        ? ArrowDown
        : Minus;

  const iconSize = size === "compact" ? "h-3 w-3" : "h-3 w-3";
  const textSize = size === "compact" ? "text-xs" : "text-xs";

  // Format the value - use fixed decimal for percentages, integer for absolute values
  const formattedValue = suffix === "%"
    ? value.toFixed(1)
    : Math.abs(value).toString();

  return (
    <div className={cn("flex items-center gap-1", colors.text)}>
      <IconComponent className={iconSize} />
      <span className={cn("font-medium", textSize)}>
        {value > 0 && suffix === "%" ? "+" : ""}
        {formattedValue}{suffix}
      </span>
      {label && (
        <span className={cn("text-muted-foreground", textSize)}>{label}</span>
      )}
    </div>
  );
};

interface IconContainerProps {
  icon: LucideIcon;
  color?: IconColor;
  size?: CardSize;
}

const IconContainer: React.FC<IconContainerProps> = ({
  icon: Icon,
  color = "blue",
  size = "default",
}) => {
  const colorStyles = STAT_ICON_STYLES.colors[color] || STAT_ICON_STYLES.colors.blue;
  const containerSize = size === "compact" ? "p-1.5" : "p-2";
  const iconSize = size === "compact" ? "h-3.5 w-3.5" : size === "large" ? "h-5 w-5" : "h-4 w-4";

  return (
    <div
      className={cn(
        STAT_ICON_STYLES.container,
        containerSize,
        colorStyles.container
      )}
    >
      <Icon className={cn(iconSize, colorStyles.icon)} />
    </div>
  );
};

// =============================================================================
// MAIN COMPONENT
// =============================================================================

export const DashboardStatCard: React.FC<DashboardStatCardProps> = ({
  title,
  value,
  valuePrefix,
  valueSuffix,
  subtitle,
  trend,
  icon,
  iconColor = "blue",
  size = "default",
  className,
  onClick,
  loading = false,
  tooltip,
  children,
}) => {
  // Size-based styling
  const sizeStyles = {
    default: {
      header: CARD_STYLES.header,
      value: TYPOGRAPHY.cardValue,
      title: TYPOGRAPHY.cardTitle,
      content: CARD_STYLES.content,
    },
    compact: {
      header: CARD_STYLES.headerCompact,
      value: TYPOGRAPHY.cardValueSmall,
      title: "text-xs font-medium text-muted-foreground",
      content: "px-4 pt-0 pb-3",
    },
    large: {
      header: CARD_STYLES.header,
      value: TYPOGRAPHY.cardValueLarge,
      title: TYPOGRAPHY.cardTitle,
      content: CARD_STYLES.contentPadded,
    },
  };

  const styles = sizeStyles[size];
  const cardClass = onClick ? CARD_STYLES.interactive : CARD_STYLES.base;

  // Loading state
  if (loading) {
    return (
      <Card className={cn(cardClass, className)}>
        <CardHeader className={cn(styles.header, "space-y-0")}>
          <div className="h-4 w-24 bg-muted animate-pulse rounded" />
          {icon && <div className="h-8 w-8 bg-muted animate-pulse rounded-lg" />}
        </CardHeader>
        <CardContent className={styles.content}>
          <div className="h-8 w-32 bg-muted animate-pulse rounded mb-2" />
          {subtitle && <div className="h-4 w-20 bg-muted animate-pulse rounded" />}
        </CardContent>
      </Card>
    );
  }

  // Format the display value with prefix/suffix
  const formattedValue = (
    <>
      {valuePrefix && <span className="">{valuePrefix}</span>}
      {typeof value === "number" ? value.toLocaleString() : value}
      {valueSuffix && <span className="">{valueSuffix}</span>}
    </>
  );

  return (
    <Card
      className={cn(cardClass, onClick && "cursor-pointer", className)}
      onClick={onClick}
    >
      <CardHeader className={cn(styles.header, "space-y-0")}>
        <div className="flex items-center gap-1.5">
          <CardTitle className={styles.title}>{title}</CardTitle>
          {tooltip && (
            <Tooltip>
              <TooltipTrigger asChild>
                <button
                  type="button"
                  className="text-muted-foreground hover:text-foreground transition-colors"
                  onClick={(e) => e.stopPropagation()}
                >
                  <Info className="h-3.5 w-3.5" />
                </button>
              </TooltipTrigger>
              <TooltipContent side="top" className="max-w-xs">
                <p className="text-sm">{tooltip}</p>
              </TooltipContent>
            </Tooltip>
          )}
        </div>
        {icon && <IconContainer icon={icon} color={iconColor} size={size} />}
      </CardHeader>
      <CardContent className={styles.content}>
        <div className={cn(styles.value, "text-foreground")}>
          {formattedValue}
        </div>
        {(subtitle || trend) && (
          <div className="flex flex-wrap items-center justify-between gap-2 mt-1">
            {subtitle && (
              <span className={TYPOGRAPHY.cardDescription}>{subtitle}</span>
            )}
            {trend && (
              <TrendIndicator
                value={trend.value}
                label={trend.label}
                moreIsBetter={trend.moreIsBetter}
                suffix={trend.suffix}
                size={size}
              />
            )}
          </div>
        )}
        {children}
      </CardContent>
    </Card>
  );
};

// =============================================================================
// SKELETON VARIANT
// =============================================================================

export interface DashboardStatCardSkeletonProps {
  size?: CardSize;
  hasIcon?: boolean;
  hasSubtitle?: boolean;
  className?: string;
}

export const DashboardStatCardSkeleton: React.FC<DashboardStatCardSkeletonProps> = ({
  size = "default",
  hasIcon = true,
  hasSubtitle = true,
  className,
}) => {
  const sizeStyles = {
    default: { header: CARD_STYLES.header, content: CARD_STYLES.content },
    compact: { header: CARD_STYLES.headerCompact, content: "px-4 pt-0 pb-3" },
    large: { header: CARD_STYLES.header, content: CARD_STYLES.contentPadded },
  };

  const styles = sizeStyles[size];

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

export default DashboardStatCard;
