import * as React from 'react'
import { cn } from '../../lib/utils'
import { HEALTH_TONE, type HealthStatus } from './health-status'

/** A small solid status dot. Pair it with a label — never rely on color alone. */
export function HealthDot({ status, className }: { status: HealthStatus; className?: string }) {
  return (
    <span
      className={cn('inline-block w-2.5 h-2.5 rounded-full flex-shrink-0', HEALTH_TONE[status].dot, className)}
      aria-hidden="true"
    />
  )
}

/** A tone pill: icon + label, used in a HealthCard header to name the roll-up state. */
export function HealthBadge({
  status,
  label,
  className,
}: {
  status: HealthStatus
  label?: string
  className?: string
}) {
  const tone = HEALTH_TONE[status]
  const Icon = tone.Icon
  return (
    <span
      className={cn(
        'inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium',
        tone.softBg,
        tone.text,
        className,
      )}
    >
      <Icon className="w-3.5 h-3.5" aria-hidden="true" />
      {label ?? tone.label}
    </span>
  )
}

export interface HealthCardProps {
  /** Card heading. */
  title: string
  /** The rolled-up tone — drives the left accent + the header badge. */
  status: HealthStatus
  /** Optional short label overriding the tone's default badge text (e.g. "3 stale"). */
  statusLabel?: string
  /** Optional leading icon for the title. */
  icon?: React.ComponentType<{ className?: string }>
  /** Optional right-aligned header slot (a link, a period selector…). */
  action?: React.ReactNode
  /** Body — the signal-specific content. */
  children?: React.ReactNode
  /** Shown (muted, centered) when there is nothing to report. */
  emptyMessage?: string
  /** Render the empty state instead of children. */
  isEmpty?: boolean
  isLoading?: boolean
  className?: string
}

/**
 * The base surface every SystemHealth block renders into: a titled card with a
 * left tone-accent and a status badge, so a wall of them reads as a scannable
 * health board. Presentational only — the tone + contents are computed by the
 * composer (or, in a tenant app, by the dashboard widget that fetches the data).
 */
export function HealthCard({
  title,
  status,
  statusLabel,
  icon: Icon,
  action,
  children,
  emptyMessage = 'Nothing to report.',
  isEmpty,
  isLoading,
  className,
}: HealthCardProps) {
  return (
    <div
      className={cn(
        'rounded-xl border border-l-4 bg-card text-card-foreground shadow p-5 space-y-4',
        HEALTH_TONE[status].border,
        isLoading && 'animate-pulse',
        className,
      )}
    >
      <div className="flex items-center justify-between gap-3">
        <div className="flex items-center gap-2 min-w-0">
          {Icon && <Icon className="w-4 h-4 text-gray-400 flex-shrink-0" aria-hidden="true" />}
          <h3 className="text-sm font-semibold text-gray-900 truncate">{title}</h3>
        </div>
        <div className="flex items-center gap-2 flex-shrink-0">
          {action}
          <HealthBadge status={status} label={statusLabel} />
        </div>
      </div>

      {isEmpty ? (
        <p className="text-sm text-gray-500 py-4 text-center">{emptyMessage}</p>
      ) : (
        children
      )}
    </div>
  )
}
