import * as React from 'react'
import { cn } from '../../lib/utils'
import { Rss } from 'lucide-react'
import { formatRelativeTime } from '../../utils'
import { HealthCard, HealthDot } from './HealthCard'
import { worstStatus, type HealthStatus } from './health-status'

export interface SourceFreshnessItem {
  name: string
  /** Last time this source delivered data. Null/undefined = never = stale. */
  lastUpdated?: string | Date | null
  /** Explicit status; otherwise derived from lastUpdated vs staleAfterHours. */
  status?: HealthStatus
}

export interface SourceFreshnessProps {
  title?: string
  sources: SourceFreshnessItem[]
  /** A source with no update within this window is stale (default 48h). */
  staleAfterHours?: number
  /** Compare against this instant (injectable for tests); defaults to Date.now(). */
  now?: number
  emptyMessage?: string
  className?: string
}

function deriveStatus(item: SourceFreshnessItem, staleAfterHours: number, now: number): HealthStatus {
  if (item.status) return item.status
  if (!item.lastUpdated) return 'critical'
  const ts = new Date(item.lastUpdated).getTime()
  if (Number.isNaN(ts)) return 'neutral'
  const ageHours = (now - ts) / 3_600_000
  if (ageHours <= staleAfterHours) return 'ok'
  if (ageHours <= staleAfterHours * 2) return 'warn'
  return 'critical'
}

/**
 * Source / ingestion freshness: which upstream feeds are fresh vs stale. A stale
 * source is a bug (everything is ongoing — no one-time fetches), so any stale
 * feed pulls the whole card to warn/critical. Presentational — a tenant widget
 * feeds it the source records + their last-fetched markers.
 */
export function SourceFreshness({
  title = 'Source freshness',
  sources,
  staleAfterHours = 48,
  now,
  emptyMessage = 'No sources configured.',
  className,
}: SourceFreshnessProps) {
  const at = now ?? Date.now()
  const rows = sources.map((s) => ({ ...s, resolved: deriveStatus(s, staleAfterHours, at) }))
  const staleCount = rows.filter((r) => r.resolved === 'warn' || r.resolved === 'critical').length
  const status = worstStatus(rows.map((r) => r.resolved))
  const statusLabel = sources.length === 0 ? undefined : staleCount > 0 ? `${staleCount} stale` : 'All fresh'

  return (
    <HealthCard
      title={title}
      status={status}
      statusLabel={statusLabel}
      icon={Rss}
      isEmpty={sources.length === 0}
      emptyMessage={emptyMessage}
      className={className}
    >
      <ul className="space-y-2" aria-label={`${title} sources`}>
        {rows.map((row) => (
          <li key={row.name} className="flex items-center justify-between gap-3 text-sm">
            <span className="flex items-center gap-2 min-w-0">
              <HealthDot status={row.resolved} />
              <span className="text-gray-700 truncate">{row.name}</span>
            </span>
            <span
              className={cn(
                'text-xs tabular-nums flex-shrink-0',
                row.resolved === 'ok' ? 'text-gray-500' : 'text-gray-900 font-medium',
              )}
            >
              {row.lastUpdated ? formatRelativeTime(row.lastUpdated) : 'never'}
            </span>
          </li>
        ))}
      </ul>
    </HealthCard>
  )
}
