import { type LucideIcon } from "lucide-react"

import { cn } from "@/lib/utils"

function formatValue(value: string | number) {
  if (typeof value !== "number") return value
  const formatted = Intl.NumberFormat(undefined, {
    notation: "compact",
    maximumFractionDigits: 1,
  }).format(value)

  // Normalize compact suffix casing to a consistent form to avoid
  // hydration mismatches between server and client environments.
  return formatted.replace(/(k|K|m|M|b|B)$/u, (s) => s.toUpperCase())
}

function Sparkline({ points }: { points: number[] }) {
  const width = 48
  const height = 18
  const min = Math.min(...points)
  const max = Math.max(...points)
  const range = max - min || 1

  const coords = points.map((point, index) => {
    const x = (index / (points.length - 1)) * width
    const y = height - ((point - min) / range) * height
    return [x, y] as const
  })

  const path = coords.map(([x, y], i) => `${i === 0 ? "M" : "L"}${x},${y}`).join(" ")
  const [lastX, lastY] = coords[coords.length - 1]

  return (
    <svg
      viewBox={`0 0 ${width} ${height}`}
      className="h-4.5 w-12 shrink-0 overflow-visible"
      aria-hidden="true"
    >
      <path d={path} fill="none" stroke="#cbd5e1" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" />
      <circle cx={lastX} cy={lastY} r={2.5} className="fill-indigo-600" stroke="white" strokeWidth={1.5} />
    </svg>
  )
}

export interface StatCardProps {
  label: string
  value: string | number
  icon?: LucideIcon
  delta?: number
  deltaLabel?: string
  /** Set true for metrics where an increase is bad (e.g. churn, costs). */
  invert?: boolean
  trend?: number[]
  className?: string
}

export function StatCard({
  label,
  value,
  icon: Icon,
  delta,
  deltaLabel,
  invert = false,
  trend,
  className,
}: StatCardProps) {
  const hasDelta = typeof delta === "number" && delta !== 0
  const isPositive = hasDelta && delta > 0
  const isGood = hasDelta && (invert ? !isPositive : isPositive)

  return (
    <div
      className={cn(
        "flex flex-col gap-3 rounded-2xl bg-white p-5 shadow-sm ring-1 ring-black/5 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-lg hover:ring-indigo-200",
        className
      )}
    >
      <div className="flex items-start justify-between gap-2">
        <p className="text-base font-medium text-muted-foreground">{label}</p>
        {Icon && (
          <div className="flex size-9 shrink-0 items-center justify-center rounded-lg bg-indigo-50">
            <Icon className="size-5 text-indigo-600" />
          </div>
        )}
      </div>

      <div className="flex items-end justify-between gap-2">
        <p className="text-xl font-bold tracking-tight text-slate-900">{formatValue(value)}</p>
        {trend && trend.length > 1 && <Sparkline points={trend} />}
      </div>

      {hasDelta && (
        <div className="flex items-center gap-1 text-sm">
          <span
            className={cn(
              "font-semibold",
              isGood ? "text-[#0ca30c]" : "text-[#d03b3b]"
            )}
          >
            {isPositive ? "+" : "-"}
            {Math.abs(delta).toFixed(1)}%
          </span>
          {deltaLabel && <span className="text-muted-foreground">{deltaLabel}</span>}
        </div>
      )}
    </div>
  )
}
