/**
 * Security Dashboard Mobile Responsive E2E Tests
 * Test IDs: MR-01 through MR-10
 *
 * Tests mobile viewport (375x667), tablet viewport (768x1024),
 * touch targets, scrolling, and layout responsiveness.
 */
import { test, expect } from '@playwright/test'

const base = process.env.CHARON_BASE_URL || 'http://localhost:8080'

test.describe('Security Dashboard Mobile (375x667)', () => {
  test.use({ viewport: { width: 375, height: 667 } })

  test('MR-01: cards stack vertically on mobile', async ({ page }) => {
    await page.goto(`${base}/security`)

    // Wait for page to load
    await page.waitForSelector('[data-testid="toggle-crowdsec"]', { timeout: 10000 })

    // On mobile, grid should be single column
    const grid = page.locator('.grid.grid-cols-1')
    await expect(grid).toBeVisible()

    // Get the computed grid-template-columns
    const cardsContainer = page.locator('.grid').first()
    const gridStyle = await cardsContainer.evaluate((el) => {
      const style = window.getComputedStyle(el)
      return style.gridTemplateColumns
    })

    // Single column should have just one value (not multiple columns like "repeat(4, ...)")
    const columns = gridStyle.split(' ').filter((s) => s.trim().length > 0)
    expect(columns.length).toBeLessThanOrEqual(2) // Single column or flexible
  })

  test('MR-04: toggle switches have accessible touch targets', async ({ page }) => {
    await page.goto(`${base}/security`)
    await page.waitForSelector('[data-testid="toggle-crowdsec"]', { timeout: 10000 })

    // Check CrowdSec toggle
    const crowdsecToggle = page.getByTestId('toggle-crowdsec')
    const crowdsecBox = await crowdsecToggle.boundingBox()

    // Touch target should be at least 24px (component) + padding
    // Most switches have a reasonable touch target
    expect(crowdsecBox).not.toBeNull()
    if (crowdsecBox) {
      expect(crowdsecBox.height).toBeGreaterThanOrEqual(20)
      expect(crowdsecBox.width).toBeGreaterThanOrEqual(35)
    }

    // Check WAF toggle
    const wafToggle = page.getByTestId('toggle-waf')
    const wafBox = await wafToggle.boundingBox()
    expect(wafBox).not.toBeNull()
    if (wafBox) {
      expect(wafBox.height).toBeGreaterThanOrEqual(20)
    }
  })

  test('MR-05: config buttons are tappable on mobile', async ({ page }) => {
    await page.goto(`${base}/security`)
    await page.waitForSelector('[data-testid="toggle-crowdsec"]', { timeout: 10000 })

    // Find config/configure buttons
    const configButtons = page.locator('button:has-text("Config"), button:has-text("Configure")')
    const buttonCount = await configButtons.count()

    expect(buttonCount).toBeGreaterThan(0)

    // Check first config button has reasonable size
    const firstButton = configButtons.first()
    const box = await firstButton.boundingBox()
    expect(box).not.toBeNull()
    if (box) {
      expect(box.height).toBeGreaterThanOrEqual(28) // Minimum tap height
    }
  })

  test('MR-06: page content is scrollable on mobile', async ({ page }) => {
    await page.goto(`${base}/security`)
    await page.waitForSelector('[data-testid="toggle-crowdsec"]', { timeout: 10000 })

    // Check if page is scrollable (content height > viewport)
    const bodyHeight = await page.evaluate(() => document.body.scrollHeight)
    const viewportHeight = 667

    // If content is taller than viewport, page should scroll
    if (bodyHeight > viewportHeight) {
      // Attempt to scroll down
      await page.evaluate(() => window.scrollBy(0, 200))
      const scrollY = await page.evaluate(() => window.scrollY)
      expect(scrollY).toBeGreaterThan(0)
    }
  })

  test('MR-10: navigation is accessible on mobile', async ({ page }) => {
    await page.goto(`${base}/security`)
    await page.waitForSelector('[data-testid="toggle-crowdsec"]', { timeout: 10000 })

    // On mobile, there should be some form of navigation
    // Check if sidebar or mobile menu toggle exists
    const sidebar = page.locator('nav, aside, [role="navigation"]')
    const sidebarCount = await sidebar.count()

    // Navigation should exist in some form
    expect(sidebarCount).toBeGreaterThanOrEqual(0) // May be hidden on mobile
  })

  test('MR-06b: overlay renders correctly on mobile', async ({ page }) => {
    await page.goto(`${base}/security`)
    await page.waitForSelector('[data-testid="toggle-crowdsec"]', { timeout: 10000 })

    // Skip if Cerberus is disabled (toggles would be disabled)
    const cerberusDisabled = await page.locator('text=Cerberus Disabled').isVisible()
    if (cerberusDisabled) {
      test.skip()
      return
    }

    // Trigger loading state by clicking a toggle
    const wafToggle = page.getByTestId('toggle-waf')
    const isDisabled = await wafToggle.isDisabled()

    if (!isDisabled) {
      await wafToggle.click()

      // Check for overlay (may appear briefly)
      // Use a short timeout since it might disappear quickly
      try {
        const overlay = page.locator('.fixed.inset-0')
        await overlay.waitFor({ state: 'visible', timeout: 2000 })

        // If overlay appeared, verify it fits screen
        const box = await overlay.boundingBox()
        if (box) {
          expect(box.width).toBeLessThanOrEqual(375 + 10) // Allow small margin
        }
      } catch {
        // Overlay might have disappeared before we could check
        // This is acceptable for a fast operation
      }
    }
  })
})

