// Multi-QAF workflow E2E test skeleton (KAR-953 / Multi-QAF-Programm,
// Master-Prompt §22 "End-to-end tests", 15-step list).
//
// SAME SCAFFOLD DISCIPLINE AS golden-path.spec.ts (see that file's own
// header + docs/E2E.md — read both before touching this file): ALL tests
// below are `test.fixme`. They require:
//   1. A running application (npm run dev or a deployed staging URL)
//   2. A seeded Supabase database with a test user AND an existing project
//      the test user owns
//   3. `@playwright/test` installed (NOT a default dependency — see
//      docs/E2E.md section 2) — `npm install --save-dev @playwright/test &&
//      npx playwright install chromium`
//   4. The env vars listed in docs/E2E.md, reused verbatim below
//
// To enable a test: replace `test.fixme` with `test` once the prerequisites
// are met. Run: `npx playwright test e2e/multi-qaf-workflow.spec.ts`
//
// KAR-953 investigation findings — WHERE THIS SPEC DELIBERATELY DEVIATES
// FROM A NAIVE READING OF MASTER-PROMPT §22's 15-STEP LIST (documented here,
// not silently papered over, per task instruction "ehrlich an die echte
// App-Mechanik anpassen"):
//
//   (a) SAME AS golden-path.spec.ts: every `data-testid` selector below that
//       is not called out as "REAL testid" in a comment is ASPIRATIONAL —
//       golden-path.spec.ts's own selectors (`new-project-button`,
//       `stopwatch-button`, ...) do not exist anywhere in the current
//       app/components tree either (verified via repo-wide grep, 12.07.2026)
//       — that file is a scaffold for the INTENDED UX, not a description of
//       today's DOM, and this file follows the identical convention. TWO
//       testids used below ARE real today: `qaf-multi-qaf-status-badge` and
//       `qaf-multi-qaf-hero` (components/qaf-differences/
//       qaf-multi-qaf-nav.tsx / qaf-multi-qaf-hero.tsx) — called out inline.
//
//   (b) Step 12/14 "Export German report" / "Switch interface to English" /
//       "Export English report" — investigated the REAL mechanism
//       (lib/qaf-differences/internal/multi-qaf/export.ts's own module
//       header): the Multi-QAF XLSX export is BILINGUAL INLINE — "Every
//       status/reason/gate/check code is exported in TWO columns side by
//       side: the stable machine code (Code) AND a curated DE/EN
//       plain-language sentence" — there is only ONE export action
//       (QafXlsxExportButton -> exportMultiQafComparisonXlsx server action,
//       app/qaf-differences/actions.ts:2146), not a "DE-Export" and a
//       separate "EN-Export" producing DE-only/EN-only files. What DOES
//       switch between DE/EN is the on-SCREEN comparison-detail UI text
//       (lib/i18n/i18n-context.tsx's global `useTranslation()`/`t()` — a
//       genuine app-wide locale, not a QAF-page-local toggle, persisted to
//       localStorage key `sd_locale`, changed via the user-menu dropdown
//       under the Globe icon — components/layout/user-menu.tsx, currently
//       has NO data-testid hooks of its own). This spec therefore: (1)
//       triggers the ONE Excel export once, (2) switches the GLOBAL UI
//       locale to English and asserts the on-screen text changes, (3)
//       triggers the SAME Excel export again post-switch and asserts it
//       still succeeds — proving the locale switch never accidentally makes
//       the (inherently bilingual) export DE-only, EN-only, or broken. This
//       is the real app mechanic, not the master-prompt step list's literal
//       "two different-language export files" framing.
//
//   (c) Upload mechanism: the real QAF upload UI (components/qaf/
//       qaf-client.tsx) is a SINGLE hidden multi-file `<input type="file"
//       multiple accept=".xlsx,.xlsm">` behind one button (`+ QAF-Dateien`),
//       not two separate "upload baseline" / "upload current" inputs — both
//       fixture files are selected in one `setInputFiles([...])` call, same
//       as a user would drag-select both at once in a real file picker.
//       Turning two uploaded files into a COMPARISON is then a separate
//       slot-assignment step (components/qaf/qaf-comparison-board.tsx's own
//       `assignToSlot`/`clearSlot` "picker" UI, modes `vs-basis`/
//       `aufbauend`) — modeled below as `assign-to-baseline-slot` /
//       `assign-to-current-slot` aspirational testids on that same picker.
//
// Fixture files: e2e/fixtures/multi-qaf-baseline-v2.xlsx (M-QAF Version 2.0,
// 5 variants) and e2e/fixtures/multi-qaf-current.xlsx (same template, one
// variant REMOVED, the shared material component's unit price CHANGED) —
// generated by e2e/fixtures/generate-multi-qaf-fixtures.mjs (re-run that
// script to regenerate; FIXTURE-DATEN-REGEL applies — every code/number in
// the generator is free invention, never copied from the confidential real
// Multi-QAF corpus).

