import { describe, it, expect } from 'vitest'
import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'

const adminDir = resolve(import.meta.dirname, '../../../server/api/admin')

// All admin routes grouped by directory
const adminRoutes = {
  'admin/': [
    'dashboard.get.js',
    'events.get.js',
    'events.post.js',
    'members.get.js',
    'members.post.js',
    'series.get.js',
    'series.post.js',
    'series.put.js'
  ],
  'admin/events/': [
    'events/[id].delete.js',
    'events/[id].get.js',
    'events/[id].put.js'
  ],
  'admin/members/': [
    'members/[id].put.js',
    'members/[id]/role.patch.js',
    'members/import.post.js',
    'members/invite.post.js'
  ],
  'admin/series/': [
    'series/[id].delete.js',
    'series/[id].put.js',
    'series/tickets.put.js'
  ]
}

// Business logic markers that must appear after requireAdmin
const businessLogicPatterns = [
  'readBody(event)',
  'validateBody(event',
  'fetch(',
  'connectDB()',
  'Member.find',
  'Member.findOne',
  'Member.findById',
  'Member.countDocuments',
  'Event.find',
  'Event.findOne',
  'Event.findById',
  'Event.countDocuments',
  'Series.find',
  'Series.findOne',
  'Series.findById'
]

describe('Admin endpoint auth guards', () => {
  for (const [group, files] of Object.entries(adminRoutes)) {
    describe(group, () => {
      for (const file of files) {
        describe(file, () => {
          const source = readFileSync(resolve(adminDir, file), 'utf-8')

          it('calls requireAdmin', () => {
            expect(source).toContain('requireAdmin(event)')
          })

          it('calls requireAdmin before any business logic', () => {
            const adminIndex = source.indexOf('requireAdmin(event)')
            expect(adminIndex).toBeGreaterThan(-1)

            for (const pattern of businessLogicPatterns) {
              const patternIndex = source.indexOf(pattern)
              if (patternIndex > -1) {
                expect(
                  adminIndex,
                  `requireAdmin must appear before ${pattern} in ${file}`
                ).toBeLessThan(patternIndex)
              }
            }
          })
        })
      }
    })
  }
})
