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

/**
 * IACE (CE-Compliance) Module — New Feature E2E Tests
 *
 * Covers: Order, Interview (Grenzen & Verwendung), Compliance Alerts,
 * Risk Assessment Table, Mitigations batch actions, CE-Akte Export,
 * Production Lines, Normenrecherche.
 *
 * Run with:
 *   npx playwright test e2e/specs/iace-features.spec.ts --config e2e/playwright-live.config.ts --reporter=list
 */

const BASE = 'https://macmini:3007'

const PROJECTS = [
  {
    id: 'bb7d5b88-469d-401f-a0e3-ae5b867e4a1c',
    name: 'Kniehebelpresse HP-500',
  },
  {
    id: 'a4c4031e-75a5-461e-a575-159f1eabd6b3',
    name: 'EIGENBAU-Zelle (Cobot)',
  },
  {
    id: 'c43af8df-14e0-43ff-b26f-ab425f803e53',
    name: 'Gleichstrom-/Asynchronmotor',
  },
  {
    id: '3e0808b2-2eed-4e82-b35d-6dd6857bc379',
    name: 'Schwingarm-Rundtaktanlage',
  },
] as const

const COBOT_PROJECT_ID = 'a4c4031e-75a5-461e-a575-159f1eabd6b3'
const PRODUCTION_LINE_ID = 'c63b774e-22d4-4045-bb8d-646df626c42b'

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

async function dismissCookieBanner(page: Page) {
  try {
    const acceptBtn = page.locator('button', { hasText: 'Nur notwendige Cookies' })
    if (await acceptBtn.isVisible({ timeout: 3000 })) {
      await acceptBtn.click({ force: true })
      await page.waitForTimeout(500)
    }
  } catch {
    // Banner not present or already dismissed
  }
}

async function goTo(page: Page, path: string) {
  await page.goto(`${BASE}${path}`, { waitUntil: 'networkidle', timeout: 30000 })
  await page.waitForTimeout(2000)
  await dismissCookieBanner(page)
}

async function assertNoAppError(page: Page) {
  const body = await page.textContent('body')
  expect(body).not.toContain('Application error')
  expect(body).not.toContain('Unhandled Runtime Error')
}

// ---------------------------------------------------------------------------
// Per-project new feature tests
// ---------------------------------------------------------------------------

