import { http, HttpResponse } from 'msw'
import { test, expect } from './msw-setup'

const fullEvent = {
  eventToken: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
  title: 'Summer BBQ',
  description: 'Bring your own drinks!',
  dateTime: '2026-03-15T20:00:00+01:00',
  timezone: 'Europe/Berlin',
  location: 'Central Park, NYC',
  attendeeCount: 12,
}

test.describe('US1: RSVP submission flow', () => {
  test('submits RSVP, updates attendee count, and persists in localStorage', async ({ page, network }) => {
    network.use(
      http.get('*/api/events/:token', () => {
        return HttpResponse.json(fullEvent)
      }),
      http.post('*/api/events/:token/rsvps', () => {
        return HttpResponse.json(
          { rsvpToken: 'd4e5f6a7-b8c9-0123-4567-890abcdef012', name: 'Max Mustermann' },
          { status: 201 },
        )
      }),
    )

    await page.goto(`/events/${fullEvent.eventToken}`)

    // CTA is visible
    const cta = page.getByRole('button', { name: "I'm attending" })
    await expect(cta).toBeVisible()

    // Open bottom sheet
    await cta.click()
    const dialog = page.getByRole('dialog', { name: 'RSVP' })
    await expect(dialog).toBeVisible()

    // Fill name and submit
    await dialog.getByLabel('Your name').fill('Max Mustermann')
    await dialog.getByRole('button', { name: 'Count me in' }).click()

    // Bottom sheet closes, status bar appears
    await expect(dialog).not.toBeVisible()
    await expect(page.getByText("You're attending!")).toBeVisible()
    await expect(cta).not.toBeVisible()

    // Attendee count incremented
    await expect(page.getByText('13')).toBeVisible()

    // Verify localStorage
    const stored = await page.evaluate(() => {
      const raw = localStorage.getItem('fete:events')
      return raw ? JSON.parse(raw) : null
    })
    expect(stored).toEqual(
      expect.arrayContaining([
        expect.objectContaining({
          eventToken: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
          rsvpToken: 'd4e5f6a7-b8c9-0123-4567-890abcdef012',
          rsvpName: 'Max Mustermann',
        }),
      ]),
    )
  })

  test('shows validation error when name is empty', async ({ page, network }) => {
    network.use(
      http.get('*/api/events/:token', () => {
        return HttpResponse.json(fullEvent)
      }),
    )

    await page.goto(`/events/${fullEvent.eventToken}`)
    await page.getByRole('button', { name: "I'm attending" }).click()

    const dialog = page.getByRole('dialog', { name: 'RSVP' })
    await dialog.getByRole('button', { name: 'Count me in' }).click()

    await expect(page.getByText('Please enter your name.')).toBeVisible()
  })

  test('restores RSVP status from localStorage on page load', async ({ page, network }) => {
    network.use(
      http.get('*/api/events/:token', () => {
        return HttpResponse.json(fullEvent)
      }),
    )

    // Pre-seed localStorage
    await page.goto('/')
    await page.evaluate(() => {
      localStorage.setItem(
        'fete:events',
        JSON.stringify([
          {
            eventToken: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
            title: 'Summer BBQ',
            dateTime: '2026-03-15T20:00:00+01:00',
            expiryDate: '',
            rsvpToken: 'existing-rsvp-token',
            rsvpName: 'Anna',
          },
        ]),
      )
    })

    await page.goto(`/events/${fullEvent.eventToken}`)

    // Status bar should show, not CTA
    await expect(page.getByText("You're attending!")).toBeVisible()
    await expect(page.getByRole('button', { name: "I'm attending" })).not.toBeVisible()
  })

  test('shows error when server is unreachable during RSVP', async ({ page, network }) => {
    network.use(
      http.get('*/api/events/:token', () => {
        return HttpResponse.json(fullEvent)
      }),
      http.post('*/api/events/:token/rsvps', () => {
        return HttpResponse.json(
          { type: 'about:blank', title: 'Bad Request', status: 400 },
          { status: 400, headers: { 'Content-Type': 'application/problem+json' } },
        )
      }),
    )

    await page.goto(`/events/${fullEvent.eventToken}`)
    await page.getByRole('button', { name: "I'm attending" }).click()

    const dialog = page.getByRole('dialog', { name: 'RSVP' })
    await dialog.getByLabel('Your name').fill('Max')
    await dialog.getByRole('button', { name: 'Count me in' }).click()

    await expect(page.getByText('Could not submit RSVP. Please try again.')).toBeVisible()
  })

  test('does not show RSVP bar for organizer', async ({ page, network }) => {
    network.use(
      http.get('*/api/events/:token', () => {
        return HttpResponse.json(fullEvent)
      }),
    )

    // Pre-seed localStorage with organizer token
    await page.goto('/')
    await page.evaluate(() => {
      localStorage.setItem(
        'fete:events',
        JSON.stringify([
          {
            eventToken: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
            organizerToken: 'org-token-123',
            title: 'Summer BBQ',
            dateTime: '2026-03-15T20:00:00+01:00',
            expiryDate: '',
          },
        ]),
      )
    })

    await page.goto(`/events/${fullEvent.eventToken}`)

    // Event content should load
    await expect(page.getByText('Summer BBQ')).toBeVisible()

    // But no RSVP bar
    await expect(page.getByRole('button', { name: "I'm attending" })).not.toBeVisible()
    await expect(page.getByText("You're attending!")).not.toBeVisible()
  })

})
