/**
 * Security API Integration Tests
 *
 * Tests for security enforcement on API endpoints.
 * Covers rate limiting, CSRF protection, and IP blocking.
 */

import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
import { NextRequest, NextResponse } from 'next/server'

// Enable CSRF validation in CI by setting BYPASS_CSRF=false
// This must be set before any module imports that read this variable
process.env.BYPASS_CSRF = 'false'

// Enable TRUST_PROXY to allow IP-based tests to work with x-forwarded-for headers
// In real deployment behind Caddy, this would be set in the environment
process.env.TRUST_PROXY = 'true'
import {
  generateTestCsrfToken,
  generateExpiredCsrfToken,
  generateInvalidCsrfToken,
  createMockRequest,
  randomIp,
  uniqueTestId,
} from '../helpers/security-test-utils'

// ============================================================================
// Mock Setup
// ============================================================================

// Mock Redis (not available in test environment)
vi.mock('ioredis', () => ({
  default: vi.fn().mockImplementation(() => ({
    incr: vi.fn().mockResolvedValue(1),
    pexpire: vi.fn().mockResolvedValue(1),
    pttl: vi.fn().mockResolvedValue(60000),
    keys: vi.fn().mockResolvedValue([]),
    del: vi.fn().mockResolvedValue(0),
    quit: vi.fn(),
    on: vi.fn(),
  })),
}))

vi.mock('@/lib/redis', () => ({
  getRedisClient: vi.fn(() => null),
  isRedisAvailable: vi.fn(() => false),
}))

// Mock Payload for endpoints that need it
vi.mock('payload', () => ({
  getPayload: vi.fn().mockResolvedValue({
    auth: vi.fn().mockResolvedValue({ user: null }),
    find: vi.fn().mockResolvedValue({ docs: [], totalDocs: 0, page: 1, totalPages: 0 }),
    create: vi.fn().mockResolvedValue({ id: 1 }),
    login: vi.fn().mockRejectedValue(new Error('Invalid credentials')),
  }),
}))

// Mock config
vi.mock('@payload-config', () => ({
  default: Promise.resolve({}),
}))

