import { describe, it, expect } from 'vitest'
import {
  AuthenticatedPrincipalSchema,
  StepUpPolicySchema,
  type AuthenticatedPrincipal,
  type StepUpPolicy,
} from '../src/types.js'

const basePrincipal = {
  kind: 'human' as const,
  accountId: 'acct-A',
  principalId: 'cred-1',
  amr: ['passkey' as const],
  authAt: 1_700_000_000,
  stepUpAt: null,
}

describe('StepUpPolicy.required (host-driven, fail-closed)', () => {
  it('parses a policy with required=true', () => {
    const policy: StepUpPolicy = { required: true, maxAgeSeconds: 300, requiredMethod: 'passkey' }
    expect(StepUpPolicySchema.parse(policy)).toEqual(policy)
  })

  it('parses a policy with required=false', () => {
    const policy: StepUpPolicy = { required: false, maxAgeSeconds: 300, requiredMethod: 'passkey' }
    expect(StepUpPolicySchema.parse(policy)).toEqual(policy)
  })

  it('rejects a policy missing required', () => {
    const bad = { maxAgeSeconds: 300, requiredMethod: 'passkey' }
    expect(StepUpPolicySchema.safeParse(bad).success).toBe(false)
  })

  it('rejects a non-boolean required', () => {
    const bad = { required: 'yes', maxAgeSeconds: 300, requiredMethod: 'passkey' }
    expect(StepUpPolicySchema.safeParse(bad).success).toBe(false)
  })
})

describe('AuthenticatedPrincipal.stepUpMethod (F1 method-binding, optional)', () => {
  it('parses a principal that omits stepUpMethod (backward compatible)', () => {
    const parsed = AuthenticatedPrincipalSchema.parse(basePrincipal)
    expect(parsed.stepUpMethod).toBeUndefined()
  })

  it('parses a principal with an explicit stepUpMethod', () => {
    const p: AuthenticatedPrincipal = { ...basePrincipal, stepUpAt: 1_700_000_100, stepUpMethod: 'passkey' }
    expect(AuthenticatedPrincipalSchema.parse(p).stepUpMethod).toBe('passkey')
  })

  it('parses a principal with stepUpMethod=null (no step-up)', () => {
    const parsed = AuthenticatedPrincipalSchema.parse({ ...basePrincipal, stepUpMethod: null })
    expect(parsed.stepUpMethod).toBeNull()
  })

  it('rejects an invalid stepUpMethod value', () => {
    const bad = { ...basePrincipal, stepUpMethod: 'sms' }
    expect(AuthenticatedPrincipalSchema.safeParse(bad).success).toBe(false)
  })
})
