import { afterEach, vi } from "vitest"
import { enableAutoUnmount } from "@vue/test-utils"

enableAutoUnmount(afterEach)

// Silence reka-ui's Dialog/Sheet a11y nags in test output. These warnings
// (`Warning: Missing \`Description\` or \`aria-describedby="undefined"\``
// and the matching `requires a \`Title\``) are real guidance for consumers
// and still fire in dev/prod — but minimal test mounts deliberately skip
// the description/title and the warnings drown the failure output. Keeps
// the signal-to-noise ratio high in CI logs.
const REKA_A11Y_NOISE = [
  /^Warning: Missing `Description` or `aria-describedby="undefined"` for /,
  /^Warning: `[^`]+` requires a `[^`]+` for the component to be accessible/,
]
const originalWarn = console.warn.bind(console)
console.warn = (...args: unknown[]): void => {
  const first = args[0]
  if (typeof first === "string" && REKA_A11Y_NOISE.some((p) => p.test(first))) {
    return
  }
  originalWarn(...args)
}

if (typeof window !== "undefined") {
  if (!window.matchMedia) {
    window.matchMedia = vi.fn().mockImplementation((query: string) => ({
      matches: false,
      media: query,
      onchange: null,
      addListener: vi.fn(),
      removeListener: vi.fn(),
      addEventListener: vi.fn(),
      removeEventListener: vi.fn(),
      dispatchEvent: vi.fn(),
    }))
  }

  if (!window.ResizeObserver) {
    window.ResizeObserver = class {
      observe(): void {}
      unobserve(): void {}
      disconnect(): void {}
    }
  }

  if (!window.IntersectionObserver) {
    // @ts-expect-error - jsdom shim, we only need these methods.
    window.IntersectionObserver = class {
      observe(): void {}
      unobserve(): void {}
      disconnect(): void {}
      takeRecords(): IntersectionObserverEntry[] {
        return []
      }
    }
  }

  // jsdom does not implement Element.scrollIntoView, which reka-ui's
  // Listbox/Combobox calls when highlighting items via keyboard nav.
  if (typeof Element !== "undefined" && !Element.prototype.scrollIntoView) {
    Element.prototype.scrollIntoView = function (): void {}
  }

  // jsdom does not implement the PointerEvent capture APIs that our
  // builder drag/resize handlers rely on. Stub them with no-ops so
  // tests can dispatch pointer events without crashing.
  if (
    typeof Element !== "undefined" &&
    !Element.prototype.setPointerCapture
  ) {
    Element.prototype.setPointerCapture = function (): void {}
    Element.prototype.releasePointerCapture = function (): void {}
    Element.prototype.hasPointerCapture = function (): boolean {
      return false
    }
  }

  // jsdom (as of v25) doesn't expose a PointerEvent constructor; fall
  // back to MouseEvent so tests can `new PointerEvent("pointermove", …)`.
  if (typeof window !== "undefined" && !window.PointerEvent) {
    // @ts-expect-error - intentional fallback so test code can construct one.
    window.PointerEvent = window.MouseEvent
  }

}
