// Golden-Path E2E test skeletons — Batch 6 scaffold.
//
// ALL tests are marked test.fixme — they require:
//   1. A running application (npm run dev or deployed staging URL)
//   2. A seeded Supabase database with two test users (user_a, user_b)
//   3. The env vars listed in docs/E2E.md
//
// To enable a test: replace test.fixme with test and ensure the prerequisites are met.
// Run: npx playwright test
//
// @ts-expect-error — install @playwright/test before enabling: npm install --save-dev @playwright/test
import { test, expect } from '@playwright/test'

// ─── Fixtures — read from env (populated by CI seed or local .env.test.e2e) ──

const E2E_USER_EMAIL    = process.env.E2E_USER_EMAIL    ?? 'testuser_a@example.com'
const E2E_USER_PASSWORD = process.env.E2E_USER_PASSWORD ?? 'change-me'
const E2E_ADMIN_EMAIL   = process.env.E2E_ADMIN_EMAIL   ?? 'testadmin@example.com'
const E2E_ADMIN_PASSWORD= process.env.E2E_ADMIN_PASSWORD?? 'change-me'
const E2E_USER_B_EMAIL  = process.env.E2E_USER_B_EMAIL  ?? 'testuser_b@example.com'
const E2E_USER_B_PASSWORD= process.env.E2E_USER_B_PASSWORD ?? 'change-me'

// ─── GP-01: Login → Projekt anlegen → Stoppuhr → Refresh ─────────────────────

test.describe('GP-01: Login → Projekt anlegen → Stoppuhr → Refresh (P0)', () => {
  test.fixme(
    'should preserve all 3 cycle measurements after a browser refresh',
    async ({ page }) => {
      // Step 1 — Login
      await page.goto('/login')
      await page.fill('[data-testid="email"]', E2E_USER_EMAIL)
      await page.fill('[data-testid="password"]', E2E_USER_PASSWORD)
      await page.click('[data-testid="login-submit"]')
      await expect(page).toHaveURL(/\/dashboard/)

      // Step 2 — Neues Projekt anlegen
      await page.click('[data-testid="new-project-button"]')
      await page.fill('[data-testid="supplier-name"]', 'E2E Supplier GmbH')
      await page.fill('[data-testid="visit-date"]', '2026-06-01')
      // Select Auftragstyp (LSC Workshop)
      await page.click('[data-testid="order-type-selector"]')
      await page.click('[data-testid="order-type-lsc"]')
      await page.click('[data-testid="save-project"]')
      await expect(page).toHaveURL(/\/project\/[^/]+/)

      // Step 3 — Stopwatch tab → Station anlegen
      await page.click('[data-testid="stopwatch-tab"]')
      await page.click('[data-testid="add-station"]')
      await page.fill('[data-testid="station-name"]', 'Station E2E-1')
      await page.click('[data-testid="save-station"]')

      // Step 4 — 3 Messungen erfassen
      const stopBtn = page.locator('[data-testid="stopwatch-button"]')
      for (let i = 0; i < 3; i++) {
        await stopBtn.click() // start
        await page.waitForTimeout(1200)
        await stopBtn.click() // stop = save measurement
      }

      // Verify 3 measurements visible
      const measurements = page.locator('[data-testid="measurement-row"]')
      await expect(measurements).toHaveCount(3)

      // Step 5 — Browser-Tab neu laden (F5)
      await page.reload()
      await page.waitForLoadState('networkidle')

      // Step 6 — Alle 3 Messungen vorhanden
      // This is the critical assertion: data must survive a reload.
      const measurementsAfterReload = page.locator('[data-testid="measurement-row"]')
      await expect(measurementsAfterReload).toHaveCount(3)
    }
  )
})

// ─── GP-02: LSC Workshop (P0) ─────────────────────────────────────────────────

test.describe('GP-02: LSC Workshop — OEE erfassen + Berichts-Konsistenz (P0)', () => {
  test.fixme(
    'OEE tab values should match the visualisation in the report tab',
    async ({ page }) => {
      // Step 1 — Login + LSC-Projekt öffnen
      await page.goto('/login')
      await page.fill('[data-testid="email"]', E2E_USER_EMAIL)
      await page.fill('[data-testid="password"]', E2E_USER_PASSWORD)
      await page.click('[data-testid="login-submit"]')
      await page.goto('/dashboard')
      // Open a pre-seeded LSC project
      await page.click('[data-testid="project-row"]:first-child')

      // Step 2 — Workshop tab → Neue Schicht anlegen
      await page.click('[data-testid="workshop-tab"]')
      await page.click('[data-testid="add-shift"]')
      await page.fill('[data-testid="shift-date"]', '2026-06-01')
      await page.click('[data-testid="save-shift"]')

      // Step 3 — OEE Tab → Werte eingeben
      await page.click('[data-testid="oee-tab"]')
      await page.fill('[data-testid="oee-availability"]', '95')
      await page.fill('[data-testid="oee-performance"]', '88')
      await page.fill('[data-testid="oee-quality"]', '99')
      await page.click('[data-testid="save-oee"]')

      // Expected OEE: 0.95 * 0.88 * 0.99 ≈ 82.7 %
      const expectedOee = (0.95 * 0.88 * 0.99 * 100).toFixed(1)

      // Step 4 — Bericht tab → OEE-Visualisierung prüfen
      await page.click('[data-testid="report-tab"]')
      const oeeDisplay = page.locator('[data-testid="oee-summary-value"]')
      await expect(oeeDisplay).toContainText(expectedOee)
    }
  )
})