// @ts-expect-error — install @playwright/test before enabling: npm install --save-dev @playwright/test
import { test, expect } from '@playwright/test'
import path from 'node:path'

const E2E_USER_EMAIL = process.env.E2E_USER_EMAIL ?? 'testuser_a@example.com'
const E2E_USER_PASSWORD = process.env.E2E_USER_PASSWORD ?? 'change-me'
// A pre-seeded project the test user owns — the Multi-QAF workflow needs an
// existing project to upload into (same precondition class as golden-path's
// own `E2E_OTHER_PROJECT_ID`), not created fresh by this spec (project
// creation is GP-01's job, not this one's).
const E2E_MULTI_QAF_PROJECT_ID = process.env.E2E_MULTI_QAF_PROJECT_ID ?? 'seed-project-multi-qaf-id'

const BASELINE_FIXTURE = path.join(__dirname, 'fixtures', 'multi-qaf-baseline-v2.xlsx')
const CURRENT_FIXTURE = path.join(__dirname, 'fixtures', 'multi-qaf-current.xlsx')

test.describe('Multi-QAF workflow — 15-step end-to-end (Master-Prompt §22, P0)', () => {
  test.fixme(
    'upload baseline + current Multi-QAF files, review detection/matches, inspect container/variant/material/profile sections, export, switch language, re-export, reload and confirm persistence',
    async ({ page }) => {
      // Step 1 — Login + open the pre-seeded 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"]')
      await page.goto(`/project/${E2E_MULTI_QAF_PROJECT_ID}/qaf`)

      // Step 2 — Open QAF comparison (the project's QAF tab IS the
      // comparison entry point in this app — there is no separate
      // "Vergleich öffnen" sub-navigation).
      await expect(page).toHaveURL(new RegExp(`/project/${E2E_MULTI_QAF_PROJECT_ID}/qaf`))

      // Step 3 — Upload the Multi-QAF baseline (Golden-Fixture v2, 5
      // variants) AND Step 4 — upload the Multi-QAF current file (variant
      // removed + material price changed) — real mechanism: ONE hidden
      // multi-file input behind one button (finding (c) above).
      await page.click('[data-testid="qaf-upload-trigger"]')
      await page.setInputFiles('[data-testid="qaf-upload-input"]', [BASELINE_FIXTURE, CURRENT_FIXTURE])
      await expect(page.locator('[data-testid="qaf-file-row"]')).toHaveCount(2)

      // Step 5 — Detect templates and variants: assign the two uploaded
      // files to the comparison "slots" (real mechanism: qaf-comparison-
      // board.tsx's own picker — finding (c) above) and confirm the
      // resulting comparison shows the REAL, already-existing Multi-QAF
      // badge (components/qaf-differences/qaf-multi-qaf-nav.tsx).
      await page.click('[data-testid="qaf-file-row"]:nth-child(1) [data-testid="assign-to-baseline-slot"]')
      await page.click('[data-testid="qaf-file-row"]:nth-child(2) [data-testid="assign-to-current-slot"]')
      await page.click('[data-testid="qaf-open-comparison"]')
      await expect(page).toHaveURL(/\/qaf-differences\/[^/]+/)

      // REAL testid (qaf-multi-qaf-nav.tsx) — the Multi-QAF badge itself,
      // not aspirational.
      const badge = page.locator('[data-testid="qaf-multi-qaf-status-badge"]')
      await expect(badge).toBeVisible()
      await expect(badge).toContainText(/Multi-QAF/i)

      // Step 6 — Review automatic matches (the variant-match review panel —
      // 4 unchanged variants auto-match raw_exact, 1 removed, 0 added, per
      // the fixture generator's own spec).
      await page.click('[data-testid="qaf-multi-qaf-review-matches-tab"]')
      await expect(page.locator('[data-testid="qaf-multi-qaf-match-row"]')).toHaveCount(5) // 4 matched + 1 removed row.
      await expect(page.locator('[data-testid="qaf-multi-qaf-match-row-removed"]')).toHaveCount(1)

      // Step 7 — Run comparison (auto-runs on open in this app; this click
      // models an explicit "Neu berechnen" affordance if/when one exists).
      await page.click('[data-testid="qaf-multi-qaf-recompute"]')

      // Step 8 — Inspect container-level changes. REAL testid
      // (qaf-multi-qaf-hero.tsx) for the top-level hero summary.
      const hero = page.locator('[data-testid="qaf-multi-qaf-hero"]')
      await expect(hero).toBeVisible()
      await expect(hero).toContainText(/1/) // 1 variant removed, 0 added.

      // Step 9 — Inspect one variant (drill into one of the 4 matched
      // variants' own detail section).
      await page.click('[data-testid="qaf-multi-qaf-variant-row"]:first-child')
      await expect(page.locator('[data-testid="qaf-multi-qaf-variant-detail"]')).toBeVisible()

      // Step 10 — Inspect shared material change (the fixture's own
      // deliberate 3.4 -> 4.5 unit-cost change on the shared component).
      await page.click('[data-testid="qaf-multi-qaf-material-tab"]')
      const materialFinding = page.locator('[data-testid="qaf-multi-qaf-material-unit-cost-change"]')
      await expect(materialFinding).toBeVisible()
      await expect(materialFinding).toContainText(/3[.,]4/)
      await expect(materialFinding).toContainText(/4[.,]5/)

      // Step 11 — Inspect manufacturing-profile change (both fixtures bind
      // every variant to the SAME single shared profile — the panel must
      // show it as one profile, not duplicated per variant).
      await page.click('[data-testid="qaf-multi-qaf-profile-tab"]')
      await expect(page.locator('[data-testid="qaf-multi-qaf-profile-row"]')).toHaveCount(1)

      // Step 12 — Export the (single, bilingual-inline) Excel report —
      // finding (b) above: there is no separate "German report" export
      // action.
      const [firstDownload] = await Promise.all([
        page.waitForEvent('download'),
        page.click('[data-testid="qaf-multi-qaf-export-xlsx"]'),
      ])
      expect(firstDownload.suggestedFilename()).toMatch(/\.xlsx$/)

      // Step 13 — Switch interface to English (finding (b) above: the
      // GLOBAL i18n locale switcher, components/layout/user-menu.tsx — no
      // data-testid hooks exist on it today, hence the aspirational names
      // below; the underlying mechanism itself IS real and app-wide, not a
      // QAF-page-local toggle).
      await page.click('[data-testid="user-menu-toggle"]')
      await page.click('[data-testid="language-switcher-toggle"]')
      await page.click('[data-testid="locale-option-en"]')
      // The on-screen UI text changes (useTranslation()/t() re-renders);
      // the underlying data/comparison itself is untouched.
      await expect(page.locator('[data-testid="qaf-multi-qaf-status-badge"]')).toBeVisible()
      await expect(page.locator('body')).not.toContainText('Varianten hinzugefügt') // a DE-only label must disappear.

      // Step 14 — Export again post-switch — same single bilingual export
      // action; asserts the locale switch never breaks or DE/EN-narrows it.
      const [secondDownload] = await Promise.all([
        page.waitForEvent('download'),
        page.click('[data-testid="qaf-multi-qaf-export-xlsx"]'),
      ])
      expect(secondDownload.suggestedFilename()).toMatch(/\.xlsx$/)

      // Step 15 — Save and reopen: reload the page and confirm the
      // persisted comparison (variant matches, material/profile findings)
      // survives a hard reload — the critical assertion, same category as
      // GP-01's own "data must survive a reload".
      const comparisonUrl = page.url()
      await page.reload()
      await page.waitForLoadState('networkidle')
      await expect(page).toHaveURL(comparisonUrl)
      await expect(page.locator('[data-testid="qaf-multi-qaf-status-badge"]')).toBeVisible()
      await expect(page.locator('[data-testid="qaf-multi-qaf-match-row"]')).toHaveCount(5)
    },
  )
})
