/**
 * (password strength checks, validity, change-password form gates).
 */
import {
  getPasswordChecks,
  isPasswordValid,
  getChangePasswordValidation,
  type PasswordChecks,
  type ChangePasswordFormData,
} from '@/util/password-validation'

describe('[util/password-validation]', () => {
  describe('getPasswordChecks', () => {
    it('all rules pass for strong password', () => {
      const checks = getPasswordChecks('ValidPass1!')
      expect(checks.length).toBe(true)
      expect(checks.upper).toBe(true)
      expect(checks.lower).toBe(true)
      expect(checks.digit).toBe(true)
      expect(checks.special).toBe(true)
    })

    it('fails when uppercase missing', () => {
      const checks = getPasswordChecks('validpass1!')
      expect(checks.upper).toBe(false)
    })

    it('fails when lowercase missing', () => {
      const checks = getPasswordChecks('VALIDPASS1!')
      expect(checks.lower).toBe(false)
    })

    it('fails when digit missing', () => {
      const checks = getPasswordChecks('ValidPass!')
      expect(checks.digit).toBe(false)
    })

    it('fails when special character missing', () => {
      const checks = getPasswordChecks('ValidPass1')
      expect(checks.special).toBe(false)
    })

    it('fails length when shorter than 8', () => {
      const checks = getPasswordChecks('Val1!')
      expect(checks.length).toBe(false)
    })

    it('fails length when longer than 20', () => {
      const long = 'ValidPass1!' + 'a'.repeat(10)
      const checks = getPasswordChecks(long)
      expect(checks.length).toBe(false)
    })
  })

  describe('isPasswordValid', () => {
    it('returns true when every check is true', () => {
      const checks: PasswordChecks = {
        length: true,
        upper: true,
        lower: true,
        digit: true,
        special: true,
      }
      expect(isPasswordValid(checks)).toBe(true)
    })

    it('returns false when any check is false', () => {
      expect(
        isPasswordValid({
          length: true,
          upper: false,
          lower: true,
          digit: true,
          special: true,
        }),
      ).toBe(false)
    })
  })

  describe('getChangePasswordValidation', () => {
    it('canSubmit when current set, new valid, confirm matches', () => {
      const formData: ChangePasswordFormData = {
        currentPassword: 'any-current',
        newPassword: 'NewPass1!',
        confirmPassword: 'NewPass1!',
      }
      const result = getChangePasswordValidation(formData)
      expect(result.isNewPasswordValid).toBe(true)
      expect(result.isConfirmPasswordMismatch).toBe(false)
      expect(result.canSubmit).toBe(true)
    })

    it('canSubmit false when current password empty', () => {
      const formData: ChangePasswordFormData = {
        currentPassword: '',
        newPassword: 'NewPass1!',
        confirmPassword: 'NewPass1!',
      }
      const result = getChangePasswordValidation(formData)
      expect(result.canSubmit).toBe(false)
    })

    it('flags mismatch when confirm differs from new', () => {
      const formData: ChangePasswordFormData = {
        currentPassword: 'any-current',
        newPassword: 'NewPass1!',
        confirmPassword: 'OtherPass1!',
      }
      const result = getChangePasswordValidation(formData)
      expect(result.isConfirmPasswordMismatch).toBe(true)
      expect(result.canSubmit).toBe(false)
    })
  })
})