// ─── GP-03: Agenda erstellen → Export (P1) ────────────────────────────────────

test.describe('GP-03: Agenda erstellen → PDF + Excel Export (P1)', () => {
  test.fixme(
    'exported files should not be empty and values should match UI',
    async ({ page }) => {
      // Step 1 — Projekt öffnen → Agenda-Tab
      await page.goto('/login')
      await page.fill('[data-testid="email"]', E2E_USER_EMAIL)
      await page.fill('[data-testid="password"]', E2E_USER_PASSWORD)
      await page.click('[data-testid="login-submit"]')
      await page.click('[data-testid="project-row"]:first-child')
      await page.click('[data-testid="agenda-tab"]')

      // Step 2 — Wizard: Workshop-Typ + Tage + Teilnehmer
      await page.click('[data-testid="new-agenda-wizard"]')
      await page.click('[data-testid="workshop-type-lsc"]')
      await page.fill('[data-testid="agenda-days"]', '2')
      await page.click('[data-testid="add-participant"]')
      await page.fill('[data-testid="participant-name-0"]', 'Teilnehmer E2E')
      await page.click('[data-testid="wizard-next"]')
      await page.click('[data-testid="wizard-save"]')

      // Step 3 — Editor: Agenda-Punkt verschieben (DnD)
      // Drag first item to position 2 — just verify DnD doesn't crash
      const firstItem = page.locator('[data-testid="agenda-item"]:first-child')
      const secondItem = page.locator('[data-testid="agenda-item"]:nth-child(2)')
      await firstItem.dragTo(secondItem)

      // Step 4 — Export PDF
      const [pdfDownload] = await Promise.all([
        page.waitForEvent('download'),
        page.click('[data-testid="export-pdf"]'),
      ])
      expect(pdfDownload.suggestedFilename()).toMatch(/\.pdf$/)

      // Step 5 — Export Excel
      const [xlsxDownload] = await Promise.all([
        page.waitForEvent('download'),
        page.click('[data-testid="export-excel"]'),
      ])
      expect(xlsxDownload.suggestedFilename()).toMatch(/\.(xlsx|xls)$/)
    }
  )
})

// ─── GP-04: Nutzer ohne Rechte sieht/ändert nichts (P1) ──────────────────────

test.describe('GP-04: Permission gates — non-admin cannot access admin routes (P1)', () => {
  test.fixme(
    'consultant should be redirected or shown 403 when accessing /admin',
    async ({ page }) => {
      // Step 1 — Login als Berater (nicht Admin)
      await page.goto('/login')
      await page.fill('[data-testid="email"]', E2E_USER_EMAIL)
      await page.fill('[data-testid="password"]', E2E_USER_PASSWORD)
      await page.click('[data-testid="login-submit"]')
      await expect(page).toHaveURL(/\/dashboard/)

      // Step 2 — Zugriff auf /admin → redirect oder 403
      await page.goto('/admin')
      // Should be redirected to dashboard or show a forbidden page
      const url = page.url()
      const hasForbidden = await page.locator('text=/Forbidden|403|Keine Berechtigung/i').isVisible()
      expect(
        url.includes('/dashboard') || url.includes('/login') || hasForbidden
      ).toBe(true)

      // Step 3 — Direktzugriff auf Projekt eines anderen Nutzers via URL
      // (requires seeded project ID for user_b)
      const OTHER_PROJECT_ID = process.env.E2E_OTHER_PROJECT_ID ?? 'seed-project-b-id'
      const res = await page.request.get(`/api/v1/projects/${OTHER_PROJECT_ID}`)
      // RLS should ensure this returns 404 or empty, not the actual project data
      expect([404, 403, 200]).toContain(res.status()) // 200 with empty data is acceptable
      if (res.status() === 200) {
        const body = await res.json()
        expect(body.data).toBeNull()
      }
    }
  )
})

// ─── GP-05: Mandant-Isolation (P0) ───────────────────────────────────────────

test.describe('GP-05: User isolation — user B cannot see user A projects (P0)', () => {
  test.fixme(
    'project created by user A should not appear in user B project list',
    async ({ page }) => {
      // This test requires two distinct users seeded in the same Supabase instance.
      // The staging DB must have user_a and user_b with projects belonging only to user_a.

      // Step 1 — Login as user A → create a project
      await page.goto('/login')
      await page.fill('[data-testid="email"]', E2E_USER_EMAIL)
      await page.fill('[data-testid="password"]', E2E_USER_PASSWORD)
      await page.click('[data-testid="login-submit"]')

      // Get the list of projects via API
      const resA = await page.request.get('/api/v1/projects')
      const bodyA = await resA.json()
      const projectIdsA: string[] = (bodyA.data ?? []).map((p: { id: string }) => p.id)

      // Step 2 — Login as user B → verify A's projects are invisible
      // (perform a new login by clearing cookies)
      await page.context().clearCookies()
      await page.goto('/login')
      await page.fill('[data-testid="email"]', E2E_USER_B_EMAIL)
      await page.fill('[data-testid="password"]', E2E_USER_B_PASSWORD)
      await page.click('[data-testid="login-submit"]')

      // Step 3 — GET /api/v1/projects as user B
      const resB = await page.request.get('/api/v1/projects')
      const bodyB = await resB.json()
      const projectIdsB: string[] = (bodyB.data ?? []).map((p: { id: string }) => p.id)

      // No overlap — user B must not see any of user A's projects
      const overlap = projectIdsA.filter((id) => projectIdsB.includes(id))
      expect(overlap).toHaveLength(0)
    }
  )
})
