import { describe, expect, it } from 'vitest'
import { buildRedactionMap, redactForPrompt, substitutePseudoIds } from './redact.js'

describe('redact', () => {
  it('scrubs PII then de-anonymizes via substitutePseudoIds', () => {
    const users = new Map([
      [
        'u1',
        {
          id: 'u1',
          email: 'alice@example.com',
          phone: '+1 (555) 123-4567',
        },
      ],
    ])
    const vendors = new Map([
      ['v1', { id: 'v1', ownerEmail: 'vendor@shop.com', ownerPhone: null }],
    ])

    const map = buildRedactionMap(users, vendors)
    const raw =
      'Contact alice@example.com or +1 (555) 123-4567 and vendor vendor@shop.com'
    const redacted = redactForPrompt(raw, map)

    // Security floor: BOTH email AND phone must leave the prompt — no PII reaches the provider.
    expect(redacted).not.toContain('alice@example.com')
    expect(redacted).not.toContain('vendor@shop.com')
    expect(redacted).not.toContain('555')
    expect(redacted).not.toMatch(/\d{3}/)
    // One pseudo-id per entity (by design): email + phone both collapse to {user_a}.
    expect(redacted).toBe('Contact {user_a} or {user_a} and vendor {vendor_a}')

    const restored = substitutePseudoIds(redacted, map)
    // De-anon restores the entity's primary (email); the inverse genuinely round-trips.
    expect(restored).toBe(
      'Contact alice@example.com or alice@example.com and vendor vendor@shop.com',
    )
  })

  it('returns text unchanged when the redaction map is empty', () => {
    const map = buildRedactionMap(new Map(), new Map())
    const text = 'no pii here'
    expect(redactForPrompt(text, map)).toBe(text)
    expect(substitutePseudoIds(text, map)).toBe(text)
  })
})