for (const project of PROJECTS) {
  // ------ Order tab ------
  test.describe(`Order: ${project.name}`, () => {
    test.setTimeout(60_000)

    test('order tab loads', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/order`)
      await assertNoAppError(page)
      await expect(page.locator('h1')).toContainText('Auftrag', { timeout: 15000 })
    })

    test('order — form fields visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/order`)
      const body = await page.innerText('body')
      expect(body).toContain('Auftraggeber')
      expect(body).toContain('Firmenname')
      expect(body).toContain('Ansprechpartner')
      expect(body).toContain('E-Mail')
      expect(body).toContain('Telefon')
    })

    test('order — status dropdown works', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/order`)
      const statusSelect = page.locator('select')
      await expect(statusSelect.first()).toBeVisible({ timeout: 10000 })
      const options = statusSelect.first().locator('option')
      const count = await options.count()
      expect(count).toBeGreaterThanOrEqual(3)
    })

    test('order — Auftrag and Angebot sections visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/order`)
      await expect(page.locator('text=Auftrag').first()).toBeVisible({ timeout: 10000 })
      await expect(page.locator('text=Angebot').first()).toBeVisible({ timeout: 10000 })
      await expect(page.locator('text=Notizen')).toBeVisible({ timeout: 10000 })
    })

    test('order — scope options visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/order`)
      const body = await page.innerText('body')
      expect(body).toContain('Risikobeurteilung')
      expect(body).toContain('CE-Kennzeichnung')
    })
  })

  // ------ Interview (Grenzen & Verwendung) ------
  test.describe(`Interview: ${project.name}`, () => {
    test.setTimeout(60_000)

    test('interview tab loads', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/interview`)
      await assertNoAppError(page)
      await expect(page.locator('h1')).toContainText('Grenzen', { timeout: 15000 })
    })

    test('interview — form sections visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/interview`)
      const body = await page.innerText('body')
      // Section titles contain the number prefix ("1. Allgemeine Produktbeschreibung")
      expect(body).toContain('Allgemeine Produktbeschreibung')
      expect(body).toContain('Bestimmungsgemasse Verwendung')
      expect(body).toContain('Vorhersehbare Fehlanwendung')
      expect(body).toContain('Grenzen der Maschine')
      expect(body).toContain('Schnittstellen')
      expect(body).toContain('Betroffene Personen')
    })

    test('interview — pre-filled data visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/interview`)
      await page.waitForTimeout(2000)
      const body = await page.innerText('body')
      const hasProjectName = body.includes(project.name) || body.includes('Vorausgefuellt')
      expect(hasProjectName).toBeTruthy()
    })

    test('interview — section collapse/expand works', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/interview`)
      // Click on a collapsed section to expand it
      const sectionBtn = page.locator('button').filter({ hasText: 'Bestimmungsgemasse Verwendung' })
      await expect(sectionBtn).toBeVisible({ timeout: 10000 })
      await sectionBtn.click()
      await page.waitForTimeout(1000)
      // After expanding, "Verwendungszweck" should appear in the body
      const bodyAfter = await page.innerText('body')
      expect(bodyAfter).toContain('Verwendungszweck')
    })

    test('interview — completion percentage visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/interview`)
      // CompletionBadge shows "X% ausgefuellt" — use body text check
      const body = await page.innerText('body')
      expect(body).toMatch(/\d+%\s*ausgefuellt/)
    })

    test('interview — navigation buttons present', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/interview`)
      const body = await page.innerText('body')
      expect(body).toContain('Zurueck zur Uebersicht')
      expect(body).toContain('Weiter zu Komponenten')
    })
  })

  // ------ Hazards: Risk Assessment ------
  test.describe(`Risk Assessment: ${project.name}`, () => {
    test.setTimeout(60_000)

    test('hazards — default view is Risikobewertung', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/hazards`)
      await page.waitForTimeout(2000)
      const body = await page.innerText('body')
      expect(body).toContain('Risikobewertungstabelle')
    })

    test('hazards — S/E/P dropdowns visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/hazards`)
      await page.waitForTimeout(3000)
      const selects = page.locator('select')
      await expect(selects.first()).toBeVisible({ timeout: 15000 })
      const selectCount = await selects.count()
      expect(selectCount).toBeGreaterThan(0)
      const firstValue = await selects.first().inputValue()
      const numValue = parseInt(firstValue, 10)
      expect(numValue).toBeGreaterThanOrEqual(1)
    })

    test('hazards — "Gefaehrdungen erkennen" button visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/hazards`)
      await expect(
        page.locator('button', { hasText: 'Gefaehrdungen erkennen' })
      ).toBeVisible({ timeout: 10000 })
    })
  })

  // ------ Mitigations: Batch actions ------
  test.describe(`Mitigations batch: ${project.name}`, () => {
    test.setTimeout(60_000)

    test('mitigations — 3 accordion sections visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/mitigations`)
      await expect(page.locator('text=Stufe 1: Design')).toBeVisible({ timeout: 10000 })
      await expect(page.locator('text=Stufe 2: Schutz')).toBeVisible({ timeout: 10000 })
      await expect(page.locator('text=Stufe 3: Information')).toBeVisible({ timeout: 10000 })
    })

    test('mitigations — checkbox selection works', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/mitigations`)
      await page.waitForTimeout(2000)
      const checkboxes = page.locator('input[type="checkbox"]')
      const count = await checkboxes.count()
      if (count > 0) {
        await checkboxes.first().click()
        await page.waitForTimeout(500)
        const body = await page.innerText('body')
        expect(body).toContain('ausgewaehlt')
      }
    })

    test('mitigations — batch buttons appear when items selected', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/mitigations`)
      await page.waitForTimeout(2000)
      const checkboxes = page.locator('input[type="checkbox"]')
      const count = await checkboxes.count()
      if (count > 0) {
        await checkboxes.first().click()
        await page.waitForTimeout(500)
        await expect(
          page.locator('button', { hasText: 'Verifizieren' })
        ).toBeVisible({ timeout: 10000 })
        await expect(
          page.locator('button', { hasText: 'Loeschen' })
        ).toBeVisible({ timeout: 10000 })
      }
    })
  })

  // ------ Tech File: Export buttons ------
  test.describe(`Tech File Export: ${project.name}`, () => {
    test.setTimeout(60_000)

    test('tech-file — "PDF exportieren" button visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/tech-file`)
      await expect(
        page.locator('button', { hasText: 'PDF exportieren' })
      ).toBeVisible({ timeout: 10000 })
    })

    test('tech-file — "Excel exportieren" button visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/tech-file`)
      await expect(
        page.locator('button', { hasText: 'Excel exportieren' })
      ).toBeVisible({ timeout: 10000 })
    })

    test('tech-file — progress or sections visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}/tech-file`)
      await page.waitForTimeout(2000)
      const body = await page.innerText('body')
      // Progress section or section list renders
      const hasContent = body.includes('Fortschritt') ||
        body.includes('Generieren') ||
        body.includes('Keine Abschnitte')
      expect(hasContent).toBeTruthy()
    })
  })

  // ------ Overview: Compliance Alerts & Normenrecherche ------
  test.describe(`Overview features: ${project.name}`, () => {
    test.setTimeout(60_000)

    test('overview — compliance alerts or quick actions visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}`)
      await page.waitForTimeout(3000)
      await assertNoAppError(page)
      const body = await page.innerText('body')
      const hasAlerts = body.includes('Compliance-Hinweise erkannt')
      const hasQuick = body.includes('Schnellzugriff')
      expect(hasAlerts || hasQuick).toBeTruthy()
    })

    test('overview — regulation badges when alerts present', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}`)
      await page.waitForTimeout(3000)
      const body = await page.innerText('body')
      if (body.includes('Compliance-Hinweise erkannt')) {
        const hasBadge = body.includes('DSGVO') ||
          body.includes('AI Act') || body.includes('CRA')
        expect(hasBadge).toBeTruthy()
      }
    })

    test('overview — normenrecherche section visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}`)
      await page.waitForTimeout(3000)
      const body = await page.innerText('body')
      if (body.includes('Normenrecherche')) {
        expect(body).toContain('relevante Normen')
      }
    })

    test('overview — norm add input when norms visible', async ({ page }) => {
      await goTo(page, `/sdk/iace/${project.id}`)
      await page.waitForTimeout(3000)
      const addInput = page.locator('input[placeholder*="ISO 13857"]')
      if (await addInput.count() > 0) {
        await expect(addInput.first()).toBeVisible({ timeout: 10000 })
      }
    })
  })
}

