// Form Validation Tests

describe('Email Validation', () => {
  const emailRegex = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i

  it('should validate correct email addresses', () => {
    const validEmails = [
      'test@example.com',
      'user.name@example.co.uk',
      'user+tag@example.com',
      'test123@test-domain.com',
    ]

    validEmails.forEach((email) => {
      expect(emailRegex.test(email)).toBe(true)
    })
  })

  it('should reject invalid email addresses', () => {
    const invalidEmails = [
      'invalidemail',
      'user@',
      '@example.com',
      'user@.com',
      'user@example',
      'user name@example.com',
    ]

    invalidEmails.forEach((email) => {
      expect(emailRegex.test(email)).toBe(false)
    })
  })
})

describe('Password Validation', () => {
  const minLength = 6

  it('should accept passwords with minimum length', () => {
    expect('password123'.length >= minLength).toBe(true)
    expect('12345'.length >= minLength).toBe(false)
  })

  it('should handle empty passwords', () => {
    expect(''.length >= minLength).toBe(false)
  })

  it('should handle very long passwords', () => {
    const longPassword = 'a'.repeat(100)
    expect(longPassword.length >= minLength).toBe(true)
  })

  it('should accept special characters in passwords', () => {
    const specialCharPassword = 'P@ss!w0rd'
    expect(specialCharPassword.length >= minLength).toBe(true)
  })
})

describe('Password Confirmation Validation', () => {
  it('should match identical passwords', () => {
    const password = 'password123'
    const confirmation = 'password123'
    expect(password === confirmation).toBe(true)
  })

  it('should not match different passwords', () => {
    const password = 'password123'
    const confirmation = 'password456'
    expect(password === confirmation).toBe(false)
  })

  it('should be case sensitive', () => {
    const password = 'Password123'
    const confirmation = 'password123'
    expect(password === confirmation).toBe(false)
  })

  it('should detect trailing space differences', () => {
    const password = 'password123'
    const confirmation = 'password123 '
    expect(password === confirmation).toBe(false)
  })
})

describe('Required Field Validation', () => {
  it('should detect empty strings', () => {
    expect(''.trim().length > 0).toBe(false)
    expect('John'.trim().length > 0).toBe(true)
  })

  it('should detect whitespace-only strings', () => {
    expect('   '.trim().length > 0).toBe(false)
    expect(' John '.trim().length > 0).toBe(true)
  })

  it('should handle null and undefined', () => {
    expect((null as any)?.length).toBeUndefined()
    expect((undefined as any)?.length).toBeUndefined()
  })
})

describe('Form Data Validation', () => {
  interface LoginFormData {
    email: string
    password: string
    remember?: boolean
  }

  const validateLoginForm = (data: LoginFormData) => {
    const errors: Record<string, string> = {}

    if (!data.email) {
      errors.email = 'Email is required'
    } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(data.email)) {
      errors.email = 'Invalid email address'
    }

    if (!data.password) {
      errors.password = 'Password is required'
    } else if (data.password.length < 6) {
      errors.password = 'Password must be at least 6 characters'
    }

    return errors
  }

  it('should validate complete form data', () => {
    const validData: LoginFormData = {
      email: 'test@example.com',
      password: 'password123',
      remember: true,
    }

    const errors = validateLoginForm(validData)
    expect(Object.keys(errors).length).toBe(0)
  })

  it('should catch missing email', () => {
    const invalidData: LoginFormData = {
      email: '',
      password: 'password123',
    }

    const errors = validateLoginForm(invalidData)
    expect(errors.email).toBe('Email is required')
  })

  it('should catch invalid email format', () => {
    const invalidData: LoginFormData = {
      email: 'not-an-email',
      password: 'password123',
    }

    const errors = validateLoginForm(invalidData)
    expect(errors.email).toBe('Invalid email address')
  })

  it('should catch missing password', () => {
    const invalidData: LoginFormData = {
      email: 'test@example.com',
      password: '',
    }

    const errors = validateLoginForm(invalidData)
    expect(errors.password).toBe('Password is required')
  })

  it('should catch short password', () => {
    const invalidData: LoginFormData = {
      email: 'test@example.com',
      password: '12345',
    }

    const errors = validateLoginForm(invalidData)
    expect(errors.password).toBe('Password must be at least 6 characters')
  })

  it('should catch all errors at once', () => {
    const invalidData: LoginFormData = {
      email: 'invalid',
      password: '123',
    }

    const errors = validateLoginForm(invalidData)
    expect(errors.email).toBe('Invalid email address')
    expect(errors.password).toBe('Password must be at least 6 characters')
  })
})

describe('Registration Form Validation', () => {
  interface RegisterFormData {
    name: string
    email: string
    password: string
    password_confirmation: string
  }

  const validateRegisterForm = (data: RegisterFormData) => {
    const errors: Record<string, string> = {}

    if (!data.name || !data.name.trim()) {
      errors.name = 'Name is required'
    }

    if (!data.email) {
      errors.email = 'Email is required'
    } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(data.email)) {
      errors.email = 'Invalid email address'
    }

    if (!data.password) {
      errors.password = 'Password is required'
    } else if (data.password.length < 6) {
      errors.password = 'Password must be at least 6 characters'
    }

    if (!data.password_confirmation) {
      errors.password_confirmation = 'Please confirm your password'
    } else if (data.password_confirmation !== data.password) {
      errors.password_confirmation = 'Passwords do not match'
    }

    return errors
  }

  it('should validate complete registration data', () => {
    const validData: RegisterFormData = {
      name: 'John Doe',
      email: 'john@example.com',
      password: 'password123',
      password_confirmation: 'password123',
    }

    const errors = validateRegisterForm(validData)
    expect(Object.keys(errors).length).toBe(0)
  })

  it('should catch all missing required fields', () => {
    const invalidData: RegisterFormData = {
      name: '',
      email: '',
      password: '',
      password_confirmation: '',
    }

    const errors = validateRegisterForm(invalidData)
    expect(Object.keys(errors).length).toBe(4)
  })

  it('should catch password mismatch', () => {
    const invalidData: RegisterFormData = {
      name: 'John Doe',
      email: 'john@example.com',
      password: 'password123',
      password_confirmation: 'password456',
    }

    const errors = validateRegisterForm(invalidData)
    expect(errors.password_confirmation).toBe('Passwords do not match')
  })

  it('should validate whitespace-only name', () => {
    const invalidData: RegisterFormData = {
      name: '   ',
      email: 'john@example.com',
      password: 'password123',
      password_confirmation: 'password123',
    }

    const errors = validateRegisterForm(invalidData)
    expect(errors.name).toBe('Name is required')
  })
})
