/** @vitest-environment jsdom */
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import '@testing-library/jest-dom/vitest'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import type { Item } from '../../lib/collector-types'
import { DecisionsListBody } from './DecisionsApp'

const postCollectorAction = vi.hoisted(() => vi.fn())
const postDecisionAnswer = vi.hoisted(() => vi.fn())

vi.mock('../../lib/action-client', () => ({ postCollectorAction }))
vi.mock('../../lib/decision-answer', () => ({ postDecisionAnswer }))
vi.mock('../inbox/project-settings', () => ({ useProjectColorOverrides: () => [{}, vi.fn()] }))

function permissionItem(): Item {
  return {
    id: 'permission:boot:7',
    source: 'permissions',
    severity: 'act',
    kind: 'decision',
    title: 'Bash — awaiting approval',
    detail: '/home/user/Projects/overdeck',
    ts: new Date().toISOString(),
    actions: [
      { verb: 'permission.answer', args: { requestId: 'permission:boot:7', choice: 'allow' }, label: 'Allow' },
      { verb: 'permission.answer', args: { requestId: 'permission:boot:7', choice: 'deny' }, label: 'Deny' },
    ],
    decision: {
      question: 'Allow Bash in /home/user/Projects/overdeck?',
      options: [{ label: 'Allow' }, { label: 'Deny' }],
      freeText: false,
      context: '{"dataBlock":"{\\n  \\"command\\": \\"ls\\"\\n}"}',
      waitingSince: new Date().toISOString(),
    },
  }
}

beforeEach(() => {
  postCollectorAction.mockReset().mockResolvedValue({ ok: true })
  postDecisionAnswer.mockReset().mockResolvedValue(undefined)
})

describe('DecisionsListBody', () => {
  it('answers a queued tool permission through the collector permission queue', async () => {
    render(<DecisionsListBody items={[permissionItem()]} />)

    expect(screen.getByText('Bash — awaiting approval')).toBeInTheDocument()
    fireEvent.click(screen.getByRole('button', { name: 'Allow' }))

    await waitFor(() => expect(postCollectorAction).toHaveBeenCalledWith('permission.answer', {
      args: { requestId: 'permission:boot:7', choice: 'allow' },
      requestedBy: 'deck-web',
    }))
    expect(postDecisionAnswer).not.toHaveBeenCalled()
  })

  it('denies through the same queue', async () => {
    render(<DecisionsListBody items={[permissionItem()]} />)
    fireEvent.click(screen.getByRole('button', { name: 'Deny' }))
    await waitFor(() => expect(postCollectorAction).toHaveBeenCalledWith('permission.answer', {
      args: { requestId: 'permission:boot:7', choice: 'deny' },
      requestedBy: 'deck-web',
    }))
  })

  it('reports an empty queue rather than inventing a pending decision', () => {
    render(<DecisionsListBody items={[]} />)
    expect(screen.getByText(/No decisions waiting/)).toBeInTheDocument()
  })
})
