/**
 * MetricsCard — labeled key/value grid with an optional progress footer.
 * @countermeasure-platform/web-components/composites/metrics-card
 *
 * Mirrors the live training-metrics card the consumer's run-monitor uses.
 * Built on the shadcn-tone Card + Progress so it slots into a Tailwind-v4
 * host app without extra theming work.
 *
 * `format` controls how each `value` renders:
 *   - `'number'`   → comma-grouped integer (locale)
 *   - `'percent'`  → "12.3%"  (assumes a 0-1 fraction OR a 0-100 number;
 *                   values > 1 are treated as already-percent)
 *   - `'expo'`     → exponential, 2 sig figs (e.g. "3.2e-4")
 *   - `'eta'`      → "Hh Mm Ss" elapsed/remaining (positive seconds)
 *   - `'duration'` → same as `eta` but always positive
 *   - undefined    → as-is (string or number toString)
 */

import * as React from 'react'
import { Card } from '../react/primitives/card'
import { Progress } from '../react/primitives/progress'
import { cn } from '../react/primitives/utils'

export type MetricsFormat = 'number' | 'percent' | 'expo' | 'eta' | 'duration'

export interface MetricsItem {
  label: string
  value: string | number
  format?: MetricsFormat
}

export interface MetricsCardProps extends React.HTMLAttributes<HTMLDivElement> {
  title?: string
  items: MetricsItem[]
  progress?: { value: number; total: number }
}

function formatValue(value: string | number, format?: MetricsFormat): string {
  if (typeof value === 'string') return value
  if (!Number.isFinite(value)) return '—'

  switch (format) {
    case 'number':
      return value.toLocaleString()
    case 'percent': {
      const pct = Math.abs(value) <= 1 ? value * 100 : value
      return `${pct.toFixed(1)}%`
    }
    case 'expo':
      return value.toExponential(2)
    case 'eta':
    case 'duration': {
      const seconds = Math.max(0, Math.round(value))
      const h = Math.floor(seconds / 3600)
      const m = Math.floor((seconds % 3600) / 60)
      const s = seconds % 60
      const parts: string[] = []
      if (h > 0) parts.push(`${String(h)}h`)
      if (h > 0 || m > 0) parts.push(`${String(m)}m`)
      parts.push(`${String(s)}s`)
      return parts.join(' ')
    }
    default:
      return String(value)
  }
}

export function MetricsCard({ title, items, progress, className, ...rest }: MetricsCardProps) {
  const progressValue =
    progress && progress.total > 0
      ? Math.min(100, Math.max(0, (progress.value / progress.total) * 100))
      : null

  const progressLabel =
    progress && progress.total > 0
      ? `${progress.value.toLocaleString()} / ${progress.total.toLocaleString()}`
      : undefined

  return (
    <Card tone="shadcn" className={cn('p-4', className)} {...rest}>
      {title && <div className="mb-3 text-sm font-semibold text-foreground">{title}</div>}
      <dl className="grid grid-cols-2 gap-x-4 gap-y-2 sm:grid-cols-3">
        {items.map(item => (
          <div key={item.label} className="flex flex-col">
            <dt className="text-xs text-muted-foreground">{item.label}</dt>
            <dd className="text-sm font-semibold tabular-nums text-foreground">
              {formatValue(item.value, item.format)}
            </dd>
          </div>
        ))}
      </dl>
      {progress && (
        <div className="mt-4">
          <Progress
            value={progressValue}
            showLabel={progressValue !== null}
            {...(progressLabel ? { secondaryLabel: progressLabel } : {})}
          />
        </div>
      )}
    </Card>
  )
}
