/**
 * Playwright Test Fixtures for AI Compliance SDK
 *
 * These fixtures provide reusable setup for SDK E2E tests.
 * Demo data is seeded via the API (same storage path as real data).
 */

import { test as base, expect, Page } from '@playwright/test'

// Selectors for SDK components
export const selectors = {
  // Dashboard
  dashboard: '[data-testid="sdk-dashboard"]',
  loadDemoDataButton: '[data-testid="load-demo-data"]',
  progressBar: '[data-testid="progress-bar"]',

  // Sidebar
  sidebar: '[data-testid="sdk-sidebar"]',
  sidebarPhase1: '[data-testid="sidebar-phase-1"]',
  sidebarPhase2: '[data-testid="sidebar-phase-2"]',
  sidebarStep: (stepId: string) => `[data-testid="sidebar-step-${stepId}"]`,

  // Command Bar
  commandBar: '[data-testid="command-bar"]',
  commandInput: '[data-testid="command-input"]',
  commandSuggestion: (index: number) => `[data-testid="command-suggestion-${index}"]`,

  // Navigation
  prevButton: '[data-testid="prev-step-button"]',
  nextButton: '[data-testid="next-step-button"]',
  stepHeader: '[data-testid="step-header"]',

  // Use Case Workshop
  useCaseCard: (index: number) => `[data-testid="use-case-card-${index}"]`,
  addUseCaseButton: '[data-testid="add-use-case-button"]',
  useCaseForm: '[data-testid="use-case-form"]',

  // Risk Matrix
  riskCard: (riskId: string) => `[data-testid="risk-card-${riskId}"]`,
  riskMatrix: '[data-testid="risk-matrix"]',
  addRiskButton: '[data-testid="add-risk-button"]',

  // Controls
  controlCard: (controlId: string) => `[data-testid="control-card-${controlId}"]`,
  controlsGrid: '[data-testid="controls-grid"]',

  // Export
  exportButton: '[data-testid="export-button"]',
  exportPdfButton: '[data-testid="export-pdf-button"]',
  exportZipButton: '[data-testid="export-zip-button"]',
}

// Type for SDK test fixtures
type SDKFixtures = {
  sdkPage: Page
  withDemoData: Page
  commandBar: Page
}

/**
 * Extended test with SDK-specific fixtures
 */
export const test = base.extend<SDKFixtures>({
  // Basic SDK page (navigates to dashboard)
  sdkPage: async ({ page }, use) => {
    await page.goto('/sdk')
    // Wait for page to be ready
    await page.waitForLoadState('networkidle')
    await use(page)
  },

  // SDK page with demo data loaded
  withDemoData: async ({ page }, use) => {
    // Navigate to SDK
    await page.goto('/sdk')
    await page.waitForLoadState('networkidle')

    // Seed demo data via API (same storage path as real data)
    await page.evaluate(async () => {
      const response = await fetch('/api/sdk/v1/demo/seed', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ tenantId: 'e2e-test-tenant' }),
      })
      if (!response.ok) {
        // If endpoint doesn't exist, try seeding via localStorage
        // This is a fallback for development
        console.warn('Demo seed endpoint not available, using localStorage fallback')
      }
    })

    // Reload page to pick up demo data
    await page.reload()
    await page.waitForLoadState('networkidle')

    await use(page)

    // Cleanup: Clear demo data after test
    await page.evaluate(async () => {
      try {
        await fetch('/api/sdk/v1/demo/clear', {
          method: 'DELETE',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ tenantId: 'e2e-test-tenant' }),
        })
      } catch {
        // Ignore cleanup errors
      }
    })
  },

  // SDK page with command bar opened
  commandBar: async ({ page }, use) => {
    await page.goto('/sdk')
    await page.waitForLoadState('networkidle')

    // Open command bar with keyboard shortcut
    await page.keyboard.press('Meta+k')

    // Wait for command bar to be visible
    await page.waitForSelector(selectors.commandBar, { state: 'visible' })

    await use(page)
  },
})

// Re-export expect for convenience
export { expect }

/**
 * Helper: Wait for SDK to initialize
 */
export async function waitForSDKInit(page: Page): Promise<void> {
  await page.waitForLoadState('networkidle')
  // Wait for React hydration
  await page.waitForFunction(() => {
    return document.querySelector('[data-testid="sdk-dashboard"]') !== null ||
           document.querySelector('[data-testid="step-header"]') !== null
  }, { timeout: 10000 })
}

/**
 * Helper: Navigate to a specific SDK step
 */
export async function navigateToStep(page: Page, stepId: string): Promise<void> {
  const stepUrl = getStepUrl(stepId)
  await page.goto(stepUrl)
  await waitForSDKInit(page)
}

/**
 * Helper: Get URL for a step
 */
export function getStepUrl(stepId: string): string {
  const stepUrls: Record<string, string> = {
    'use-case-workshop': '/sdk/advisory-board',
    'screening': '/sdk/screening',
    'modules': '/sdk/modules',
    'requirements': '/sdk/requirements',
    'controls': '/sdk/controls',
    'evidence': '/sdk/evidence',
    'audit-checklist': '/sdk/audit-checklist',
    'risks': '/sdk/risks',
    'ai-act': '/sdk/ai-act',
    'obligations': '/sdk/obligations',
    'dsfa': '/sdk/dsfa',
    'tom': '/sdk/tom',
    'loeschfristen': '/sdk/loeschfristen',
    'vvt': '/sdk/vvt',
    'consent': '/sdk/consent',
    'cookie-banner': '/sdk/cookie-banner',
    'einwilligungen': '/sdk/einwilligungen',
    'dsr': '/sdk/dsr',
    'escalations': '/sdk/escalations',
  }
  return stepUrls[stepId] || '/sdk'
}

/**
 * Helper: Use command bar to navigate
 */
export async function useCommandBarToNavigate(page: Page, searchTerm: string): Promise<void> {
  // Open command bar
  await page.keyboard.press('Meta+k')
  await page.waitForSelector(selectors.commandBar, { state: 'visible' })

  // Type search term
  await page.fill(selectors.commandInput, searchTerm)

  // Wait for suggestions
  await page.waitForSelector(selectors.commandSuggestion(0), { timeout: 5000 })

  // Click first suggestion
  await page.click(selectors.commandSuggestion(0))

  // Wait for navigation
  await page.waitForLoadState('networkidle')
}

/**
 * Helper: Seed demo data programmatically
 */
export async function seedDemoData(page: Page, tenantId: string = 'e2e-test'): Promise<boolean> {
  const result = await page.evaluate(async (tid) => {
    try {
      const response = await fetch('/api/sdk/v1/demo/seed', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ tenantId: tid }),
      })
      return response.ok
    } catch {
      return false
    }
  }, tenantId)

  if (result) {
    await page.reload()
    await waitForSDKInit(page)
  }

  return result
}

/**
 * Helper: Clear demo data
 */
export async function clearDemoData(page: Page, tenantId: string = 'e2e-test'): Promise<boolean> {
  return await page.evaluate(async (tid) => {
    try {
      const response = await fetch('/api/sdk/v1/demo/clear', {
        method: 'DELETE',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ tenantId: tid }),
      })
      return response.ok
    } catch {
      return false
    }
  }, tenantId)
}
