import { describe, expect, it, beforeAll } from 'vitest'
import {
  signMentorUploadToken, verifyMentorUploadToken,
  type MentorUploadPayload,
} from '../../src/lib/mentor-upload-token'

const samplePayload: MentorUploadPayload = {
  mentorAssignmentId: 'ma-123',
  projectId: 'proj-789',
  uploaderUserId: 'user-456',
  fileName: 'doc.pdf',
  mimeType: 'application/pdf',
  size: 12345,
  bucket: 'mopc-files',
  objectKey: 'Project/mentorship/123-doc.pdf',
  exp: Math.floor(Date.now() / 1000) + 3600,
}

beforeAll(() => {
  process.env.NEXTAUTH_SECRET = process.env.NEXTAUTH_SECRET || 'test-secret-123'
})

describe('mentor upload token', () => {
  it('round-trips a payload', () => {
    const token = signMentorUploadToken(samplePayload)
    expect(typeof token).toBe('string')
    expect(token.split('.').length).toBe(2) // payload.signature

    const verified = verifyMentorUploadToken(token)
    expect(verified.mentorAssignmentId).toBe('ma-123')
    expect(verified.objectKey).toBe('Project/mentorship/123-doc.pdf')
  })

  it('rejects a tampered payload', () => {
    const token = signMentorUploadToken(samplePayload)
    const [, sig] = token.split('.')
    const tamperedPayload = Buffer.from(JSON.stringify({ ...samplePayload, size: 999999 })).toString('base64url')
    const tampered = `${tamperedPayload}.${sig}`
    expect(() => verifyMentorUploadToken(tampered)).toThrow(/signature/i)
  })

  it('rejects a token with a different signature', () => {
    const token = signMentorUploadToken(samplePayload)
    const [payload] = token.split('.')
    const bad = `${payload}.0000000000000000000000000000000000000000000000000000000000000000`
    expect(() => verifyMentorUploadToken(bad)).toThrow(/signature/i)
  })

  it('rejects an expired token', () => {
    const expired = signMentorUploadToken({
      ...samplePayload,
      exp: Math.floor(Date.now() / 1000) - 60,
    })
    expect(() => verifyMentorUploadToken(expired)).toThrow(/expired/i)
  })

  it('rejects a malformed token', () => {
    expect(() => verifyMentorUploadToken('not-a-token')).toThrow()
    expect(() => verifyMentorUploadToken('one-segment')).toThrow()
  })
})