// ---------------------------------------------------------------------------
// Compliance Alerts — Cobot project specific
// ---------------------------------------------------------------------------

test.describe('Compliance Alerts — Cobot', () => {
  test.setTimeout(60_000)

  test('trigger count > 0', async ({ page }) => {
    await goTo(page, `/sdk/iace/${COBOT_PROJECT_ID}`)
    await page.waitForTimeout(4000)
    const body = await page.innerText('body')
    if (body.includes('Compliance-Hinweise erkannt')) {
      const match = body.match(/(\d+)\s*Compliance-Hinweise erkannt/)
      expect(match).not.toBeNull()
      if (match) {
        expect(parseInt(match[1], 10)).toBeGreaterThan(0)
      }
    }
  })

  test('regulation badges visible', async ({ page }) => {
    await goTo(page, `/sdk/iace/${COBOT_PROJECT_ID}`)
    await page.waitForTimeout(4000)
    const body = await page.innerText('body')
    if (body.includes('Compliance-Hinweise erkannt')) {
      const hasDSGVO = body.includes('DSGVO')
      const hasAIAct = body.includes('AI Act')
      const hasCRA = body.includes('CRA')
      expect(hasDSGVO || hasAIAct || hasCRA).toBeTruthy()
    }
  })
})

// ---------------------------------------------------------------------------
// Production Lines
// ---------------------------------------------------------------------------

test.describe('Production Lines', () => {
  test.setTimeout(60_000)

  test('lines list page loads', async ({ page }) => {
    await goTo(page, '/sdk/iace/lines')
    await assertNoAppError(page)
    await expect(page.locator('h1')).toContainText('Produktionslinien', { timeout: 15000 })
  })

  test('"Neue Produktionslinie" button visible', async ({ page }) => {
    await goTo(page, '/sdk/iace/lines')
    await expect(
      page.locator('button', { hasText: 'Neue Produktionslinie' })
    ).toBeVisible({ timeout: 10000 })
  })

  test('"Fertigungsstrasse Halle 3" visible', async ({ page }) => {
    await goTo(page, '/sdk/iace/lines')
    await page.waitForTimeout(3000)
    const body = await page.innerText('body')
    expect(body).toContain('Fertigungsstrasse Halle 3')
  })

  test('line dashboard loads with stations', async ({ page }) => {
    await goTo(page, `/sdk/iace/lines/${PRODUCTION_LINE_ID}`)
    await assertNoAppError(page)
    await page.waitForTimeout(3000)
    await expect(
      page.locator('text=Stationsuebersicht')
    ).toBeVisible({ timeout: 15000 })
  })

  test('line dashboard — station cards rendered', async ({ page }) => {
    await goTo(page, `/sdk/iace/lines/${PRODUCTION_LINE_ID}`)
    await page.waitForTimeout(3000)
    const body = await page.innerText('body')
    expect(body).toContain('Stationsuebersicht')
    await expect(
      page.locator('text=Alle Produktionslinien')
    ).toBeVisible({ timeout: 10000 })
  })

  test('line dashboard — back link', async ({ page }) => {
    await goTo(page, `/sdk/iace/lines/${PRODUCTION_LINE_ID}`)
    const backLink = page.locator('a', { hasText: 'Alle Produktionslinien' })
    await expect(backLink).toBeVisible({ timeout: 10000 })
  })
})

// ---------------------------------------------------------------------------
// Normenrecherche — Cobot project
// ---------------------------------------------------------------------------

test.describe('Normenrecherche — Cobot', () => {
  test.setTimeout(60_000)

  test('shows norm count', async ({ page }) => {
    await goTo(page, `/sdk/iace/${COBOT_PROJECT_ID}`)
    await page.waitForTimeout(4000)
    const body = await page.innerText('body')
    if (body.includes('Normenrecherche')) {
      expect(body).toContain('relevante Normen')
      // Extract and verify a substantial count
      const match = body.match(/(\d+)\s*relevante Normen/)
      if (match) {
        expect(parseInt(match[1], 10)).toBeGreaterThan(50)
      }
    }
  })

  test('add norm input visible', async ({ page }) => {
    await goTo(page, `/sdk/iace/${COBOT_PROJECT_ID}`)
    await page.waitForTimeout(4000)
    const body = await page.innerText('body')
    // Check the "Weitere Norm ergaenzen" text and input field
    if (body.includes('Normenrecherche')) {
      expect(body).toContain('Weitere Norm ergaenzen')
    }
  })
})
