import { describe, expect, it } from 'vitest'
import { canAssignCarrier, carrierIdLine, resolveCarrier, sameCarrierName, type CarrierSummary } from '@/lib/domain/carrier-assignment'

/**
 * Which carrier is performing a trip (Nash, 2026-09-19): the broker must see
 * the carrier name, MC and DOT on Overview. One relation → attached by
 * default. Several → the dispatcher chooses first, and nothing is shown
 * until then. Synchron-imported trips arrive already assigned.
 */

const PAN: CarrierSummary = { id: 'c-pan', name: 'PAN LOGISTICS INC', mc: '1130384', dot: '3462028' }
const ATLAS: CarrierSummary = { id: 'c-atlas', name: 'ATLAS LOGISTICS GROUP INC', mc: '1470761', dot: '3951531' }

describe('resolveCarrier', () => {
  it('an assigned carrier (e.g. an imported trip) wins over everything', () => {
    expect(resolveCarrier({ assigned: PAN, hasDispatcherAccount: true, dispatcherCarriers: [ATLAS] })).toEqual({ kind: 'assigned', carrier: PAN })
  })

  it('one relation → attached by default', () => {
    expect(resolveCarrier({ assigned: null, hasDispatcherAccount: true, dispatcherCarriers: [PAN] })).toEqual({ kind: 'auto', carrier: PAN })
  })

  it('several relations → the dispatcher must choose; nothing is shown yet', () => {
    const r = resolveCarrier({ assigned: null, hasDispatcherAccount: true, dispatcherCarriers: [PAN, ATLAS] })
    expect(r.kind).toBe('choose')
    if (r.kind === 'choose') expect(r.options.map((c) => c.name)).toEqual(['ATLAS LOGISTICS GROUP INC', 'PAN LOGISTICS INC'])
  })

  it('the same carrier through two dispatchers is still one relation → auto', () => {
    expect(resolveCarrier({ assigned: null, hasDispatcherAccount: true, dispatcherCarriers: [PAN, PAN] })).toEqual({ kind: 'auto', carrier: PAN })
  })

  it('one relation, but the trip names a different carrier → the dispatcher confirms', () => {
    expect(resolveCarrier({ assigned: null, hasDispatcherAccount: true, dispatcherCarriers: [PAN], tripCarrierName: 'ATLAS LOGISTICS GROUP INC' })).toEqual({ kind: 'choose', options: [PAN] })
  })

  it('one relation and the trip names the same carrier (any punctuation/case) → auto', () => {
    expect(resolveCarrier({ assigned: null, hasDispatcherAccount: true, dispatcherCarriers: [PAN], tripCarrierName: 'Pan Logistics, Inc.' })).toEqual({ kind: 'auto', carrier: PAN })
    expect(resolveCarrier({ assigned: null, hasDispatcherAccount: true, dispatcherCarriers: [PAN], tripCarrierName: '' })).toEqual({ kind: 'auto', carrier: PAN })
  })

  it('no dispatcher with an account yet → nothing to resolve', () => {
    expect(resolveCarrier({ assigned: null, hasDispatcherAccount: false, dispatcherCarriers: [] })).toEqual({ kind: 'none', reason: 'no_dispatcher' })
  })

  it('a dispatcher with no carrier relation → nothing to resolve', () => {
    expect(resolveCarrier({ assigned: null, hasDispatcherAccount: true, dispatcherCarriers: [] })).toEqual({ kind: 'none', reason: 'no_relations' })
  })
})

describe('who may choose the carrier', () => {
  it('the dispatcher and an admin; not the broker or driver', () => {
    expect(canAssignCarrier({ viewerRole: 'dispatcher', viewerIsAdmin: false })).toBe(true)
    expect(canAssignCarrier({ viewerRole: 'broker', viewerIsAdmin: true })).toBe(true)
    expect(canAssignCarrier({ viewerRole: 'broker', viewerIsAdmin: false })).toBe(false)
    expect(canAssignCarrier({ viewerRole: 'driver', viewerIsAdmin: false })).toBe(false)
    expect(canAssignCarrier({ viewerRole: null, viewerIsAdmin: false })).toBe(false)
  })
})

describe('the MC · DOT line', () => {
  it('shows what is known', () => {
    expect(carrierIdLine(PAN)).toBe('MC 1130384 · DOT 3462028')
    expect(carrierIdLine({ mc: '123', dot: null })).toBe('MC 123')
    expect(carrierIdLine({ mc: null, dot: null })).toBe('')
  })
})

describe('sameCarrierName', () => {
  it('ignores case and punctuation, not letters', () => {
    expect(sameCarrierName('PAN LOGISTICS INC', 'Pan Logistics, Inc.')).toBe(true)
    expect(sameCarrierName('PAN LOGISTICS INC', 'PAN LOGISTICS LLC')).toBe(false)
  })
})
