import { render, screen, fireEvent } from '@testing-library/react'
import {
  worstStatus,
  HealthCard,
  PipelineHealth,
  SourceFreshness,
  DeliveryHealth,
  AttentionFeed,
} from '../index'

const NOW = 1_700_000_000_000 // fixed instant for freshness/delivery derivation
const hoursAgo = (h: number) => new Date(NOW - h * 3_600_000).toISOString()
const hoursAhead = (h: number) => new Date(NOW + h * 3_600_000).toISOString()

describe('worstStatus', () => {
  it('returns neutral for an empty list', () => {
    expect(worstStatus([])).toBe('neutral')
  })
  it('escalates critical > warn > ok > neutral', () => {
    expect(worstStatus(['ok', 'neutral'])).toBe('ok')
    expect(worstStatus(['ok', 'warn'])).toBe('warn')
    expect(worstStatus(['ok', 'warn', 'critical'])).toBe('critical')
  })
})

describe('HealthCard', () => {
  it('renders the title and the tone badge', () => {
    render(<HealthCard title="Pipeline" status="ok" />)
    expect(screen.getByText('Pipeline')).toBeInTheDocument()
    expect(screen.getByText('Healthy')).toBeInTheDocument()
  })
  it('shows the empty message when isEmpty', () => {
    render(<HealthCard title="X" status="neutral" isEmpty emptyMessage="Nothing here" />)
    expect(screen.getByText('Nothing here')).toBeInTheDocument()
  })
  it('honors a custom status label', () => {
    render(<HealthCard title="X" status="warn" statusLabel="3 stale" />)
    expect(screen.getByText('3 stale')).toBeInTheDocument()
  })
})

describe('PipelineHealth', () => {
  const stages = [
    { label: 'draft', count: 4 },
    { label: 'review', count: 2 },
    { label: 'ready', count: 1 },
  ]
  it('renders every stage with its count', () => {
    render(<PipelineHealth title="Briefs" stages={stages} />)
    expect(screen.getByText('draft')).toBeInTheDocument()
    expect(screen.getByText('4')).toBeInTheDocument()
    expect(screen.getByText('7 total')).toBeInTheDocument()
  })
  it('flags attention items in the badge', () => {
    render(<PipelineHealth stages={stages} attention={2} />)
    expect(screen.getByText('2 need attention')).toBeInTheDocument()
  })
  it('renders the empty state when there are no records', () => {
    render(<PipelineHealth stages={[{ label: 'draft', count: 0 }]} emptyMessage="No records yet." />)
    expect(screen.getByText('No records yet.')).toBeInTheDocument()
  })
  it('calls onStageClick', () => {
    const onClick = jest.fn()
    render(<PipelineHealth stages={stages} onStageClick={onClick} />)
    fireEvent.click(screen.getByText('review'))
    expect(onClick).toHaveBeenCalledWith('review')
  })
})

describe('SourceFreshness', () => {
  it('reports all fresh when every source is recent', () => {
    render(
      <SourceFreshness
        now={NOW}
        staleAfterHours={48}
        sources={[
          { name: 'RSS A', lastUpdated: hoursAgo(2) },
          { name: 'RSS B', lastUpdated: hoursAgo(10) },
        ]}
      />,
    )
    expect(screen.getByText('All fresh')).toBeInTheDocument()
  })
  it('counts stale sources and shows "never" for missing timestamps', () => {
    render(
      <SourceFreshness
        now={NOW}
        staleAfterHours={48}
        sources={[
          { name: 'RSS A', lastUpdated: hoursAgo(2) },
          { name: 'RSS B', lastUpdated: hoursAgo(200) },
          { name: 'RSS C', lastUpdated: null },
        ]}
      />,
    )
    expect(screen.getByText('2 stale')).toBeInTheDocument()
    expect(screen.getByText('never')).toBeInTheDocument()
  })
})

describe('DeliveryHealth', () => {
  it('is on track when deliveries are on time', () => {
    render(
      <DeliveryHealth
        now={NOW}
        items={[{ label: 'Week 1', dueAt: hoursAgo(48), deliveredAt: hoursAgo(50) }]}
      />,
    )
    expect(screen.getByText('On track')).toBeInTheDocument()
  })
  it('flags missed and late deliveries', () => {
    render(
      <DeliveryHealth
        now={NOW}
        items={[
          { label: 'Week 1', dueAt: hoursAgo(10) }, // undelivered + past due => missed
          { label: 'Week 2', dueAt: hoursAhead(24) }, // upcoming
        ]}
      />,
    )
    expect(screen.getByText('1 off-track')).toBeInTheDocument()
  })
})

describe('AttentionFeed', () => {
  it('is all clear when empty', () => {
    render(<AttentionFeed items={[]} />)
    expect(screen.getByText('All clear')).toBeInTheDocument()
  })
  it('counts items to review and links them', () => {
    render(
      <AttentionFeed
        items={[
          { id: '1', label: 'Draft needs review', href: '/t/general/1' },
          { id: '2', label: 'Stuck brief' },
        ]}
      />,
    )
    expect(screen.getByText('2 to review')).toBeInTheDocument()
    expect(screen.getByRole('link', { name: /Draft needs review/ })).toHaveAttribute('href', '/t/general/1')
  })
})
