import { describe, expect, it } from 'vitest'
import { sanitizeAndFormat, toTitleCase, toTitleCaseAll, toLowerCase, toUpperCase, preserveOriginal, getMaxLength } from './inputValidation'

describe('toTitleCase', () => {
  it('uppercases first letter and lowercases rest of each word', () => {
    expect(toTitleCase('john doe')).toBe('John Doe')
    expect(toTitleCase('MARIA')).toBe('Maria')
    expect(toTitleCase('new york')).toBe('New York')
  })

  it('preserves numbers and special chars that survive sanitization', () => {
    expect(toTitleCase('123 main st.')).toBe('123 Main St.')
  })

  it('handles single word', () => {
    expect(toTitleCase('hello')).toBe('Hello')
  })
})

describe('toTitleCaseAll', () => {
  it('uppercases first letter of every word', () => {
    expect(toTitleCaseAll('acme corporation ltd.')).toBe('Acme Corporation Ltd.')
    expect(toTitleCaseAll('123 main street, apt 4b')).toBe('123 Main Street, Apt 4b')
  })
})

describe('toLowerCase', () => {
  it('lowercases all characters', () => {
    expect(toLowerCase('John.Doe@Example.COM')).toBe('john.doe@example.com')
    expect(toLowerCase('ALLCAPS')).toBe('allcaps')
  })
})

describe('toUpperCase', () => {
  it('uppercases letters, leaves numbers unchanged', () => {
    expect(toUpperCase('abc-123')).toBe('ABC-123')
    expect(toUpperCase('ab123cd')).toBe('AB123CD')
  })
})

describe('preserveOriginal', () => {
  it('returns the string unchanged', () => {
    expect(preserveOriginal('SW1A 1AA')).toBe('SW1A 1AA')
    expect(preserveOriginal('12345')).toBe('12345')
  })
})

describe('sanitizeAndFormat', () => {
  // ─── Title Case fields

  it('formats name fields (title case, max 50)', () => {
    expect(sanitizeAndFormat('john doe', 'name')).toBe('John Doe')
    expect(sanitizeAndFormat('MARIA', 'name')).toBe('Maria')
  })

  it('formats streetAddress (title case, max 100)', () => {
    expect(sanitizeAndFormat('123 main st.', 'streetAddress')).toBe('123 Main St')
    expect(sanitizeAndFormat('elm street 42', 'streetAddress')).toBe('Elm Street 42')
  })

  it('formats city (title case, max 50)', () => {
    expect(sanitizeAndFormat('new york', 'city')).toBe('New York')
  })

  it('formats pickupLocation and returnLocation', () => {
    expect(sanitizeAndFormat('airport terminal 1', 'pickupLocation')).toBe('Airport Terminal 1')
    expect(sanitizeAndFormat('downtown garage', 'returnLocation')).toBe('Downtown Garage')
  })

  it('formats country (title case)', () => {
    expect(sanitizeAndFormat('united kingdom', 'country')).toBe('United Kingdom')
  })

  // ─── Title Case All fields

  it('formats fullAddress (title case all, max 200)', () => {
    expect(sanitizeAndFormat('123 main street, apt 4b', 'fullAddress')).toBe('123 Main Street, Apt 4b')
  })

  it('formats commercialName (title case all, max 100)', () => {
    expect(sanitizeAndFormat('acme corporation', 'commercialName')).toBe('Acme Corporation')
  })

  it('formats legalCompanyName (title case all, max 100)', () => {
    expect(sanitizeAndFormat('global rentals llc', 'legalCompanyName')).toBe('Global Rentals Llc')
  })

  // ─── Email

  it('formats email (lowercase)', () => {
    expect(sanitizeAndFormat('John.Doe@Example.COM', 'email')).toBe('john.doe@example.com')
  })

  // ─── Uppercase fields

  it('formats licensePlate (uppercase, preserves hyphens)', () => {
    expect(sanitizeAndFormat('abc-123', 'licensePlate')).toBe('ABC-123')
  })

  it('formats VIN (uppercase)', () => {
    expect(sanitizeAndFormat('1hgbh41jxmn109186', 'vin')).toBe('1HGBH41JXMN109186')
  })

  it('formats passportNumber (uppercase)', () => {
    expect(sanitizeAndFormat('ab123456', 'passportNumber')).toBe('AB123456')
  })

  it('formats driverLicenseNumber (uppercase, preserves hyphens)', () => {
    expect(sanitizeAndFormat('d123-456-789', 'driverLicenseNumber')).toBe('D123-456-789')
  })

  it('formats licenseCategory (uppercase)', () => {
    expect(sanitizeAndFormat('b', 'licenseCategory')).toBe('B')
  })

  // ─── Car fields

  it('formats carMark (title case)', () => {
    expect(sanitizeAndFormat('TOYOTA', 'carMark')).toBe('Toyota')
    expect(sanitizeAndFormat('mercedes-benz', 'carMark')).toBe('Mercedes-Benz')
  })

  it('formats carModel (title case)', () => {
    expect(sanitizeAndFormat('corolla', 'carModel')).toBe('Corolla')
  })

  it('formats carColor (title case)', () => {
    expect(sanitizeAndFormat('midnight-blue', 'carColor')).toBe('Midnight-Blue')
  })

  // ─── ZIP Code (preserved)

  it('preserves ZIP code format', () => {
    expect(sanitizeAndFormat('12345', 'zipCode')).toBe('12345')
    expect(sanitizeAndFormat('SW1A 1AA', 'zipCode')).toBe('SW1A 1AA')
  })

  // ─── Sanitization

  it('removes disallowed characters', () => {
    expect(sanitizeAndFormat('John!@#', 'name')).toBe('John')
  })

  it('strips disallowed characters including angle brackets', () => {
    const result = sanitizeAndFormat('test<script>alert(1)</script>', 'name')
    expect(result).toBe('Testscriptalertscript')
  })

  // ─── Truncation

  it('truncates to max length', () => {
    const longName = 'A'.repeat(60)
    expect(sanitizeAndFormat(longName, 'name')).toHaveLength(50)
  })

  it('does not truncate strings within limit', () => {
    expect(sanitizeAndFormat('John', 'name')).toHaveLength(4)
  })
})

describe('getMaxLength', () => {
  it('returns correct max lengths', () => {
    expect(getMaxLength('name')).toBe(50)
    expect(getMaxLength('streetAddress')).toBe(100)
    expect(getMaxLength('fullAddress')).toBe(200)
    expect(getMaxLength('email')).toBe(100)
    expect(getMaxLength('licensePlate')).toBe(30)
    expect(getMaxLength('zipCode')).toBe(10)
    expect(getMaxLength('carMark')).toBe(30)
  })
})

