import { test, expect } from '@playwright/test'
import { API_KEY_HEADER } from './helpers'

test.describe('Onboarding API', () => {
  // Reset onboarding state before each test to ensure isolation
  test.beforeEach(async ({ request }) => {
    await request.post('/api/onboarding', {
      headers: API_KEY_HEADER,
      data: { action: 'reset' },
    })
  })

  // ── Auth ─────────────────────────────────────

  test('GET /api/onboarding returns 401 without auth', async ({ request }) => {
    const res = await request.get('/api/onboarding')
    expect(res.status()).toBe(401)
  })

  test('POST /api/onboarding returns 401 without auth', async ({ request }) => {
    const res = await request.post('/api/onboarding', {
      data: { action: 'reset' },
    })
    expect(res.status()).toBe(401)
  })

  // ── GET ──────────────────────────────────────

  test('GET returns onboarding state with valid auth', async ({ request }) => {
    const res = await request.get('/api/onboarding', { headers: API_KEY_HEADER })
    expect(res.status()).toBe(200)
    const body = await res.json()
    expect(body).toHaveProperty('showOnboarding')
    expect(body).toHaveProperty('completed')
    expect(body).toHaveProperty('skipped')
    expect(body).toHaveProperty('checklistDismissed')
    expect(body).toHaveProperty('currentStep')
    expect(body).toHaveProperty('steps')
  })

  test('GET steps array has expected onboarding steps with id/title/completed', async ({ request }) => {
    const res = await request.get('/api/onboarding', { headers: API_KEY_HEADER })
    const body = await res.json()
    expect(body.steps).toHaveLength(4)
    expect(body.steps.map((step: any) => step.id)).toEqual([
      'welcome',
      'interface-mode',
      'gateway-link',
      'credentials',
    ])
    for (const step of body.steps) {
      expect(step).toHaveProperty('id')
      expect(step).toHaveProperty('title')
      expect(step).toHaveProperty('completed')
      expect(typeof step.id).toBe('string')
      expect(typeof step.title).toBe('string')
      expect(typeof step.completed).toBe('boolean')
    }
  })

  // ── POST: complete_step ──────────────────────

  test('POST complete_step marks step completed', async ({ request }) => {
    const res = await request.post('/api/onboarding', {
      headers: API_KEY_HEADER,
      data: { action: 'complete_step', step: 'welcome' },
    })
    expect(res.status()).toBe(200)
    const body = await res.json()
    expect(body.ok).toBe(true)
    expect(body.completedSteps).toContain('welcome')
  })

  test('POST complete_step without step returns 400', async ({ request }) => {
    const res = await request.post('/api/onboarding', {
      headers: API_KEY_HEADER,
      data: { action: 'complete_step' },
    })
    expect(res.status()).toBe(400)
  })

  test('POST complete_step with invalid step returns 400', async ({ request }) => {
    const res = await request.post('/api/onboarding', {
      headers: API_KEY_HEADER,
      data: { action: 'complete_step', step: 'nonexistent' },
    })
    expect(res.status()).toBe(400)
  })

  // ── POST: skip ───────────────────────────────

  test('POST skip sets skipped, GET reflects showOnboarding=false', async ({ request }) => {
    const skipRes = await request.post('/api/onboarding', {
      headers: API_KEY_HEADER,
      data: { action: 'skip' },
    })
    expect(skipRes.status()).toBe(200)

    const getRes = await request.get('/api/onboarding', { headers: API_KEY_HEADER })
    const state = await getRes.json()
    expect(state.skipped).toBe(true)
    expect(state.showOnboarding).toBe(false)
  })

  // ── POST: complete ───────────────────────────

  test('POST complete sets completed', async ({ request }) => {
    const res = await request.post('/api/onboarding', {
      headers: API_KEY_HEADER,
      data: { action: 'complete' },
    })
    expect(res.status()).toBe(200)

    const getRes = await request.get('/api/onboarding', { headers: API_KEY_HEADER })
    const state = await getRes.json()
    expect(state.completed).toBe(true)
    expect(state.showOnboarding).toBe(false)
  })

  test('POST dismiss_checklist is persisted per user in onboarding state', async ({ request }) => {
    const res = await request.post('/api/onboarding', {
      headers: API_KEY_HEADER,
      data: { action: 'dismiss_checklist' },
    })
    expect(res.status()).toBe(200)

    const getRes = await request.get('/api/onboarding', { headers: API_KEY_HEADER })
    const state = await getRes.json()
    expect(state.checklistDismissed).toBe(true)
  })

  // ── POST: reset ──────────────────────────────

  test('POST reset clears all state', async ({ request }) => {
    // First complete onboarding and dismiss checklist
    await request.post('/api/onboarding', {
      headers: API_KEY_HEADER,
      data: { action: 'complete' },
    })
    await request.post('/api/onboarding', {
      headers: API_KEY_HEADER,
      data: { action: 'dismiss_checklist' },
    })

    // Reset
    const res = await request.post('/api/onboarding', {
      headers: API_KEY_HEADER,
      data: { action: 'reset' },
    })
    expect(res.status()).toBe(200)

    // Verify onboarding state
    const getRes = await request.get('/api/onboarding', { headers: API_KEY_HEADER })
    const state = await getRes.json()
    expect(state.completed).toBe(false)
    expect(state.skipped).toBe(false)
    expect(state.checklistDismissed).toBe(false)
    expect(state.steps.every((s: any) => s.completed === false)).toBe(true)
  })

  // ── POST: invalid action ─────────────────────

  test('POST with invalid action returns 400', async ({ request }) => {
    const res = await request.post('/api/onboarding', {
      headers: API_KEY_HEADER,
      data: { action: 'invalid_action' },
    })
    expect(res.status()).toBe(400)
  })

  // ── Full lifecycle ───────────────────────────

  test('full lifecycle: reset -> steps -> complete -> verify', async ({ request }) => {
    // Reset
    await request.post('/api/onboarding', {
      headers: API_KEY_HEADER,
      data: { action: 'reset' },
    })

    // Verify initial state shows onboarding
    const initial = await request.get('/api/onboarding', { headers: API_KEY_HEADER })
    const initialState = await initial.json()
    expect(initialState.completed).toBe(false)
    expect(initialState.skipped).toBe(false)

    // Complete all configured steps
    for (const stepId of ['welcome', 'interface-mode', 'gateway-link', 'credentials']) {
      const res = await request.post('/api/onboarding', {
        headers: API_KEY_HEADER,
        data: { action: 'complete_step', step: stepId },
      })
      expect(res.status()).toBe(200)
    }

    // Mark complete
    const completeRes = await request.post('/api/onboarding', {
      headers: API_KEY_HEADER,
      data: { action: 'complete' },
    })
    expect(completeRes.status()).toBe(200)

    // Verify done
    const final = await request.get('/api/onboarding', { headers: API_KEY_HEADER })
    const finalState = await final.json()
    expect(finalState.completed).toBe(true)
    expect(finalState.showOnboarding).toBe(false)
    expect(finalState.steps.every((s: any) => s.completed === true)).toBe(true)
  })
})
