/**
 * E2E Tests für Newsletter Double Opt-In Flow
 *
 * Testet den kompletten Newsletter-Anmeldeprozess inkl. Rate-Limiting
 */

import { test, expect } from '@playwright/test'

// Test tenant ID (porwoll.de)
const TEST_TENANT_ID = 1

test.describe('Newsletter Subscribe API', () => {
  const subscribeEndpoint = '/api/newsletter/subscribe'

  test('POST /api/newsletter/subscribe requires email', async ({ request }) => {
    const response = await request.post(subscribeEndpoint, {
      data: {
        tenantId: TEST_TENANT_ID,
      },
    })

    // Handle rate limiting
    if (response.status() === 429) {
      return
    }

    expect(response.status()).toBe(400)

    const data = await response.json()
    expect(data.success).toBe(false)
    expect(data.message).toContain('E-Mail')
  })

  test('POST /api/newsletter/subscribe validates email format', async ({ request }) => {
    const response = await request.post(subscribeEndpoint, {
      data: {
        email: 'not-an-email',
        tenantId: TEST_TENANT_ID,
      },
    })

    // Handle rate limiting
    if (response.status() === 429) {
      return
    }

    expect(response.status()).toBe(400)

    const data = await response.json()
    expect(data.success).toBe(false)
    expect(data.message).toContain('gültige E-Mail')
  })

  test('POST /api/newsletter/subscribe requires tenant', async ({ request }) => {
    const response = await request.post(subscribeEndpoint, {
      data: {
        email: 'test@example.com',
      },
    })

    // Handle rate limiting
    if (response.status() === 429) {
      return
    }

    expect(response.status()).toBe(400)

    const data = await response.json()
    expect(data.success).toBe(false)
    expect(data.message).toContain('Tenant')
  })

  test('POST /api/newsletter/subscribe accepts valid subscription', async ({ request }) => {
    // Use a unique email to avoid conflicts with existing data
    const uniqueEmail = `test-${Date.now()}@e2e-test.example`

    const response = await request.post(subscribeEndpoint, {
      data: {
        email: uniqueEmail,
        tenantId: TEST_TENANT_ID,
        firstName: 'E2E',
        lastName: 'Test',
        source: 'e2e-test',
      },
    })

    // Should succeed, indicate already subscribed, or be rate limited
    expect([200, 400, 429]).toContain(response.status())

    // Only check response body if not rate limited
    if (response.status() !== 429) {
      const data = await response.json()
      expect(data).toHaveProperty('success')
      expect(data).toHaveProperty('message')

      if (data.success) {
        // New subscription
        expect(data.message).toContain('Bestätigungs')
      }
    }
  })

  test('POST /api/newsletter/subscribe normalizes email to lowercase', async ({ request }) => {
    const uniqueEmail = `Test-Upper-${Date.now()}@E2E-TEST.Example`

    const response = await request.post(subscribeEndpoint, {
      data: {
        email: uniqueEmail,
        tenantId: TEST_TENANT_ID,
      },
    })

    // Request should be processed (email normalized internally) or rate limited
    expect([200, 400, 429]).toContain(response.status())
  })

  test('POST /api/newsletter/subscribe handles optional fields', async ({ request }) => {
    const uniqueEmail = `test-optional-${Date.now()}@e2e-test.example`

    const response = await request.post(subscribeEndpoint, {
      data: {
        email: uniqueEmail,
        tenantId: TEST_TENANT_ID,
        // Only required fields, no optional ones
      },
    })

    // Accept rate limiting as valid (429)
    expect([200, 400, 429]).toContain(response.status())

    // Only check response structure if not rate limited
    if (response.status() !== 429) {
      const data = await response.json()
      expect(data).toHaveProperty('success')
      expect(data).toHaveProperty('message')
    }
  })

  test('POST /api/newsletter/subscribe accepts source parameter', async ({ request }) => {
    const uniqueEmail = `test-source-${Date.now()}@e2e-test.example`

    const response = await request.post(subscribeEndpoint, {
      data: {
        email: uniqueEmail,
        tenantId: TEST_TENANT_ID,
        source: 'footer-form',
      },
    })

    // Accept rate limiting as valid (429)
    expect([200, 400, 429]).toContain(response.status())
  })
})

