'use client';

import { Sparkline } from '@/components/charts/sparkline.js';
import { AnimatedNumber } from '@/components/dashboard/animated-number.js';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card.js';
import { cn } from '@/lib/utils.js';
import type { ReactNode } from 'react';
import { useCallback } from 'react';

type AnimatedFormat = 'dollar' | 'compact' | 'integer';

const FORMAT_FNS: Record<AnimatedFormat, (n: number) => string> = {
  dollar: (n: number) => `$${n.toFixed(2)}`,
  compact: (n: number) => {
    if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
    if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;
    return n.toFixed(1);
  },
  integer: (n: number) => Math.round(n).toLocaleString(),
};

interface MetricCardProps {
  title: string;
  value: string;
  /** When provided with animatedFormat, the value animates via spring physics on change. */
  numericValue?: number;
  /** Named format preset for the animated value. */
  animatedFormat?: AnimatedFormat;
  unit?: string;
  icon: ReactNode;
  className?: string;
  sparklineData?: { value: number }[];
  sparklineColor?: string;
}

export function MetricCard({
  title,
  value,
  numericValue,
  animatedFormat,
  unit,
  icon,
  className,
  sparklineData,
  sparklineColor,
}: MetricCardProps) {
  const formatFn = useCallback(
    (n: number) => (animatedFormat ? FORMAT_FNS[animatedFormat](n) : n.toFixed(2)),
    [animatedFormat],
  );

  return (
    <Card className={cn('gap-0 py-4', className)}>
      <CardHeader className="pb-2">
        <CardTitle className="flex items-center gap-2 text-sm font-medium text-muted-foreground">
          {icon}
          {title}
        </CardTitle>
      </CardHeader>
      <CardContent>
        <div className="flex items-baseline gap-1.5">
          {numericValue !== undefined && animatedFormat ? (
            <AnimatedNumber value={numericValue} format={formatFn} className="text-3xl font-bold tracking-tight" />
          ) : (
            <span className="text-3xl font-bold tracking-tight">{value}</span>
          )}
          {unit && <span className="text-sm text-muted-foreground">{unit}</span>}
        </div>
        {sparklineData && sparklineData.length >= 2 && (
          <div className="mt-2">
            <Sparkline data={sparklineData} color={sparklineColor} height={28} />
          </div>
        )}
      </CardContent>
    </Card>
  );
}