test.describe('Security Dashboard Tablet (768x1024)', () => {
  test.use({ viewport: { width: 768, height: 1024 } })

  test('MR-02: cards show 2 columns on tablet', async ({ page }) => {
    await page.goto(`${base}/security`)
    await page.waitForSelector('[data-testid="toggle-crowdsec"]', { timeout: 10000 })

    // On tablet (md breakpoint), should have md:grid-cols-2
    const grid = page.locator('.grid').first()
    await expect(grid).toBeVisible()

    // Get computed style
    const gridStyle = await grid.evaluate((el) => {
      const style = window.getComputedStyle(el)
      return style.gridTemplateColumns
    })

    // Should have 2 columns at md breakpoint
    const columns = gridStyle.split(' ').filter((s) => s.trim().length > 0 && s !== 'none')
    expect(columns.length).toBeGreaterThanOrEqual(2)
  })

  test('MR-08: cards have proper spacing on tablet', async ({ page }) => {
    await page.goto(`${base}/security`)
    await page.waitForSelector('[data-testid="toggle-crowdsec"]', { timeout: 10000 })

    // Check gap between cards
    const grid = page.locator('.grid.gap-6').first()
    const hasGap = await grid.isVisible()
    expect(hasGap).toBe(true)
  })
})

test.describe('Security Dashboard Desktop (1920x1080)', () => {
  test.use({ viewport: { width: 1920, height: 1080 } })

  test('MR-03: cards show 4 columns on desktop', async ({ page }) => {
    await page.goto(`${base}/security`)
    await page.waitForSelector('[data-testid="toggle-crowdsec"]', { timeout: 10000 })

    // On desktop (lg breakpoint), should have lg:grid-cols-4
    const grid = page.locator('.grid').first()
    await expect(grid).toBeVisible()

    // Get computed style
    const gridStyle = await grid.evaluate((el) => {
      const style = window.getComputedStyle(el)
      return style.gridTemplateColumns
    })

    // Should have 4 columns at lg breakpoint
    const columns = gridStyle.split(' ').filter((s) => s.trim().length > 0 && s !== 'none')
    expect(columns.length).toBeGreaterThanOrEqual(4)
  })
})

test.describe('Security Dashboard Layout Tests', () => {
  test('cards maintain correct order across viewports', async ({ page }) => {
    // Test on mobile
    await page.setViewportSize({ width: 375, height: 667 })
    await page.goto(`${base}/security`)
    await page.waitForSelector('[data-testid="toggle-crowdsec"]', { timeout: 10000 })

    // Get card headings
    const getCardOrder = async () => {
      const headings = await page.locator('h3').allTextContents()
      return headings.filter((h) => ['CrowdSec', 'Access Control', 'Coraza', 'Rate Limiting'].includes(h))
    }

    const mobileOrder = await getCardOrder()

    // Test on tablet
    await page.setViewportSize({ width: 768, height: 1024 })
    await page.waitForTimeout(100) // Allow reflow
    const tabletOrder = await getCardOrder()

    // Test on desktop
    await page.setViewportSize({ width: 1920, height: 1080 })
    await page.waitForTimeout(100) // Allow reflow
    const desktopOrder = await getCardOrder()

    // Order should be consistent
    expect(mobileOrder).toEqual(tabletOrder)
    expect(tabletOrder).toEqual(desktopOrder)
    expect(desktopOrder).toEqual(['CrowdSec', 'Access Control', 'Coraza', 'Rate Limiting'])
  })

  test('MR-09: all security cards are visible on scroll', async ({ page }) => {
    await page.setViewportSize({ width: 375, height: 667 })
    await page.goto(`${base}/security`)
    await page.waitForSelector('[data-testid="toggle-crowdsec"]', { timeout: 10000 })

    // Scroll to each card type
    const cardTypes = ['CrowdSec', 'Access Control', 'Coraza', 'Rate Limiting']

    for (const cardType of cardTypes) {
      const card = page.locator(`h3:has-text("${cardType}")`)
      await card.scrollIntoViewIfNeeded()
      await expect(card).toBeVisible()
    }
  })
})

test.describe('Security Dashboard Interaction Tests', () => {
  test.use({ viewport: { width: 375, height: 667 } })

  test('MR-07: config buttons navigate correctly on mobile', async ({ page }) => {
    await page.goto(`${base}/security`)
    await page.waitForSelector('[data-testid="toggle-crowdsec"]', { timeout: 10000 })

    // Skip if Cerberus disabled
    const cerberusDisabled = await page.locator('text=Cerberus Disabled').isVisible()
    if (cerberusDisabled) {
      test.skip()
      return
    }

    // Find and click WAF Configure button
    const configureButton = page.locator('button:has-text("Configure")').first()

    if (await configureButton.isVisible()) {
      await configureButton.click()

      // Should navigate to a config page
      await page.waitForTimeout(500)
      const url = page.url()

      // URL should include security/waf or security/rate-limiting etc
      expect(url).toMatch(/security\/(waf|rate-limiting|access-lists|crowdsec)/i)
    }
  })

  test('documentation button works on mobile', async ({ page }) => {
    await page.goto(`${base}/security`)
    await page.waitForSelector('[data-testid="toggle-crowdsec"]', { timeout: 10000 })

    // Find documentation button
    const docButton = page.locator('button:has-text("Documentation"), a:has-text("Documentation")').first()

    if (await docButton.isVisible()) {
      // Check it has correct external link behavior
      const onclick = await docButton.getAttribute('onclick')
      const href = await docButton.getAttribute('href')

      // Should open external docs
      if (href) {
        expect(href).toContain('wikid82.github.io')
      }
    }
  })
})