test.describe('Newsletter Confirm API', () => {
  const confirmEndpoint = '/api/newsletter/confirm'

  test('GET /api/newsletter/confirm requires token', async ({ request }) => {
    const response = await request.get(confirmEndpoint)

    // Returns HTML page with error
    expect(response.ok()).toBe(true)

    const html = await response.text()
    expect(html).toContain('Ungültiger')
  })

  test('GET /api/newsletter/confirm rejects invalid token', async ({ request }) => {
    const response = await request.get(`${confirmEndpoint}?token=invalid-token-12345`)

    expect(response.ok()).toBe(true)

    const html = await response.text()
    // Should show error page
    expect(html).toContain('Fehler')
  })

  test('POST /api/newsletter/confirm requires token', async ({ request }) => {
    const response = await request.post(confirmEndpoint, {
      data: {},
    })

    expect(response.status()).toBe(400)

    const data = await response.json()
    expect(data.success).toBe(false)
    expect(data.message).toContain('Token')
  })

  test('POST /api/newsletter/confirm rejects invalid token', async ({ request }) => {
    const response = await request.post(confirmEndpoint, {
      data: {
        token: 'invalid-token-67890',
      },
    })

    expect(response.status()).toBe(400)

    const data = await response.json()
    expect(data.success).toBe(false)
  })

  test('GET /api/newsletter/confirm returns HTML response', async ({ request }) => {
    const response = await request.get(`${confirmEndpoint}?token=test`)

    expect(response.ok()).toBe(true)

    const contentType = response.headers()['content-type']
    expect(contentType).toContain('text/html')
  })
})

test.describe('Newsletter Unsubscribe API', () => {
  const unsubscribeEndpoint = '/api/newsletter/unsubscribe'

  test('GET /api/newsletter/unsubscribe requires token', async ({ request }) => {
    const response = await request.get(unsubscribeEndpoint)

    expect(response.ok()).toBe(true)

    const html = await response.text()
    expect(html).toContain('Ungültiger')
  })

  test('GET /api/newsletter/unsubscribe returns HTML response', async ({ request }) => {
    const response = await request.get(`${unsubscribeEndpoint}?token=test`)

    expect(response.ok()).toBe(true)

    const contentType = response.headers()['content-type']
    expect(contentType).toContain('text/html')
  })

  test('POST /api/newsletter/unsubscribe requires token', async ({ request }) => {
    const response = await request.post(unsubscribeEndpoint, {
      data: {},
    })

    expect(response.status()).toBe(400)

    const data = await response.json()
    expect(data.success).toBe(false)
  })
})

test.describe('Newsletter Rate Limiting', () => {
  test('Newsletter subscribe has rate limiting headers', async ({ request }) => {
    const response = await request.post('/api/newsletter/subscribe', {
      data: {
        email: 'ratelimit-test@example.com',
        tenantId: TEST_TENANT_ID,
      },
    })

    // Rate limit headers should be present on rate limited response
    if (response.status() === 429) {
      expect(response.headers()['retry-after']).toBeDefined()
    }
  })
})

test.describe('Newsletter Flow Integration', () => {
  test('Complete subscription flow structure', async ({ request }) => {
    // 1. Subscribe
    const uniqueEmail = `integration-${Date.now()}@e2e-test.example`

    const subscribeResponse = await request.post('/api/newsletter/subscribe', {
      data: {
        email: uniqueEmail,
        tenantId: TEST_TENANT_ID,
        firstName: 'Integration',
        lastName: 'Test',
        source: 'e2e-integration-test',
      },
    })

    expect([200, 400, 429]).toContain(subscribeResponse.status())

    const subscribeData = await subscribeResponse.json()

    // If successful, should indicate confirmation email sent
    if (subscribeData.success) {
      expect(subscribeData.message).toContain('Bestätigungs')
    }

    // 2. Confirm endpoint should be accessible
    const confirmResponse = await request.get('/api/newsletter/confirm?token=dummy')
    expect(confirmResponse.ok()).toBe(true)

    // 3. Unsubscribe endpoint should be accessible
    const unsubscribeResponse = await request.get('/api/newsletter/unsubscribe?token=dummy')
    expect(unsubscribeResponse.ok()).toBe(true)
  })

  test('Re-subscription handling', async ({ request }) => {
    const email = `resub-test-${Date.now()}@e2e-test.example`

    // First subscription
    const firstResponse = await request.post('/api/newsletter/subscribe', {
      data: {
        email: email,
        tenantId: TEST_TENANT_ID,
      },
    })

    if (firstResponse.status() === 429) {
      test.skip() // Rate limited, skip test
      return
    }

    // Second subscription with same email
    const secondResponse = await request.post('/api/newsletter/subscribe', {
      data: {
        email: email,
        tenantId: TEST_TENANT_ID,
      },
    })

    // Should handle gracefully (either success or already subscribed message)
    expect([200, 400, 429]).toContain(secondResponse.status())

    const data = await secondResponse.json()
    expect(data).toHaveProperty('success')
    expect(data).toHaveProperty('message')
  })
})