describe('Security API Integration', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    vi.useFakeTimers()

    // Set up environment
    vi.stubEnv('CSRF_SECRET', 'test-csrf-secret-for-testing')
    vi.stubEnv('PAYLOAD_PUBLIC_SERVER_URL', 'https://test.example.com')
    vi.stubEnv('NEXT_PUBLIC_SERVER_URL', 'https://test.example.com')
  })

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

  describe('Rate Limiting', () => {
    describe('searchLimiter on /api/posts', () => {
      it('includes rate limit headers on success', async () => {
        // Reset modules to get fresh rate limiter state
        vi.resetModules()
        const { GET } = await import('@/app/(frontend)/api/posts/route')

        const testIp = uniqueTestId('ip')
        const req = createMockRequest({
          method: 'GET',
          url: 'https://test.example.com/api/posts',
          ip: testIp,
        })

        const response = await GET(req)

        expect(response.headers.get('X-RateLimit-Limit')).toBe('30')
        expect(response.headers.get('X-RateLimit-Remaining')).toBeDefined()
        expect(response.headers.get('X-RateLimit-Reset')).toBeDefined()
      })

      it('returns 429 when rate limit exceeded', async () => {
        vi.resetModules()
        const { GET } = await import('@/app/(frontend)/api/posts/route')

        const testIp = uniqueTestId('blocked-ip')
        const req = () =>
          createMockRequest({
            method: 'GET',
            url: 'https://test.example.com/api/posts',
            ip: testIp,
          })

        // Exhaust rate limit (30 requests)
        for (let i = 0; i < 30; i++) {
          await GET(req())
        }

        // 31st request should be blocked
        const response = await GET(req())

        expect(response.status).toBe(429)
        expect(response.headers.get('Retry-After')).toBeDefined()
      })
    })

    describe('searchLimiter on /api/search', () => {
      it('includes rate limit headers', async () => {
        vi.resetModules()
        const { GET } = await import('@/app/(frontend)/api/search/route')

        const testIp = uniqueTestId('search-ip')
        const req = createMockRequest({
          method: 'GET',
          url: 'https://test.example.com/api/search?q=test',
          ip: testIp,
        })

        const response = await GET(req)

        expect(response.headers.has('X-RateLimit-Remaining')).toBe(true)
      })
    })
  })

  describe('IP Blocking', () => {
    it('blocks requests from blocked IPs on /api/posts', async () => {
      vi.stubEnv('BLOCKED_IPS', '192.168.100.50')
      vi.resetModules()
      const { GET } = await import('@/app/(frontend)/api/posts/route')

      const req = createMockRequest({
        method: 'GET',
        url: 'https://test.example.com/api/posts',
        ip: '192.168.100.50',
      })

      const response = await GET(req)

      expect(response.status).toBe(403)
      const body = await response.json()
      expect(body.error).toContain('Access denied')
    })

    it('blocks requests from blocked CIDR range', async () => {
      vi.stubEnv('BLOCKED_IPS', '10.0.0.0/8')
      vi.resetModules()
      const { GET } = await import('@/app/(frontend)/api/posts/route')

      const req = createMockRequest({
        method: 'GET',
        url: 'https://test.example.com/api/posts',
        ip: '10.50.100.200',
      })

      const response = await GET(req)

      expect(response.status).toBe(403)
    })

    it('allows requests from non-blocked IPs', async () => {
      vi.stubEnv('BLOCKED_IPS', '192.168.100.50')
      vi.resetModules()
      const { GET } = await import('@/app/(frontend)/api/posts/route')

      const req = createMockRequest({
        method: 'GET',
        url: 'https://test.example.com/api/posts',
        ip: '8.8.8.8',
      })

      const response = await GET(req)

      expect(response.status).not.toBe(403)
    })
  })

  describe('CSRF Protection', () => {
    describe('Login Endpoints', () => {
      it('validates CSRF on /api/auth/login', async () => {
        vi.resetModules()
        const { POST } = await import('@/app/(payload)/api/auth/login/route')

        // Request without CSRF token
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/auth/login',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
          },
          ip: randomIp(),
        })

        // Mock json() method
        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            email: 'test@example.com',
            password: 'password123',
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(403)
        const body = await response.json()
        expect(body.error || body.errors?.[0]?.message).toContain('CSRF')
      })

      it('allows login with valid CSRF token', async () => {
        vi.resetModules()
        const { POST } = await import('@/app/(payload)/api/auth/login/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/auth/login',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: randomIp(),
        })

        // Mock json() method
        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            email: 'test@example.com',
            password: 'password123',
          }),
        })

        const response = await POST(req)

        // Should proceed past CSRF check (may fail auth, but that's expected)
        expect(response.status).not.toBe(403)
      })

      it('allows server-to-server login requests without CSRF', async () => {
        vi.resetModules()
        const { POST } = await import('@/app/(payload)/api/auth/login/route')

        // Server-to-server: Authorization header, JSON content-type, no Origin
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/auth/login',
          headers: {
            'content-type': 'application/json',
            authorization: 'Bearer api-token',
            // No origin header
          },
          ip: randomIp(),
        })

        // Mock json() method
        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            email: 'test@example.com',
            password: 'password123',
          }),
        })

        const response = await POST(req)

        // Should not be CSRF blocked
        expect(response.status).not.toBe(403)
      })
    })

    describe('Send Email Endpoint', () => {
      it('requires CSRF for browser requests', async () => {
        vi.resetModules()
        const { POST } = await import('@/app/(payload)/api/send-email/route')

        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/send-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
          },
          ip: randomIp(),
        })

        // Mock json() method
        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 1,
            to: 'recipient@example.com',
            subject: 'Test',
            html: '<p>Test</p>',
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(403)
      })
    })

    describe('Token Validation', () => {
      it('rejects expired CSRF tokens', async () => {
        vi.resetModules()
        const { POST } = await import('@/app/(payload)/api/auth/login/route')

        const expiredToken = generateExpiredCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/auth/login',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': expiredToken,
          },
          cookies: {
            'csrf-token': expiredToken,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            email: 'test@example.com',
            password: 'password123',
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(403)
      })

      it('rejects invalid CSRF tokens', async () => {
        vi.resetModules()
        const { POST } = await import('@/app/(payload)/api/auth/login/route')

        const invalidToken = generateInvalidCsrfToken()
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/auth/login',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': invalidToken,
          },
          cookies: {
            'csrf-token': invalidToken,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            email: 'test@example.com',
            password: 'password123',
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(403)
      })

      it('rejects mismatched header and cookie tokens', async () => {
        vi.resetModules()
        const { POST } = await import('@/app/(payload)/api/auth/login/route')

        const token1 = generateTestCsrfToken('test-csrf-secret-for-testing')
        const token2 = generateTestCsrfToken('test-csrf-secret-for-testing')

        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/auth/login',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token1,
          },
          cookies: {
            'csrf-token': token2, // Different token
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            email: 'test@example.com',
            password: 'password123',
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(403)
      })
    })
  })

  describe('CSRF Token Endpoint', () => {
    it('returns new CSRF token', async () => {
      vi.resetModules()
      const { GET } = await import('@/app/(frontend)/api/csrf-token/route')

      const req = createMockRequest({
        method: 'GET',
        url: 'https://test.example.com/api/csrf-token',
        ip: randomIp(),
      })

      const response = await GET(req)

      expect(response.status).toBe(200)
      const body = await response.json()
      expect(body.success).toBe(true)
      expect(body.token).toBeDefined()
      expect(body.header).toBe('X-CSRF-Token')
      expect(body.cookie).toBe('csrf-token')
    })

    it('sets CSRF cookie in response', async () => {
      vi.resetModules()
      const { GET } = await import('@/app/(frontend)/api/csrf-token/route')

      const req = createMockRequest({
        method: 'GET',
        url: 'https://test.example.com/api/csrf-token',
        ip: randomIp(),
      })

      const response = await GET(req)

      // Check for Set-Cookie header
      const setCookie = response.headers.get('set-cookie')
      expect(setCookie).toContain('csrf-token')
    })

    it('includes rate limit headers', async () => {
      vi.resetModules()
      const { GET } = await import('@/app/(frontend)/api/csrf-token/route')

      const req = createMockRequest({
        method: 'GET',
        url: 'https://test.example.com/api/csrf-token',
        ip: randomIp(),
      })

      const response = await GET(req)

      expect(response.headers.has('X-RateLimit-Remaining')).toBe(true)
    })
  })

  describe('Safe Methods', () => {
    it('allows GET requests without CSRF token', async () => {
      vi.resetModules()
      const { GET } = await import('@/app/(frontend)/api/posts/route')

      const req = createMockRequest({
        method: 'GET',
        url: 'https://test.example.com/api/posts',
        ip: randomIp(),
      })

      const response = await GET(req)

      // GET should work without CSRF
      expect(response.status).not.toBe(403)
    })
  })

  describe('Origin Validation', () => {
    it('rejects requests from unauthorized origins', async () => {
      vi.resetModules()
      const { POST } = await import('@/app/(payload)/api/auth/login/route')

      const token = generateTestCsrfToken('test-csrf-secret-for-testing')
      const req = createMockRequest({
        method: 'POST',
        url: 'https://test.example.com/api/auth/login',
        headers: {
          'content-type': 'application/json',
          origin: 'https://malicious-site.com',
          'X-CSRF-Token': token,
        },
        cookies: {
          'csrf-token': token,
        },
        ip: randomIp(),
      })

      Object.defineProperty(req, 'json', {
        value: vi.fn().mockResolvedValue({
          email: 'test@example.com',
          password: 'password123',
        }),
      })

      const response = await POST(req)

      expect(response.status).toBe(403)
    })
  })

  // ============================================================================
  // Test Email Endpoint Security Tests
  // ============================================================================

  describe('Test Email Endpoint (/api/test-email)', () => {
    describe('CSRF Protection', () => {
      it('requires CSRF token for browser requests', async () => {
        vi.resetModules()
        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 1,
            recipientEmail: 'test@example.com',
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(403)
        const body = await response.json()
        expect(body.error).toContain('CSRF')
      })

      it('accepts valid CSRF token', async () => {
        vi.resetModules()

        // Mock authenticated user
        vi.doMock('payload', () => ({
          getPayload: vi.fn().mockResolvedValue({
            auth: vi.fn().mockResolvedValue({
              user: {
                id: 1,
                email: 'admin@test.com',
                isSuperAdmin: true,
                tenants: [],
              },
            }),
            findByID: vi.fn().mockResolvedValue({ id: 1, name: 'Test Tenant' }),
            create: vi.fn().mockResolvedValue({ id: 1 }),
            update: vi.fn().mockResolvedValue({}),
          }),
        }))

        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 1,
            recipientEmail: 'test@example.com',
          }),
        })

        const response = await POST(req)

        // Should pass CSRF check (may fail on email send, but not 403)
        expect(response.status).not.toBe(403)
      })

      it('rejects expired CSRF tokens', async () => {
        vi.resetModules()
        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const expiredToken = generateExpiredCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': expiredToken,
          },
          cookies: {
            'csrf-token': expiredToken,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 1,
            recipientEmail: 'test@example.com',
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(403)
      })
    })

    describe('IP Blocking', () => {
      it('blocks requests from blocked IPs', async () => {
        vi.stubEnv('BLOCKED_IPS', '192.168.200.100')
        vi.resetModules()
        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: '192.168.200.100',
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 1,
            recipientEmail: 'test@example.com',
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(403)
        const body = await response.json()
        expect(body.error).toContain('Access denied')
      })

      it('respects SEND_EMAIL_ALLOWED_IPS allowlist', async () => {
        vi.stubEnv('SEND_EMAIL_ALLOWED_IPS', '10.0.0.1')
        vi.resetModules()
        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        // Request from IP not in allowlist
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: '192.168.1.100', // Not in allowlist
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 1,
            recipientEmail: 'test@example.com',
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(403)
        const body = await response.json()
        expect(body.error).toContain('Access denied')
      })
    })

    describe('Authentication', () => {
      it('requires authentication', async () => {
        vi.resetModules()

        // Mock unauthenticated user
        vi.doMock('payload', () => ({
          getPayload: vi.fn().mockResolvedValue({
            auth: vi.fn().mockResolvedValue({ user: null }),
          }),
        }))

        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 1,
            recipientEmail: 'test@example.com',
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(401)
        const body = await response.json()
        expect(body.error).toContain('authentifiziert')
      })
    })

    describe('Tenant Access Control', () => {
      it('allows super admin access to any tenant', async () => {
        vi.resetModules()

        vi.doMock('payload', () => ({
          getPayload: vi.fn().mockResolvedValue({
            auth: vi.fn().mockResolvedValue({
              user: {
                id: 1,
                email: 'superadmin@test.com',
                isSuperAdmin: true,
                tenants: [],
              },
            }),
            findByID: vi.fn().mockResolvedValue({ id: 99, name: 'Any Tenant' }),
          }),
        }))

        // Mock sendTestEmail
        vi.doMock('@/lib/email/tenant-email-service', () => ({
          sendTestEmail: vi.fn().mockResolvedValue({
            success: true,
            messageId: 'test-123',
            logId: 1,
          }),
        }))

        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 99,
            recipientEmail: 'test@example.com',
          }),
        })

        const response = await POST(req)

        // Super admin should have access
        expect(response.status).not.toBe(403)
      })

      it('denies access to tenants user is not assigned to', async () => {
        vi.resetModules()

        vi.doMock('payload', () => ({
          getPayload: vi.fn().mockResolvedValue({
            auth: vi.fn().mockResolvedValue({
              user: {
                id: 2,
                email: 'user@test.com',
                isSuperAdmin: false,
                tenants: [{ tenant: { id: 1 } }], // Only has access to tenant 1
              },
            }),
            findByID: vi.fn().mockResolvedValue({ id: 99, name: 'Other Tenant' }),
          }),
        }))

        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 99, // Different tenant
            recipientEmail: 'test@example.com',
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(403)
        const body = await response.json()
        expect(body.error).toContain('Zugriff')
      })

      it('normalizes tenant object format { tenant: { id } }', async () => {
        vi.resetModules()

        vi.doMock('payload', () => ({
          getPayload: vi.fn().mockResolvedValue({
            auth: vi.fn().mockResolvedValue({
              user: {
                id: 2,
                email: 'user@test.com',
                isSuperAdmin: false,
                // Multi-tenant plugin format: { tenant: { id: number } }
                tenants: [{ tenant: { id: 5 } }],
              },
            }),
            findByID: vi.fn().mockResolvedValue({ id: 5, name: 'User Tenant' }),
          }),
        }))

        vi.doMock('@/lib/email/tenant-email-service', () => ({
          sendTestEmail: vi.fn().mockResolvedValue({
            success: true,
            messageId: 'test-456',
            logId: 2,
          }),
        }))

        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 5,
            recipientEmail: 'test@example.com',
          }),
        })

        const response = await POST(req)

        // Should have access (tenant ID 5 matches)
        expect(response.status).not.toBe(403)
      })

      it('normalizes tenant primitive format { tenant: number }', async () => {
        vi.resetModules()

        vi.doMock('payload', () => ({
          getPayload: vi.fn().mockResolvedValue({
            auth: vi.fn().mockResolvedValue({
              user: {
                id: 2,
                email: 'user@test.com',
                isSuperAdmin: false,
                // Alternative format: { tenant: number }
                tenants: [{ tenant: 7 }],
              },
            }),
            findByID: vi.fn().mockResolvedValue({ id: 7, name: 'User Tenant' }),
          }),
        }))

        vi.doMock('@/lib/email/tenant-email-service', () => ({
          sendTestEmail: vi.fn().mockResolvedValue({
            success: true,
            messageId: 'test-789',
            logId: 3,
          }),
        }))

        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 7,
            recipientEmail: 'test@example.com',
          }),
        })

        const response = await POST(req)

        // Should have access (tenant ID 7 matches)
        expect(response.status).not.toBe(403)
      })
    })

    describe('Input Validation', () => {
      it('requires tenantId', async () => {
        vi.resetModules()

        vi.doMock('payload', () => ({
          getPayload: vi.fn().mockResolvedValue({
            auth: vi.fn().mockResolvedValue({
              user: { id: 1, isSuperAdmin: true },
            }),
          }),
        }))

        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            recipientEmail: 'test@example.com',
            // Missing tenantId
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(400)
        const body = await response.json()
        expect(body.error).toContain('tenantId')
      })

      it('requires recipientEmail', async () => {
        vi.resetModules()

        vi.doMock('payload', () => ({
          getPayload: vi.fn().mockResolvedValue({
            auth: vi.fn().mockResolvedValue({
              user: { id: 1, isSuperAdmin: true },
            }),
          }),
        }))

        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 1,
            // Missing recipientEmail
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(400)
        const body = await response.json()
        expect(body.error).toContain('recipientEmail')
      })

      it('validates email format', async () => {
        vi.resetModules()

        vi.doMock('payload', () => ({
          getPayload: vi.fn().mockResolvedValue({
            auth: vi.fn().mockResolvedValue({
              user: { id: 1, isSuperAdmin: true },
            }),
          }),
        }))

        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 1,
            recipientEmail: 'invalid-email', // Invalid format
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(400)
        const body = await response.json()
        expect(body.error).toContain('E-Mail')
      })

      it('validates tenantId is numeric', async () => {
        vi.resetModules()

        vi.doMock('payload', () => ({
          getPayload: vi.fn().mockResolvedValue({
            auth: vi.fn().mockResolvedValue({
              user: { id: 1, isSuperAdmin: true },
            }),
          }),
        }))

        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 'not-a-number',
            recipientEmail: 'test@example.com',
          }),
        })

        const response = await POST(req)

        expect(response.status).toBe(400)
        const body = await response.json()
        expect(body.error).toContain('Zahl')
      })
    })

    describe('Rate Limiting', () => {
      it('includes rate limit headers', async () => {
        vi.resetModules()

        vi.doMock('payload', () => ({
          getPayload: vi.fn().mockResolvedValue({
            auth: vi.fn().mockResolvedValue({
              user: { id: 1, isSuperAdmin: true },
            }),
            findByID: vi.fn().mockResolvedValue({ id: 1, name: 'Test Tenant' }),
          }),
        }))

        vi.doMock('@/lib/email/tenant-email-service', () => ({
          sendTestEmail: vi.fn().mockResolvedValue({
            success: true,
            messageId: 'test-rate',
            logId: 1,
          }),
        }))

        const { POST } = await import('@/app/(payload)/api/test-email/route')

        const token = generateTestCsrfToken('test-csrf-secret-for-testing')
        const req = createMockRequest({
          method: 'POST',
          url: 'https://test.example.com/api/test-email',
          headers: {
            'content-type': 'application/json',
            origin: 'https://test.example.com',
            'X-CSRF-Token': token,
          },
          cookies: {
            'csrf-token': token,
          },
          ip: randomIp(),
        })

        Object.defineProperty(req, 'json', {
          value: vi.fn().mockResolvedValue({
            tenantId: 1,
            recipientEmail: 'test@example.com',
          }),
        })

        const response = await POST(req)

        // Should include rate limit headers on success
        if (response.status === 200) {
          expect(response.headers.has('X-RateLimit-Limit')).toBe(true)
          expect(response.headers.has('X-RateLimit-Remaining')).toBe(true)
        }
      })
    })
  })
})
