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

export type DeliveryState = 'on_time' | 'upcoming' | 'late' | 'missed'

export interface DeliveryItem {
  label: string
  /** Explicit state; otherwise derived from due/delivered vs now. */
  status?: DeliveryState
  dueAt?: string | Date | null
  deliveredAt?: string | Date | null
}

export interface DeliveryHealthProps {
  title?: string
  items: DeliveryItem[]
  /** Compare against this instant (injectable for tests); defaults to Date.now(). */
  now?: number
  /** Cap the number of rows listed (summary counts still cover all). */
  limit?: number
  emptyMessage?: string
  className?: string
}

const STATE_TONE: Record<DeliveryState, HealthStatus> = {
  on_time: 'ok',
  upcoming: 'neutral',
  late: 'warn',
  missed: 'critical',
}

const STATE_LABEL: Record<DeliveryState, string> = {
  on_time: 'On time',
  upcoming: 'Upcoming',
  late: 'Late',
  missed: 'Missed',
}

function deriveState(item: DeliveryItem, now: number): DeliveryState {
  if (item.status) return item.status
  const due = item.dueAt ? new Date(item.dueAt).getTime() : null
  if (item.deliveredAt) {
    const delivered = new Date(item.deliveredAt).getTime()
    return due !== null && delivered > due ? 'late' : 'on_time'
  }
  if (due === null) return 'upcoming'
  return due < now ? 'missed' : 'upcoming'
}

/**
 * Delivery / schedule health: were scheduled deliverables (e.g. weekly briefs)
 * shipped on time? Missed/late deliveries drive the card critical/warn; upcoming
 * ones are informational. Presentational — a tenant widget derives states from a
 * type's scheduled_for / delivered_at fields.
 */
export function DeliveryHealth({
  title = 'Delivery',
  items,
  now,
  limit,
  emptyMessage = 'Nothing scheduled.',
  className,
}: DeliveryHealthProps) {
  const at = now ?? Date.now()
  const rows = items.map((it) => ({ ...it, state: deriveState(it, at) }))
  const counts = rows.reduce(
    (acc, r) => ((acc[r.state] += 1), acc),
    { on_time: 0, upcoming: 0, late: 0, missed: 0 } as Record<DeliveryState, number>,
  )
  const status = worstStatus(rows.map((r) => STATE_TONE[r.state]))
  const problems = counts.late + counts.missed
  const statusLabel =
    items.length === 0 ? undefined : problems > 0 ? `${problems} off-track` : 'On track'

  const listed = limit ? rows.slice(0, limit) : rows

  return (
    <HealthCard
      title={title}
      status={status}
      statusLabel={statusLabel}
      icon={CalendarClock}
      isEmpty={items.length === 0}
      emptyMessage={emptyMessage}
      className={className}
    >
      <div className="flex flex-wrap gap-x-4 gap-y-1 text-xs text-gray-600">
        {(['on_time', 'late', 'missed', 'upcoming'] as DeliveryState[])
          .filter((s) => counts[s] > 0)
          .map((s) => (
            <span key={s} className="inline-flex items-center gap-1.5">
              <HealthDot status={STATE_TONE[s]} />
              <span className="tabular-nums font-medium text-gray-900">{counts[s]}</span> {STATE_LABEL[s]}
            </span>
          ))}
      </div>

      <ul className="space-y-2" aria-label={`${title} items`}>
        {listed.map((row, i) => (
          <li key={`${row.label}-${i}`} className="flex items-center justify-between gap-3 text-sm">
            <span className="flex items-center gap-2 min-w-0">
              <HealthDot status={STATE_TONE[row.state]} />
              <span className="text-gray-700 truncate">{row.label}</span>
            </span>
            <span
              className={cn(
                'text-xs tabular-nums flex-shrink-0',
                STATE_TONE[row.state] === 'ok' ? 'text-gray-500' : 'text-gray-900 font-medium',
              )}
            >
              {STATE_LABEL[row.state]}
              {row.deliveredAt
                ? ` · ${formatRelativeTime(row.deliveredAt)}`
                : row.dueAt
                  ? ` · ${formatRelativeTime(row.dueAt)}`
                  : ''}
            </span>
          </li>
        ))}
      </ul>
    </HealthCard>
  )
}
