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

/**
 * Arcade Modal Session E2E Tests
 *
 * These tests verify that the arcade modal session system works correctly:
 * - Users are locked into games once they start
 * - Automatic redirects to active games
 * - Player modification is blocked during games
 * - "Return to Arcade" button properly ends sessions
 */

test.describe('Arcade Modal Session - Redirects', () => {
  test.beforeEach(async ({ page }) => {
    // Clear arcade session before each test
    await page.goto('/arcade')
    await page.waitForLoadState('networkidle')

    // Click "Return to Arcade" button if it exists (to clear any existing session)
    const returnButton = page.locator('button:has-text("Return to Arcade")')
    if (await returnButton.isVisible({ timeout: 1000 }).catch(() => false)) {
      await returnButton.click()
      await page.waitForLoadState('networkidle')
    }
  })

  test('should stay on arcade lobby when no active session', async ({ page }) => {
    await page.goto('/arcade')
    await page.waitForLoadState('networkidle')

    // Should see "Champion Arena" title
    const title = page.locator('h1:has-text("Champion Arena")')
    await expect(title).toBeVisible()

    // Should be able to select players
    const playerSection = page.locator('text=/Player|Select|Add/i')
    await expect(playerSection.first()).toBeVisible()
  })

  test('should redirect from arcade to active game when session exists', async ({ page }) => {
    // Start a game to create a session
    await page.goto('/arcade')
    await page.waitForLoadState('networkidle')

    // Find and click a player card to activate
    const playerCard = page.locator('[data-testid="player-card"]').first()
    if (await playerCard.isVisible({ timeout: 2000 }).catch(() => false)) {
      await playerCard.click()
      await page.waitForTimeout(500)
    }

    // Navigate to matching game to create session
    await page.goto('/arcade/matching')
    await page.waitForLoadState('networkidle')

    // Start the game (click Start button if visible)
    const startButton = page.locator('button:has-text("Start")')
    if (await startButton.isVisible({ timeout: 2000 }).catch(() => false)) {
      await startButton.click()
      await page.waitForTimeout(1000)
    }

    // Try to navigate back to arcade lobby
    await page.goto('/arcade')
    await page.waitForTimeout(2000) // Give time for redirect

    // Should be redirected back to the game
    await expect(page).toHaveURL(/\/arcade\/matching/)
    const gameTitle = page.locator('h1:has-text("Memory Pairs")')
    await expect(gameTitle).toBeVisible()
  })

  test('should redirect to correct game when navigating to wrong game', async ({ page }) => {
    // Create a session with matching game
    await page.goto('/arcade')
    await page.waitForLoadState('networkidle')

    // Activate a player
    const addPlayerButton = page.locator('button:has-text("Add Player"), button:has-text("+")')
    if (
      await addPlayerButton
        .first()
        .isVisible({ timeout: 2000 })
        .catch(() => false)
    ) {
      await addPlayerButton.first().click()
      await page.waitForTimeout(500)
    }

    // Go to matching game
    await page.goto('/arcade/matching')
    await page.waitForLoadState('networkidle')

    // Start game if needed
    const startButton = page.locator('button:has-text("Start")')
    if (await startButton.isVisible({ timeout: 2000 }).catch(() => false)) {
      await startButton.click()
      await page.waitForTimeout(1000)
    }

    // Try to navigate to a different game
    await page.goto('/arcade/memory-quiz')
    await page.waitForTimeout(2000) // Give time for redirect

    // Should be redirected back to matching
    await expect(page).toHaveURL(/\/arcade\/matching/)
  })

  test('should NOT redirect when on correct game page', async ({ page }) => {
    // Navigate to matching game
    await page.goto('/arcade/matching')
    await page.waitForLoadState('networkidle')

    // Should stay on matching page
    await expect(page).toHaveURL(/\/arcade\/matching/)
    const gameTitle = page.locator('h1:has-text("Memory Pairs")')
    await expect(gameTitle).toBeVisible()
  })
})

