import { render, screen, waitFor } from '@testing-library/react'
import '@testing-library/jest-dom/vitest'
import React from 'react'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { useFactoryRun } from '../../lib/collector-queries'
import { RequestWorkEvidence } from './RequestWorkEvidence'

vi.mock('../../lib/collector-queries', () => ({ useFactoryRun: vi.fn() }))
vi.mock('../factory/FactoryPhaseTable', () => ({ FactoryPhaseTable: () => <div>Recorded phases and retries</div> }))
vi.mock('../factory/FactoryTraceTables', () => ({
  FactoryAttemptTable: () => <div>Recorded tools, sessions, hosts, and accounts</div>,
  FactoryGateTable: () => <div>Recorded gate verdict</div>,
  FactoryDiffTable: () => <div>Recorded structured diff</div>,
}))

const runQuery = vi.mocked(useFactoryRun)

afterEach(() => {
  vi.restoreAllMocks()
})

describe('RequestWorkEvidence', () => {
  it('shows the named exact-link coverage gap without inventing a run', () => {
    render(<RequestWorkEvidence
      requestId="manual-unlinked"
      links={[]}
      attachments={[]}
      coverage={{
        fact: 'work_evidence',
        status: 'unavailable',
        sourceId: 'request-evidence-links',
        reason: 'No exact work run, gate, tool, or change link was recorded for this request.',
      }}
    />)

    expect(screen.getByText('No exact work run, gate, tool, or change link was recorded for this request.')).toBeInTheDocument()
    expect(screen.queryByText('Open full run')).not.toBeInTheDocument()
    expect(runQuery).not.toHaveBeenCalled()
  })

  it('loads only the explicitly linked Factory run and renders its recorded evidence', () => {
    runQuery.mockReturnValue({
      data: {
        adwId: 'adw-exact-42', repo: '/repo', repoName: 'repo', adwName: 'build', runSlug: null,
        request: 'same prose', status: 'success', engineer: 'factory', startedAt: null, endedAt: null,
        totalTokens: null, totalCost: null, detailAvailable: true,
        phases: [{ phaseId: 'phase-1' }], attempts: [{}], gates: [{}], diffs: [{}], events: [], decisions: [],
      },
      isPending: false,
      isError: false,
    } as unknown as ReturnType<typeof useFactoryRun>)

    render(<RequestWorkEvidence
      requestId="manual-exact"
      links={[{
        kind: 'factory_run', targetSource: 'factory-trace', targetId: 'adw-exact-42',
        occurredAt: '2026-08-18T00:00:00Z', sourceId: 'factory-trace', sourceEventId: 'link-1',
        metadata: { status: 'success' },
      }]}
      attachments={[]}
      coverage={{ fact: 'work_evidence', status: 'complete', sourceId: 'factory-trace' }}
    />)

    expect(runQuery).toHaveBeenCalledWith('adw-exact-42', true, false)
    expect(screen.getByRole('link', { name: 'Open full run' })).toHaveAttribute('href', '/factory/adw-exact-42')
    expect(screen.getByText('Recorded phases and retries')).toBeInTheDocument()
    expect(screen.getByText('Recorded tools, sessions, hosts, and accounts')).toBeInTheDocument()
    expect(screen.getByText('Recorded gate verdict')).toBeInTheDocument()
    expect(screen.getByText('Recorded structured diff')).toBeInTheDocument()
  })

  it('loads an exact diff attachment through the request-authorized proxy path', async () => {
    runQuery.mockReturnValue({ isPending: false, isError: false } as ReturnType<typeof useFactoryRun>)
    const fetchMock = vi.spyOn(globalThis, 'fetch').mockResolvedValue(new Response('diff --git a/a b/a\n'))
    render(<RequestWorkEvidence
      requestId="manual-exact"
      links={[]}
      attachments={[{
        digest: `sha256:${'a'.repeat(64)}`,
        byteCount: 24,
        mediaType: 'text/x-diff',
        redactionStatus: 'not_required',
        truncated: false,
        status: 'available',
      }]}
      coverage={{ fact: 'work_evidence', status: 'complete', sourceId: 'request-evidence-links' }}
    />)

    await waitFor(() => expect(fetchMock).toHaveBeenCalledWith(
      `/api/collector/requests/manual-exact/attachments/sha256%3A${'a'.repeat(64)}`,
      expect.objectContaining({ signal: expect.any(AbortSignal) }),
    ))
    expect(await screen.findByLabelText('Recorded request change')).toBeInTheDocument()
  })
})
