import { describe, expect, it } from 'vitest'

import type { CompletionResult } from './chat-client.js'
import { captureWork, parseCaptureArgs } from './capture-work.js'

describe('parseCaptureArgs', () => {
  it('validates issues and keeps only real titles + valid labels', () => {
    const p = parseCaptureArgs({
      issues: [
        { title: 'Fix token refresh', body: 'dies silently', estimate: 'est/2d', priority: 'p/1' },
        { title: '  ', body: 'blank title dropped' },
        { title: 'Docs', estimate: 'est/9d', priority: 'urgent' }, // invalid labels → dropped to undefined
      ],
      consequence: 'Beta slips a day',
    })
    expect(p.issues).toHaveLength(2)
    expect(p.issues[0]).toEqual({ title: 'Fix token refresh', body: 'dies silently', estimate: 'est/2d', priority: 'p/1' })
    expect(p.issues[1]).toEqual({ title: 'Docs', body: '', estimate: undefined, priority: undefined })
    expect(p.consequence).toBe('Beta slips a day')
  })

  it('tolerates a missing/!array issues field', () => {
    expect(parseCaptureArgs({}).issues).toEqual([])
    expect(parseCaptureArgs({ issues: 'nope' }).issues).toEqual([])
  })
})

describe('captureWork', () => {
  it('forces propose_issues and returns the validated set', async () => {
    const result: CompletionResult = {
      content: '',
      toolCalls: [
        {
          id: 'c1',
          name: 'propose_issues',
          arguments: JSON.stringify({
            issues: [{ title: 'Retry token refresh with backoff', body: '', estimate: 'est/2d', priority: 'p/2' }],
            consequence: 'no material shift',
          }),
        },
      ],
    }
    let sawTool = ''
    const proposal = await captureWork(async (_m, tools) => {
      sawTool = tools?.[0]?.name ?? ''
      return result
    }, 'auth is flaky, token refresh dies')
    expect(sawTool).toBe('propose_issues')
    expect(proposal.issues[0].title).toBe('Retry token refresh with backoff')
    expect(proposal.consequence).toBe('no material shift')
  })

  it('returns an empty set when the model answers without the tool', async () => {
    const proposal = await captureWork(async () => ({ content: 'I need more detail.', toolCalls: [] }), 'vague')
    expect(proposal.issues).toEqual([])
  })

  it('survives malformed tool arguments', async () => {
    const proposal = await captureWork(
      async () => ({ content: '', toolCalls: [{ id: 'c1', name: 'propose_issues', arguments: '{not json' }] }),
      'x',
    )
    expect(proposal.issues).toEqual([])
  })
})