test.describe('Arcade Modal Session - Player Modification Blocking', () => {
  test.beforeEach(async ({ page }) => {
    // Clear session
    await page.goto('/arcade')
    await page.waitForLoadState('networkidle')

    const returnButton = page.locator('button:has-text("Return to Arcade")')
    if (await returnButton.isVisible({ timeout: 1000 }).catch(() => false)) {
      await returnButton.click()
      await page.waitForLoadState('networkidle')
    }
  })

  test('should allow player modification in arcade lobby with no session', async ({ page }) => {
    await page.goto('/arcade')
    await page.waitForLoadState('networkidle')

    // Look for add player button (should be enabled)
    const addPlayerButton = page.locator('button:has-text("Add Player"), button:has-text("+")')
    const firstButton = addPlayerButton.first()

    if (await firstButton.isVisible({ timeout: 2000 }).catch(() => false)) {
      // Should be clickable
      await expect(firstButton).toBeEnabled()

      // Try to click it
      await firstButton.click()
      await page.waitForTimeout(500)

      // Should see player added
      const activePlayer = page.locator('[data-testid="active-player"]')
      await expect(activePlayer.first()).toBeVisible({ timeout: 3000 })
    }
  })

  test('should block player modification during active game', async ({ page }) => {
    // Start a game
    await page.goto('/arcade/matching')
    await page.waitForLoadState('networkidle')

    // Start game
    const startButton = page.locator('button:has-text("Start")')
    if (await startButton.isVisible({ timeout: 2000 }).catch(() => false)) {
      await startButton.click()
      await page.waitForTimeout(1000)
    }

    // Look for player modification controls
    // They should be disabled or have reduced opacity
    const playerControls = page.locator('[data-testid="player-controls"], .player-list')
    if (await playerControls.isVisible({ timeout: 1000 }).catch(() => false)) {
      // Check if controls have pointer-events: none or low opacity
      const opacity = await playerControls.evaluate((el) => {
        return window.getComputedStyle(el).opacity
      })

      // If controls are visible, they should be dimmed (opacity < 1)
      if (parseFloat(opacity) < 1) {
        expect(parseFloat(opacity)).toBeLessThan(1)
      }
    }

    // "Add Player" button should not be visible during game
    const addPlayerButton = page.locator('button:has-text("Add Player")')
    if (await addPlayerButton.isVisible({ timeout: 500 }).catch(() => false)) {
      // If visible, should be disabled
      const isDisabled = await addPlayerButton.isDisabled()
      expect(isDisabled).toBe(true)
    }
  })

  test('should show "Return to Arcade" button during game', async ({ page }) => {
    // Start a game
    await page.goto('/arcade/matching')
    await page.waitForLoadState('networkidle')

    // Look for "Return to Arcade" button
    const returnButton = page.locator('button:has-text("Return to Arcade")')

    // During game setup, might see "Setup" button instead
    const setupButton = page.locator('button:has-text("Setup")')

    // One of these should be visible
    const hasReturnButton = await returnButton.isVisible({ timeout: 2000 }).catch(() => false)
    const hasSetupButton = await setupButton.isVisible({ timeout: 2000 }).catch(() => false)

    expect(hasReturnButton || hasSetupButton).toBe(true)
  })

  test('should NOT show "Setup" button in arcade lobby with no session', async ({ page }) => {
    await page.goto('/arcade')
    await page.waitForLoadState('networkidle')

    // Should NOT see "Return to Arcade" or "Setup" button in lobby
    const returnButton = page.locator('button:has-text("Return to Arcade")')
    const setupButton = page.locator('button:has-text("Setup")')

    const hasReturnButton = await returnButton.isVisible({ timeout: 1000 }).catch(() => false)
    const hasSetupButton = await setupButton.isVisible({ timeout: 1000 }).catch(() => false)

    // Neither should be visible in empty lobby
    expect(hasReturnButton).toBe(false)
    expect(hasSetupButton).toBe(false)
  })
})

test.describe('Arcade Modal Session - Return to Arcade Button', () => {
  test.beforeEach(async ({ page }) => {
    // Clear session
    await page.goto('/arcade')
    await page.waitForLoadState('networkidle')
  })

  test('should end session and return to arcade when clicking "Return to Arcade"', async ({
    page,
  }) => {
    // Start a game
    await page.goto('/arcade/matching')
    await page.waitForLoadState('networkidle')

    // Start game if needed
    const startButton = page.locator('button:has-text("Start")')
    if (await startButton.isVisible({ timeout: 2000 }).catch(() => false)) {
      await startButton.click()
      await page.waitForTimeout(1000)
    }

    // Find and click "Return to Arcade" button
    const returnButton = page.locator('button:has-text("Return to Arcade")')
    if (await returnButton.isVisible({ timeout: 2000 }).catch(() => false)) {
      await returnButton.click()
      await page.waitForTimeout(1000)

      // Should be redirected to arcade lobby
      await expect(page).toHaveURL(/\/arcade\/?$/)

      // Should see arcade lobby title
      const title = page.locator('h1:has-text("Champion Arena")')
      await expect(title).toBeVisible()

      // Now should be able to modify players again
      const addPlayerButton = page.locator('button:has-text("Add Player"), button:has-text("+")')
      if (
        await addPlayerButton
          .first()
          .isVisible({ timeout: 2000 })
          .catch(() => false)
      ) {
        await expect(addPlayerButton.first()).toBeEnabled()
      }
    }
  })

  test('should allow navigating to different game after returning to arcade', async ({ page }) => {
    // Start matching game
    await page.goto('/arcade/matching')
    await page.waitForLoadState('networkidle')

    // Return to arcade
    const returnButton = page.locator(
      'button:has-text("Return to Arcade"), button:has-text("Setup")'
    )
    if (
      await returnButton
        .first()
        .isVisible({ timeout: 2000 })
        .catch(() => false)
    ) {
      await returnButton.first().click()
      await page.waitForTimeout(1000)
    }

    // Should be in arcade lobby
    await expect(page).toHaveURL(/\/arcade\/?$/)

    // Now navigate to different game - should NOT redirect back to matching
    await page.goto('/arcade/memory-quiz')
    await page.waitForTimeout(2000)

    // Should stay on memory-quiz (not redirect back to matching)
    await expect(page).toHaveURL(/\/arcade\/memory-quiz/)

    // Should see memory quiz title
    const title = page.locator('h1:has-text("Memory Lightning")')
    await expect(title).toBeVisible({ timeout: 3000 })
  })
})

test.describe('Arcade Modal Session - Session Persistence', () => {
  test('should maintain active session across page reloads', async ({ page }) => {
    // Start a game
    await page.goto('/arcade/matching')
    await page.waitForLoadState('networkidle')

    // Start game
    const startButton = page.locator('button:has-text("Start")')
    if (await startButton.isVisible({ timeout: 2000 }).catch(() => false)) {
      await startButton.click()
      await page.waitForTimeout(1000)
    }

    // Reload the page
    await page.reload()
    await page.waitForLoadState('networkidle')

    // Should still be on matching game
    await expect(page).toHaveURL(/\/arcade\/matching/)
    const gameTitle = page.locator('h1:has-text("Memory Pairs")')
    await expect(gameTitle).toBeVisible()

    // Try to navigate to arcade
    await page.goto('/arcade')
    await page.waitForTimeout(2000)

    // Should be redirected back to matching
    await expect(page).toHaveURL(/\/arcade\/matching/)
  })
})
