import { fireEvent, render, screen } from '@testing-library/react'
import { describe, expect, it, vi } from 'vitest'
import { DecisionRow, type DecisionRowOption } from './DecisionRow'

const OPTIONS: DecisionRowOption[] = [
  { label: 'Pin 0.44 until M2 lands', recommended: true, choice: 'pin-044' },
  { label: 'Bump to 0.45 now', choice: 'bump-045' },
]

const BASE = {
  itemId: 'decision-drizzle',
  projectName: 'multideal',
  projectColor: '#7aa2f7',
  title: 'Pin drizzle-orm at 0.44 or bump to 0.45?',
  meta: 'factory dep-provisioning · phase 3/4',
  waitingAgeLabel: 'waiting 42m',
  options: OPTIONS,
}

describe('DecisionRow', () => {
  it('renders collapsed row chrome from the mockup', () => {
    render(<DecisionRow {...BASE} />)
    expect(screen.getByText('Pin drizzle-orm at 0.44 or bump to 0.45?')).toBeInTheDocument()
    expect(screen.getByText('factory dep-provisioning · phase 3/4')).toBeInTheDocument()
    expect(screen.getByText('waiting 42m')).toBeInTheDocument()
    expect(screen.getByRole('button', { name: /Pin 0.44 until M2 lands/ })).toBeInTheDocument()
    expect(screen.getByPlaceholderText('Or answer in plain text…')).toBeInTheDocument()
  })

  it('toggles expanded detail when the title row is clicked', () => {
    const onToggleExpand = vi.fn()
    render(
      <DecisionRow
        {...BASE}
        expanded={false}
        onToggleExpand={onToggleExpand}
        question="Lockfile has drizzle-orm 0.44.2."
        dataBlock="affected: packages/db"
        contextKvs={[{ label: 'plan', value: 'factory-dep-provisioning' }]}
        journalRef="runstate/factory-dep-provisioning.log.jsonl:412"
      />,
    )

    expect(screen.queryByText('Full question from agent')).not.toBeInTheDocument()
    fireEvent.click(screen.getByRole('button', { name: /Pin drizzle-orm/ }))
    expect(onToggleExpand).toHaveBeenCalledOnce()
  })

  it('shows expanded sections and fires option / free-text callbacks', () => {
    const onSelectOption = vi.fn()
    const onSubmitFreeText = vi.fn()
    const onFreeTextChange = vi.fn()

    render(
      <DecisionRow
        {...BASE}
        expanded
        question="Lockfile has drizzle-orm 0.44.2."
        dataBlock="affected: packages/db"
        contextKvs={[{ label: 'plan', value: 'factory-dep-provisioning' }]}
        journalRef="runstate/factory-dep-provisioning.log.jsonl:412"
        freeTextValue="Use 0.44.2 exactly"
        onSelectOption={onSelectOption}
        onSubmitFreeText={onSubmitFreeText}
        onFreeTextChange={onFreeTextChange}
      />,
    )

    expect(screen.getByText('Full question from agent')).toBeInTheDocument()
    expect(screen.getByText('affected: packages/db')).toBeInTheDocument()
    expect(screen.getByText('runstate/factory-dep-provisioning.log.jsonl:412')).toBeInTheDocument()

    fireEvent.click(screen.getByRole('button', { name: /Pin 0.44 until M2 lands/ }))
    expect(onSelectOption).toHaveBeenCalledWith(OPTIONS[0])

    fireEvent.change(screen.getByPlaceholderText('Or answer in plain text…'), { target: { value: 'typed' } })
    expect(onFreeTextChange).toHaveBeenCalledWith('typed')

    fireEvent.click(screen.getByRole('button', { name: 'Send' }))
    expect(onSubmitFreeText).toHaveBeenCalledOnce()
  })

  it('marks old waiting age and preserves free text in the error state', () => {
    render(
      <DecisionRow
        {...BASE}
        isOld
        waitingAgeLabel="waiting 2d"
        answerState="error"
        errorMessage="Answer failed — try again"
        freeTextValue="keep this text"
      />,
    )

    expect(screen.getByText('waiting 2d')).toHaveClass('text-danger')
    expect(screen.getByText('Answer failed — try again')).toBeInTheDocument()
    expect(screen.getByDisplayValue('keep this text')).toBeInTheDocument()
  })
})
