import { beforeEach, describe, expect, it, vi } from 'vitest'
import { createFakeSupabase } from './stubs/fake-supabase'
import { COMPANY_A, COMPANY_B, USER_ID, seedTrip } from './stubs/purchase-fixtures'
import type { SessionUser } from '@/lib/auth'

/**
 * Test J (docs/TASKS-2026-09-29-SYNCHRON-PURCHASING.md §13, §22–§23): a
 * person who is a Carrier Dispatcher at Company A and a Freight Broker at
 * Company B bills under the ACTIVE mode's company and cannot read a purchase
 * made under the other company.
 */

const db = createFakeSupabase()
vi.mock('@/lib/supabase/admin', () => ({ createAdminClient: () => db }))

const { resolveBillingContext, canViewPurchase } = await import('@/lib/data/billing-context')

const ROLE_A = 'a1a1a1a1-0000-4000-8000-000000000001'
const ROLE_B = 'b2b2b2b2-0000-4000-8000-000000000002'
const OTHER_USER = '99999999-9999-4999-8999-999999999999'

const sessionUser = (extra: Partial<SessionUser> = {}): SessionUser => ({
  id: USER_ID, email: 'dana@example.com', name: 'Dana', role: 'dispatcher', company: null, internal: false, originId: USER_ID, ...extra,
})

beforeEach(() => {
  db.reset()
  db.seed('profiles', [{ id: USER_ID, source_token: 'USERTOKEN1234567' }])
  db.seed('companies', [
    { id: COMPANY_A, name: 'Carrier A', source_token: 'CARRIERA12345678' },
    { id: COMPANY_B, name: 'Broker B', source_token: 'BROKERB123456789' },
  ])
  db.seed('membership_roles', [
    { id: ROLE_A, user_id: USER_ID, company_id: COMPANY_A, role_type: 'carrier_dispatcher', status: 'active' },
    { id: ROLE_B, user_id: USER_ID, company_id: COMPANY_B, role_type: 'freight_broker', status: 'active' },
  ])
})

describe('Test J — billing follows the active mode', () => {
  it('contextKey = the Company A role bills under Company A with its carrier token', async () => {
    const trip = seedTrip(db, { synchron_order_token: 'ABC12345', carrier_company_id: COMPANY_B })
    const result = await resolveBillingContext(sessionUser({ contextKey: ROLE_A }), trip)
    expect(result.ok).toBe(true)
    if (!result.ok) return
    expect(result.companyId).toBe(COMPANY_A)
    expect(result.billing).toEqual({
      hhaUserId: USER_ID, hhaCompanyId: COMPANY_A, synchronUserToken: 'USERTOKEN1234567',
      synchronCarrierToken: 'CARRIERA12345678', synchronOrderToken: 'ABC12345', hhaTripId: trip.id,
    })
  })

  it('contextKey = the Company B role bills under Company B', async () => {
    const trip = seedTrip(db)
    const result = await resolveBillingContext(sessionUser({ contextKey: ROLE_B }), trip)
    expect(result.ok && result.companyId).toBe(COMPANY_B)
    expect(result.ok && result.billing.synchronCarrierToken).toBe('BROKERB123456789')
  })

  it('with two roles and no active context, the trip carrier company wins only when the user holds a role there', async () => {
    const onTrip = await resolveBillingContext(sessionUser(), seedTrip(db, { carrier_company_id: COMPANY_A }))
    expect(onTrip.ok && onTrip.companyId).toBe(COMPANY_A)
    const elsewhere = await resolveBillingContext(sessionUser(), seedTrip(db, { carrier_company_id: 'cccccccc-cccc-4ccc-8ccc-cccccccccccc' }))
    expect(elsewhere.ok && elsewhere.companyId).toBeNull()
    expect(elsewhere.ok && elsewhere.billing.synchronCarrierToken).toBeNull()
  })
})

describe('Test J — reading a purchase under another company context', () => {
  const purchaseUnderB = { hha_user_id: OTHER_USER, company_id: COMPANY_B }

  it('is refused for the dispatcher without an approved billing membership there', async () => {
    await expect(canViewPurchase(sessionUser({ contextKey: ROLE_A }), purchaseUnderB)).resolves.toBe(false)
    await expect(canViewPurchase(sessionUser({ contextKey: ROLE_B }), purchaseUnderB)).resolves.toBe(false)
    // A pending or non-billing membership does not help either.
    db.seed('company_memberships', [{ user_id: USER_ID, company_id: COMPANY_B, role: 'billing_admin', status: 'pending' }])
    await expect(canViewPurchase(sessionUser(), purchaseUnderB)).resolves.toBe(false)
  })

  it('is allowed for the owner, an admin, or an approved billing member', async () => {
    await expect(canViewPurchase(sessionUser(), { hha_user_id: USER_ID, company_id: COMPANY_B })).resolves.toBe(true)
    await expect(canViewPurchase(sessionUser({ id: OTHER_USER, role: 'admin' }), purchaseUnderB)).resolves.toBe(true)
    await expect(canViewPurchase(sessionUser({ id: 'someone-else' }), purchaseUnderB)).resolves.toBe(false)
    db.seed('company_memberships', [{ user_id: USER_ID, company_id: COMPANY_B, role: 'billing_admin', status: 'approved' }])
    await expect(canViewPurchase(sessionUser(), purchaseUnderB)).resolves.toBe(true)
  })

  it('a personal purchase (no company) is visible only to its owner and admins', async () => {
    const personal = { hha_user_id: OTHER_USER, company_id: null }
    await expect(canViewPurchase(sessionUser(), personal)).resolves.toBe(false)
    await expect(canViewPurchase(sessionUser({ id: OTHER_USER }), personal)).resolves.toBe(true)
  })
})
