import { suite } from '../lib/context.js'

// Helper: create a tiny 1x1 JPEG for testing uploads
const TINY_JPEG = Buffer.from(
  '/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB' +
  'AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEB' +
  'AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAABAAEDASIA' +
  'AhEBAxEB/8QAFAABAAAAAAAAAAAAAAAAAAAACf/EABQQAQAAAAAAAAAAAAAAAAAAAAD/xAAUAQEA' +
  'AAAAAAAAAAAAAAAAAAAB/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AJgA//9k=',
  'base64',
)

suite('Files', { tags: ['files', 'storage'] }, (t) => {
  t.test('uploads an image file', { tags: ['upload'] }, async () => {
    const acct = await t.api.post('/v1/accounts', { name: 'File Test' })
    const member = await t.api.post(`/v1/accounts/${acct.data.id}/members`, {
      firstName: 'File',
      lastName: 'Test',
    })

    // Upload via multipart
    const formData = new FormData()
    formData.append('file', new Blob([TINY_JPEG], { type: 'image/jpeg' }), 'test.jpg')
    formData.append('entityType', 'member_identifier')
    formData.append('entityId', member.data.id)
    formData.append('category', 'front')

    const res = await fetch(`${t.baseUrl}/v1/files`, {
      method: 'POST',
      headers: { Authorization: `Bearer ${t.token}` },
      body: formData,
    })
    const data = await res.json()

    t.assert.equal(res.status, 201)
    t.assert.ok(data.id)
    t.assert.equal(data.contentType, 'image/jpeg')
    t.assert.equal(data.entityType, 'member_identifier')
    t.assert.equal(data.category, 'front')
    t.assert.ok(data.url)
  })

  t.test('lists files for an entity', { tags: ['read'] }, async () => {
    const acct = await t.api.post('/v1/accounts', { name: 'File List Test' })
    const member = await t.api.post(`/v1/accounts/${acct.data.id}/members`, {
      firstName: 'List',
      lastName: 'Files',
    })

    // Upload a file first
    const formData = new FormData()
    formData.append('file', new Blob([TINY_JPEG], { type: 'image/jpeg' }), 'list-test.jpg')
    formData.append('entityType', 'member_identifier')
    formData.append('entityId', member.data.id)
    formData.append('category', 'back')

    await fetch(`${t.baseUrl}/v1/files`, {
      method: 'POST',
      headers: { Authorization: `Bearer ${t.token}` },
      body: formData,
    })

    const res = await t.api.get('/v1/files', {
      entityType: 'member_identifier',
      entityId: member.data.id,
    })
    t.assert.status(res, 200)
    t.assert.greaterThan(res.data.data.length, 0)
    t.assert.ok(res.data.data[0].url)
  })

  t.test('gets file metadata by id', { tags: ['read'] }, async () => {
    const acct = await t.api.post('/v1/accounts', { name: 'File Get Test' })
    const member = await t.api.post(`/v1/accounts/${acct.data.id}/members`, {
      firstName: 'Get',
      lastName: 'File',
    })

    const formData = new FormData()
    formData.append('file', new Blob([TINY_JPEG], { type: 'image/jpeg' }), 'get-test.jpg')
    formData.append('entityType', 'member_identifier')
    formData.append('entityId', member.data.id)
    formData.append('category', 'front')

    const uploadRes = await fetch(`${t.baseUrl}/v1/files`, {
      method: 'POST',
      headers: { Authorization: `Bearer ${t.token}` },
      body: formData,
    })
    const uploaded = await uploadRes.json()

    const res = await t.api.get(`/v1/files/${uploaded.id}`)
    t.assert.status(res, 200)
    t.assert.equal(res.data.id, uploaded.id)
    t.assert.equal(res.data.filename, 'get-test.jpg')
  })

  t.test('deletes a file', { tags: ['delete'] }, async () => {
    const acct = await t.api.post('/v1/accounts', { name: 'File Delete Test' })
    const member = await t.api.post(`/v1/accounts/${acct.data.id}/members`, {
      firstName: 'Delete',
      lastName: 'File',
    })

    const formData = new FormData()
    formData.append('file', new Blob([TINY_JPEG], { type: 'image/jpeg' }), 'delete-test.jpg')
    formData.append('entityType', 'member_identifier')
    formData.append('entityId', member.data.id)
    formData.append('category', 'front')

    const uploadRes = await fetch(`${t.baseUrl}/v1/files`, {
      method: 'POST',
      headers: { Authorization: `Bearer ${t.token}` },
      body: formData,
    })
    const uploaded = await uploadRes.json()

    const res = await t.api.del(`/v1/files/${uploaded.id}`)
    t.assert.status(res, 200)

    const check = await t.api.get(`/v1/files/${uploaded.id}`)
    t.assert.status(check, 404)
  })

  t.test('rejects unsupported file types', { tags: ['validation'] }, async () => {
    const acct = await t.api.post('/v1/accounts', { name: 'File Reject Test' })

    const formData = new FormData()
    formData.append('file', new Blob(['not an image'], { type: 'text/plain' }), 'test.txt')
    formData.append('entityType', 'member_identifier')
    formData.append('entityId', acct.data.id)
    formData.append('category', 'front')

    const res = await fetch(`${t.baseUrl}/v1/files`, {
      method: 'POST',
      headers: { Authorization: `Bearer ${t.token}` },
      body: formData,
    })
    t.assert.equal(res.status, 400)
  })

  t.test('uploads profile picture for user entity type', { tags: ['upload', 'profile'] }, async () => {
    // Get the current test user ID from the users list
    const usersRes = await t.api.get('/v1/users')
    const testUser = usersRes.data.data[0]
    t.assert.ok(testUser)

    const formData = new FormData()
    formData.append('file', new Blob([TINY_JPEG], { type: 'image/jpeg' }), 'avatar.jpg')
    formData.append('entityType', 'user')
    formData.append('entityId', testUser.id)
    formData.append('category', 'profile')

    const res = await fetch(`${t.baseUrl}/v1/files`, {
      method: 'POST',
      headers: { Authorization: `Bearer ${t.token}` },
      body: formData,
    })
    const data = await res.json()

    t.assert.equal(res.status, 201)
    t.assert.equal(data.entityType, 'user')
    t.assert.equal(data.category, 'profile')

    // Verify it shows up in files list
    const listRes = await t.api.get('/v1/files', { entityType: 'user', entityId: testUser.id })
    t.assert.status(listRes, 200)
    t.assert.greaterThan(listRes.data.data.length, 0)
  })

  t.test('returns 404 for missing file', { tags: ['read'] }, async () => {
    const res = await t.api.get('/v1/files/a0000000-0000-0000-0000-999999999999')
    t.assert.status(res, 404)
  })
})
