import { afterEach, describe, expect, it, vi } from 'vitest'
import { verifyRecaptcha } from '@/lib/security/recaptcha'
import { googleContextCookie, safeNextPath } from '@/lib/auth/google-oauth'

afterEach(() => {
  vi.unstubAllEnvs()
  vi.unstubAllGlobals()
})

describe('Google OAuth redirect state', () => {
  it('accepts only same-site paths and valid PKCE flow IDs', () => {
    expect(safeNextPath('/fb-dashboard?tab=company-info')).toBe('/fb-dashboard?tab=company-info')
    for (const path of ['https://example.com', '//example.com', '/\\example.com', '/dashboard\nLocation: evil']) {
      expect(safeNextPath(path)).toBeNull()
    }
    expect(googleContextCookie('a'.repeat(32))).toBe(`hha_google_context_${'a'.repeat(32)}`)
    expect(googleContextCookie('../bad')).toBeNull()
  })
})

describe('reCAPTCHA v3 server verification', () => {
  it('requires the expected action, hostname, and minimum score', async () => {
    vi.stubEnv('NEXT_PUBLIC_RECAPTCHA_SITE_KEY', 'public-key')
    vi.stubEnv('RECAPTCHA_SECRET_KEY', 'private-key')
    const response = { success: true, action: 'google_signup', hostname: 'heavyhaulagent.com', score: 0.7 }
    vi.stubGlobal('fetch', vi.fn(async () => ({ ok: true, json: async () => response })))
    expect(await verifyRecaptcha('one-use-token', 'google_signup', 'heavyhaulagent.com')).toEqual({ ok: true })
    expect(await verifyRecaptcha('one-use-token', 'google_login', 'heavyhaulagent.com')).toMatchObject({ ok: false })
    response.action = 'google_login'
    expect(await verifyRecaptcha('one-use-token', 'google_login', 'other.example')).toMatchObject({ ok: false })
    response.hostname = 'other.example'
    response.score = 0.49
    expect(await verifyRecaptcha('one-use-token', 'google_login', 'other.example')).toMatchObject({ ok: false })
  })

  it('fails closed when keys are partially configured or Google is unavailable', async () => {
    vi.stubEnv('NEXT_PUBLIC_RECAPTCHA_SITE_KEY', 'public-key')
    vi.stubEnv('RECAPTCHA_SECRET_KEY', '')
    expect(await verifyRecaptcha('token', 'google_login', 'heavyhaulagent.com')).toMatchObject({ ok: false })
    vi.stubEnv('RECAPTCHA_SECRET_KEY', 'private-key')
    vi.stubGlobal('fetch', vi.fn(async () => { throw new Error('offline') }))
    expect(await verifyRecaptcha('token', 'google_login', 'heavyhaulagent.com')).toMatchObject({ ok: false })
  })
})
