import { describe, expect, it } from 'vitest'
import { isValidTransition } from './transition-validator.js'

const ticketAdjacency = {
  open: ['pending', 'closed'],
  pending: ['open', 'closed'],
  closed: [],
} as const

const caseAdjacency = {
  new: ['review', 'dismissed'],
  review: ['resolved', 'dismissed'],
  resolved: [],
  dismissed: [],
} as const

describe('isValidTransition', () => {
  it('accepts a legal edge from the host adjacency map', () => {
    expect(isValidTransition(ticketAdjacency, 'open', 'pending')).toBe(true)
  })

  it('rejects an illegal edge', () => {
    expect(isValidTransition(ticketAdjacency, 'open', 'resolved')).toBe(false)
  })

  it('rejects unknown from/to without throwing', () => {
    expect(() => isValidTransition(ticketAdjacency, 'missing', 'pending')).not.toThrow()
    expect(isValidTransition(ticketAdjacency, 'missing', 'pending')).toBe(false)
    expect(isValidTransition(ticketAdjacency, 'open', 'missing')).toBe(false)
  })

  it('lets a predicate guard veto an otherwise-legal edge', () => {
    const needsApproval = (ctx: { approved: boolean }) => ctx.approved
    expect(isValidTransition(caseAdjacency, 'review', 'resolved', needsApproval, { approved: true })).toBe(
      true,
    )
    expect(isValidTransition(caseAdjacency, 'review', 'resolved', needsApproval, { approved: false })).toBe(
      false,
    )
  })

  it('validates two host adjacency maps independently', () => {
    expect(isValidTransition(ticketAdjacency, 'pending', 'open')).toBe(true)
    expect(isValidTransition(caseAdjacency, 'pending', 'open')).toBe(false)
  })
})
