import path from "path"

import { expect, test } from "@playwright/test"

import type { Page } from "@playwright/test"

const SCREENSHOT_DIR = path.join(__dirname, "screenshots")

// Helper to capture console errors
function collectConsoleErrors(page: Page): string[] {
  const errors: string[] = []
  page.on("console", (msg) => {
    if (msg.type() === "error") {
      errors.push(`[console.error] ${msg.text()}`)
    }
  })
  page.on("pageerror", (err) => {
    errors.push(`[pageerror] ${err.message}`)
  })
  return errors
}

test.describe("CannaManage E2E Funktionscheck — Phases 1-3", () => {
  test.setTimeout(30_000)

  test("01 - Login page loads correctly", async ({ page }) => {
    const errors = collectConsoleErrors(page)

    const response = await page.goto("/login", {
      waitUntil: "domcontentloaded",
    })
    expect(response?.status()).toBe(200)

    // Wait for hydration
    await page.waitForTimeout(3000)

    // Verify login form elements are visible
    const emailField = page.locator('input[id="email"]')
    const passwordField = page.locator('input[id="password"]')
    const submitButton = page.locator('button[type="submit"]')

    await expect(emailField).toBeVisible({ timeout: 10000 })
    await expect(passwordField).toBeVisible({ timeout: 5000 })
    await expect(submitButton).toBeVisible({ timeout: 5000 })

    // Verify branding
    await expect(page.locator("text=CannaManage")).toBeVisible({
      timeout: 5000,
    })

    // Take screenshot
    await page.screenshot({
      path: path.join(SCREENSHOT_DIR, "01-login-page.png"),
      fullPage: true,
    })

    // Report console errors (filter expected auth errors without backend)
    const unexpectedErrors = errors.filter(
      (e) =>
        !e.includes("next-auth") &&
        !e.includes("ECONNREFUSED") &&
        !e.includes("fetch") &&
        !e.includes("Failed to fetch") &&
        !e.includes("NetworkError") &&
        !e.includes("ERR_CONNECTION_REFUSED") &&
        !e.includes("[auth]")
    )
    expect(
      unexpectedErrors,
      `Unexpected console errors on login page: ${unexpectedErrors.join(", ")}`
    ).toHaveLength(0)
  })

  test("02 - Auth redirect for protected routes", async ({ page }) => {
    collectConsoleErrors(page)

    await page.goto("/dashboard", { waitUntil: "domcontentloaded" })

    // Wait for redirect to happen
    await page.waitForTimeout(3000)
    await page.waitForURL(/\/login/, { timeout: 10000 })

    // Should redirect to /login with callbackUrl
    expect(page.url()).toContain("/login")

    // Take screenshot
    await page.screenshot({
      path: path.join(SCREENSHOT_DIR, "02-auth-redirect.png"),
      fullPage: true,
    })
  })

  test("03 - Login with invalid credentials shows error", async ({ page }) => {
    collectConsoleErrors(page)

    await page.goto("/login", { waitUntil: "domcontentloaded" })
    await page.waitForTimeout(2000)

    // Fill in invalid credentials
    await page.fill('input[id="email"]', "test@invalid.com")
    await page.fill('input[id="password"]', "wrongpass")

    // Click submit
    await page.click('button[type="submit"]')

    // Wait for the response — backend isn't running so we expect network error feedback
    await page.waitForTimeout(5000)

    // Take screenshot regardless of what happened
    await page.screenshot({
      path: path.join(SCREENSHOT_DIR, "03-login-error.png"),
      fullPage: true,
    })

    // Check for any error indication on page
    const errorVisible = await page
      .locator('[class*="destructive"], [class*="error"], [class*="amber"]')
      .first()
      .isVisible()
      .catch(() => false)

    console.log(`Login error feedback visible: ${errorVisible}`)
    // We expect SOME error feedback (either "invalid credentials" or "network error")
    // Not hard-failing if missing — just documenting
  })

  test("04 - 404 page renders for unknown routes", async ({ page }) => {
    collectConsoleErrors(page)

    const response = await page.goto("/this-does-not-exist", {
      waitUntil: "domcontentloaded",
    })
    await page.waitForTimeout(3000)

    // Take screenshot of whatever page we land on
    await page.screenshot({
      path: path.join(SCREENSHOT_DIR, "04-not-found.png"),
      fullPage: true,
    })

    // Document the actual URL we ended up at
    const url = page.url()
    console.log(`404 test: ended up at ${url}`)
    console.log(`404 test: response status ${response?.status()}`)

    // The page should either show a 404 content or redirect to login (middleware)
    const isExpectedBehavior =
      url.includes("/login") ||
      url.includes("not-found") ||
      url.includes("this-does-not-exist")
    expect(isExpectedBehavior).toBeTruthy()
  })

  test("05 - No critical JavaScript errors on accessible pages", async ({
    page,
  }) => {
    const errors = collectConsoleErrors(page)

    await page.goto("/login", { waitUntil: "domcontentloaded" })
    await page.waitForTimeout(3000)

    // Filter out expected errors (next-auth session check without backend)
    const criticalErrors = errors.filter(
      (e) =>
        !e.includes("next-auth") &&
        !e.includes("NEXT_REDIRECT") &&
        !e.includes("fetch") &&
        !e.includes("Failed to fetch") &&
        !e.includes("NetworkError") &&
        !e.includes("ECONNREFUSED") &&
        !e.includes("ERR_CONNECTION_REFUSED") &&
        !e.includes("[auth]") &&
        !e.includes("session") &&
        !e.includes("hydrat")
    )

    console.log(`Total console errors: ${errors.length}`)
    console.log(`Critical (non-network) errors: ${criticalErrors.length}`)
    for (const err of errors) {
      console.log(`  ${err}`)
    }

    // Only fail on truly critical errors
    expect(
      criticalErrors,
      `Critical JS errors: ${criticalErrors.join("\n")}`
    ).toHaveLength(0)
  })

  test("06 - Login page visual structure check", async ({ page }) => {
    await page.goto("/login", { waitUntil: "domcontentloaded" })
    await page.waitForTimeout(3000)

    // Check page structure elements
    const heading = page.locator("h1")
    const form = page.locator("form")
    const emailInput = page.locator('input[type="email"]')
    const passwordInput = page.locator('input[type="password"]')

    await expect(heading).toContainText("CannaManage", { timeout: 5000 })
    await expect(form).toBeVisible({ timeout: 5000 })
    await expect(emailInput).toBeVisible({ timeout: 5000 })
    await expect(passwordInput).toBeVisible({ timeout: 5000 })

    // Check placeholder text
    await expect(emailInput).toHaveAttribute("placeholder", "name@verein.de")

    // Viewport check — ensure nothing overflows
    const bodyWidth = await page.evaluate(() => document.body.scrollWidth)
    const viewportWidth = await page.evaluate(() => window.innerWidth)
    expect(bodyWidth).toBeLessThanOrEqual(viewportWidth + 1)

    console.log("Login page visual structure: OK")
  })
})
