// @vitest-environment node
import { describe, expect, it, vi } from 'vitest'
import { createElement } from 'react'
import { renderToString as reactRenderToString } from 'react-dom/server'

vi.mock('next/navigation', () => ({ useRouter: () => ({ push: () => {}, refresh: () => {} }), useSearchParams: () => new URLSearchParams() }))
const render = (el: Parameters<typeof reactRenderToString>[0]) => reactRenderToString(el).replace(/<!--.*?-->/g, '')

import { PermitFeeLine, PermitFeeSummary } from '@/components/app/permit-cost'
import type { Permit } from '@/types/db'

/**
 * The permit-fee UI (Nash, 2026-09-24). The acceptance tests in §22 and §23,
 * plus §13: a pilot sees none of it.
 */
const permit = (over: Partial<Permit> & { id: string; state_code: string }): Permit =>
  ({ trip_id: 't1', document_id: null, permit_number: `${over.state_code}-1`, effective_date: null, expiration_date: '2027-01-01',
     permit_length_in: null, permit_width_in: null, permit_height_in: null, permit_weight_lbs: null, extraction: null, extraction_status: 'processed',
     permit_cost_currency: 'USD', created_at: '2026-09-24T00:00:00Z', ...over }) as Permit

const withFee = (state: string, amount: number) => permit({ id: state, state_code: state, permit_cost_amount: amount, permit_cost_status: 'found' })

describe('§22 — four permits, complete total', () => {
  const permits = [withFee('TX', 125), withFee('NM', 48), withFee('AZ', 36), withFee('OH', 92)]

  it('a broker sees each fee and a complete total with the disclaimer', () => {
    const html = render(createElement(PermitFeeSummary, { permits, myRole: 'broker', showLines: true }))
    expect(html).toContain('Total Permit Fees')
    expect(html).toContain('$301.00')
    expect(html).toContain('Does not include permitting-company service fees')
    expect(html).not.toContain('Known Permit Fees')
    expect(html).not.toContain('may be higher')
    for (const s of ['TX', 'NM', 'AZ', 'OH']) expect(html).toContain(s)
  })

  it('the fee shows on a permit card as "State Permit Fee"', () => {
    const html = render(createElement(PermitFeeLine, { permit: permits[0], myRole: 'broker', tripId: 't1' }))
    expect(html).toContain('State Permit Fee')
    expect(html).toContain('$125.00')
  })

  it('a carrier dispatcher and a carrier driver both see it', () => {
    for (const role of ['dispatcher', 'driver'] as const) {
      expect(render(createElement(PermitFeeSummary, { permits, myRole: role }))).toContain('$301.00')
    }
  })
})

describe('§23 — one fee missing', () => {
  const permits = [withFee('TX', 125), withFee('NM', 48), permit({ id: 'AZ', state_code: 'AZ', permit_cost_status: 'not_found' })]

  it('reads as Known Permit Fees and warns that the real total may be higher', () => {
    const html = render(createElement(PermitFeeSummary, { permits, myRole: 'broker', showLines: true }))
    expect(html).toContain('Known Permit Fees')
    expect(html).toContain('$173.00')
    expect(html).toContain('Permit fee was not detected for 1 permit')
    expect(html).toContain('may be higher')
    expect(html).not.toContain('Total Permit Fees')
  })

  it('§7 — a missing fee never renders as $0.00', () => {
    const html = render(createElement(PermitFeeLine, { permit: permits[2], myRole: 'broker', tripId: 't1' }))
    expect(html).toContain('State Permit Fee')
    expect(html).not.toContain('$0.00')
    expect(html).toContain('—')
  })
})

describe('§13 — pilots see nothing about cost', () => {
  const permits = [withFee('TX', 125), withFee('NM', 48)]
  it('renders nothing at all for a pilot', () => {
    expect(render(createElement(PermitFeeSummary, { permits, myRole: 'pilot' }))).toBe('')
    expect(render(createElement(PermitFeeLine, { permit: permits[0], myRole: 'pilot', tripId: 't1' }))).toBe('')
  })
  it('renders nothing when the role is unknown', () => {
    expect(render(createElement(PermitFeeSummary, { permits, myRole: null }))).toBe('')
    expect(render(createElement(PermitFeeLine, { permit: permits[0], myRole: null, tripId: 't1' }))).toBe('')
  })
  it('even with the fields stripped there is nothing to leak', () => {
    const stripped = permits.map((p) => { const c = { ...p } as Record<string, unknown>; delete c.permit_cost_amount; delete c.permit_cost_status; return c as unknown as Permit })
    expect(render(createElement(PermitFeeSummary, { permits: stripped, myRole: 'pilot' }))).toBe('')
  })
})

describe('needs review and corrections', () => {
  it('a permit needing review says so instead of showing a number', () => {
    const p = permit({ id: 'TX', state_code: 'TX', permit_cost_status: 'needs_review' })
    const html = render(createElement(PermitFeeLine, { permit: p, myRole: 'broker', tripId: 't1' }))
    expect(html).toContain('Needs review')
  })
  it('a corrected fee is labelled and shows the corrected amount', () => {
    const p = permit({ id: 'TX', state_code: 'TX', permit_cost_amount: 102, permit_cost_extracted_amount: 120, permit_cost_manual_override: 102, permit_cost_status: 'corrected', permit_cost_updated_by: 'Val Verified' })
    const html = render(createElement(PermitFeeLine, { permit: p, myRole: 'broker', tripId: 't1' }))
    expect(html).toContain('$102.00')
    expect(html).toContain('corrected')
    expect(html).not.toContain('$120.00')
  })
  it('a driver sees the fee but gets no edit control', () => {
    const p = withFee('TX', 125)
    expect(render(createElement(PermitFeeLine, { permit: p, myRole: 'driver', tripId: 't1' }))).not.toContain('Correct')
    expect(render(createElement(PermitFeeLine, { permit: p, myRole: 'broker', tripId: 't1' }))).toContain('Correct')
  })
  it('a revision left out of the total says so', () => {
    const permits = [withFee('TX', 125), permit({ id: 'TX2', state_code: 'TX', permit_number: 'TX-1R', permit_cost_amount: 125, permit_cost_status: 'found', supersedes_permit_id: 'TX' })]
    const html = render(createElement(PermitFeeSummary, { permits, myRole: 'broker' }))
    expect(html).toContain('$125.00')
    expect(html).toContain('no fee is counted twice')
  })
})
