/** @vitest-environment jsdom */
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom/vitest'
import { describe, expect, it } from 'vitest'
import { AutopsyStrip } from './AutopsyStrip'
import type { AttemptRecord } from './attempt-record'

const NOW_MS = Date.parse('2026-08-04T03:00:00.000Z')

function attempt(overrides: Partial<AttemptRecord> = {}): AttemptRecord {
  return {
    attemptId: 'attempt-done',
    task: 't1',
    phase: 'coder',
    seat: 'coder',
    model: 'gpt-test',
    wrapper: '/tmp/agent.sh',
    timeoutSecs: 120,
    promptPath: '/run/attempts/attempt-done.prompt.md',
    promptSha: 'a'.repeat(64),
    causalInput: 't1:initial',
    valid: true,
    replyPath: '/run/attempts/attempt-done.reply.json',
    usage: { inputTokens: 11, outputTokens: 7, model: 'gpt-test' },
    liveness: null,
    activity: {
      toolCalls: 6,
      filesTouched: ['src/app.js'],
      repeatedCommands: [['bash', 'npm test']],
      failureFingerprint: 'coder:coder:gpt-test',
    },
    ...overrides,
  }
}

describe('AutopsyStrip', () => {
  it('renders one marker per attempt in journal order for failed runs', () => {
    const attempts = [
      attempt({ attemptId: 'attempt-first', verdict: 'PASS', failureClass: 'gate-failed' }),
      attempt({ attemptId: 'attempt-second', verdict: 'FAIL', valid: false, causalInput: 'gate-error:abc', failureClass: 'timeout' }),
      attempt({ attemptId: 'attempt-third', verdict: 'PASS', causalInput: 'review-findings:def' }),
    ]

    render(<AutopsyStrip attempts={attempts} runStatus="failed" nowMs={NOW_MS} />)

    const markers = [
      screen.getByTestId('autopsy-marker-attempt-first'),
      screen.getByTestId('autopsy-marker-attempt-second'),
      screen.getByTestId('autopsy-marker-attempt-third'),
    ]
    expect(markers).toHaveLength(3)
    expect(markers[0]).toHaveAttribute('data-marker-index', '0')
    expect(markers[1]).toHaveAttribute('data-marker-index', '1')
    expect(markers[2]).toHaveAttribute('data-marker-index', '2')
    expect(markers[0]).toHaveTextContent('PASS')
    expect(markers[1]).toHaveTextContent('FAIL')
    expect(markers[2]).toHaveTextContent('PASS')
    expect(screen.getByTestId('autopsy-transition-attempt-second')).toHaveTextContent('gate-failed')
    expect(screen.getByTestId('autopsy-transition-attempt-second')).toHaveTextContent('gate-error:abc')
    expect(screen.getByTestId('autopsy-transition-attempt-third')).toHaveTextContent('timeout')
    expect(screen.getByTestId('autopsy-transition-attempt-third')).toHaveTextContent('review-findings:def')
  })

  it('marks stalled attempts using isAttemptAlarmed', () => {
    const stalled = attempt({
      attemptId: 'attempt-stalled',
      timeoutSecs: 60,
      liveness: {
        elapsedSecs: 200,
        lastActivity: 'tool_call:bash',
        lastSignalAt: '2026-08-04T02:50:00.000Z',
      },
    })

    render(<AutopsyStrip attempts={[stalled]} runStatus="blocked" nowMs={NOW_MS} />)

    expect(screen.getByTestId('autopsy-marker-attempt-stalled')).toHaveAttribute('data-alarmed', 'true')
  })

  it('enters warning state at exactly three attempts', () => {
    const twoAttempts = [
      attempt({ attemptId: 'attempt-a' }),
      attempt({ attemptId: 'attempt-b' }),
    ]
    const threeAttempts = [
      attempt({ attemptId: 'attempt-a' }),
      attempt({ attemptId: 'attempt-b' }),
      attempt({ attemptId: 'attempt-c' }),
    ]

    const { rerender } = render(<AutopsyStrip attempts={twoAttempts} runStatus="failed" nowMs={NOW_MS} />)
    expect(screen.getByTestId('autopsy-strip')).toHaveAttribute('data-warning', 'false')
    expect(screen.queryByTestId('autopsy-strip-warning')).not.toBeInTheDocument()

    rerender(<AutopsyStrip attempts={threeAttempts} runStatus="failed" nowMs={NOW_MS} />)
    expect(screen.getByTestId('autopsy-strip')).toHaveAttribute('data-warning', 'true')
    expect(screen.getByTestId('autopsy-strip-warning')).toHaveTextContent('3+ attempts')
  })

  it('does not render for healthy running or succeeded runs even with attempts present', () => {
    const attempts = [
      attempt({
        attemptId: 'attempt-healthy',
        verdict: 'PASS',
        valid: true,
        activity: { toolCalls: 1 },
      }),
    ]

    const { rerender, container } = render(
      <AutopsyStrip attempts={attempts} runStatus="running" nowMs={NOW_MS} />,
    )
    expect(screen.queryByTestId('autopsy-strip')).not.toBeInTheDocument()
    expect(container).toBeEmptyDOMElement()

    rerender(<AutopsyStrip attempts={attempts} runStatus="succeeded" nowMs={NOW_MS} />)
    expect(screen.queryByTestId('autopsy-strip')).not.toBeInTheDocument()
    expect(container).toBeEmptyDOMElement()
  })

  it('renders for blocked runs with attempt history', () => {
    render(
      <AutopsyStrip
        attempts={[
          attempt({
            attemptId: 'attempt-blocked',
            verdict: 'FAIL',
            valid: false,
            activity: { toolCalls: 1 },
          }),
        ]}
        runStatus="blocked"
        nowMs={NOW_MS}
      />,
    )

    expect(screen.getByTestId('autopsy-strip')).toHaveAttribute('data-warning', 'false')
    expect(screen.queryByTestId('autopsy-strip-warning')).not.toBeInTheDocument()
    expect(screen.getByTestId('autopsy-marker-attempt-blocked')).toHaveAttribute('data-alarmed', 'false')
  })
})

describe('AutopsyStrip quarantine', () => {
  it('renders the quarantine reason chip when a run is quarantined', () => {
    render(
      <AutopsyStrip
        attempts={[]}
        runStatus="quarantined"
        nowMs={NOW_MS}
        quarantine={{ phase: 'quality', reason: 'review rejected twice' }}
      />,
    )
    const quarantine = screen.getByTestId('autopsy-quarantine')
    expect(quarantine).toHaveTextContent('quarantined')
    expect(quarantine).toHaveTextContent('quality')
    expect(quarantine).toHaveTextContent('review rejected twice')
    const statusChip = quarantine.querySelector('[data-testid="status-chip"]')
    expect(statusChip).not.toBeNull()
    expect(statusChip).toHaveAttribute('data-status-category', 'needs-you')
    expect(statusChip).toHaveTextContent('quarantined')
  })

  it('renders nothing for a healthy run without quarantine', () => {
    const { container } = render(
      <AutopsyStrip attempts={[]} runStatus="running" nowMs={NOW_MS} quarantine={null} />,
    )
    expect(container).toBeEmptyDOMElement()
  })
})
