import { describe, expect, it } from 'vitest'
import { reviveVendor, reviveOptionalVendor } from './revive.js'
import { isMarketplaceWireError } from './errors.js'

const wireVendor = (over: Record<string, unknown> = {}) => ({
  id: 'v1',
  ownerUserId: 'u1',
  name: 'Acme',
  status: 'approved',
  commissionBps: 1000,
  createdAt: '2026-06-01T12:00:00.000Z',
  updatedAt: '2026-06-02T12:00:00.000Z',
  ...over,
})

describe('reviveVendor', () => {
  it('happy path: all valid fields → returns Vendor with correct types', () => {
    const v = reviveVendor(wireVendor())
    expect(v.id).toBe('v1')
    expect(v.ownerUserId).toBe('u1')
    expect(v.name).toBe('Acme')
    expect(v.status).toBe('approved')
    expect(v.commissionBps).toBe(1000)
    expect(v.createdAt).toBeInstanceOf(Date)
    expect(v.updatedAt).toBeInstanceOf(Date)
    expect(v.createdAt.toISOString()).toBe('2026-06-01T12:00:00.000Z')
    expect(v.updatedAt.toISOString()).toBe('2026-06-02T12:00:00.000Z')
  })

  it("invalid status ('unknown') → throws MarketplaceWireError", () => {
    expect(() => reviveVendor(wireVendor({ status: 'unknown' }))).toThrow()
    try {
      reviveVendor(wireVendor({ status: 'unknown' }))
    } catch (e) {
      expect(isMarketplaceWireError(e)).toBe(true)
    }
  })

  it('commissionBps float (1.5) → throws MarketplaceWireError', () => {
    expect(() => reviveVendor(wireVendor({ commissionBps: 1.5 }))).toThrow()
    try {
      reviveVendor(wireVendor({ commissionBps: 1.5 }))
    } catch (e) {
      expect(isMarketplaceWireError(e)).toBe(true)
    }
  })

  it('commissionBps NaN → throws MarketplaceWireError', () => {
    expect(() => reviveVendor(wireVendor({ commissionBps: NaN }))).toThrow()
    try {
      reviveVendor(wireVendor({ commissionBps: NaN }))
    } catch (e) {
      expect(isMarketplaceWireError(e)).toBe(true)
    }
  })

  it('commissionBps out-of-range (10001) → throws MarketplaceWireError', () => {
    expect(() => reviveVendor(wireVendor({ commissionBps: 10001 }))).toThrow()
    try {
      reviveVendor(wireVendor({ commissionBps: 10001 }))
    } catch (e) {
      expect(isMarketplaceWireError(e)).toBe(true)
    }
  })

  it('commissionBps negative (-1) → throws MarketplaceWireError', () => {
    expect(() => reviveVendor(wireVendor({ commissionBps: -1 }))).toThrow()
    try {
      reviveVendor(wireVendor({ commissionBps: -1 }))
    } catch (e) {
      expect(isMarketplaceWireError(e)).toBe(true)
    }
  })

  it('missing id (null) → throws MarketplaceWireError', () => {
    expect(() => reviveVendor(wireVendor({ id: null }))).toThrow()
    try {
      reviveVendor(wireVendor({ id: null }))
    } catch (e) {
      expect(isMarketplaceWireError(e)).toBe(true)
    }
  })

  it("invalid date string ('not-a-date') → throws MarketplaceWireError", () => {
    expect(() => reviveVendor(wireVendor({ createdAt: 'not-a-date' }))).toThrow()
    try {
      reviveVendor(wireVendor({ createdAt: 'not-a-date' }))
    } catch (e) {
      expect(isMarketplaceWireError(e)).toBe(true)
    }
  })
})

describe('reviveOptionalVendor', () => {
  it('null → returns null', () => {
    expect(reviveOptionalVendor(null)).toBeNull()
  })

  it('undefined → returns null', () => {
    expect(reviveOptionalVendor(undefined)).toBeNull()
  })

  it('valid wire → returns Vendor', () => {
    const v = reviveOptionalVendor(wireVendor())
    expect(v).not.toBeNull()
    expect(v!.id).toBe('v1')
    expect(v!.status).toBe('approved')
  })
})
