import { cleanup } from '@testing-library/react'
import '@testing-library/jest-dom/vitest'
import { afterEach } from 'vitest'

afterEach(cleanup)

// jsdom (<25) ships no HTMLDialogElement methods; the lab Drawer opens a
// native <dialog> via show()/showModal(). Minimal polyfill so component
// tests exercise the open/close lifecycle.
const dialogProto = globalThis.HTMLDialogElement?.prototype as
  | ({ show?: unknown; showModal?: unknown; close?: unknown } & object)
  | undefined
if (dialogProto && typeof dialogProto.showModal !== 'function') {
  dialogProto.show = function show(this: HTMLDialogElement) {
    this.setAttribute('open', '')
  }
  dialogProto.showModal = function showModal(this: HTMLDialogElement) {
    this.setAttribute('open', '')
  }
  dialogProto.close = function close(this: HTMLDialogElement) {
    this.removeAttribute('open')
  }
}

// jsdom (this version) ships no matchMedia; astryx hooks (useMediaQuery →
// theme/Toast) subscribe to it.
if (typeof window.matchMedia !== 'function') {
  window.matchMedia = (query: string) => {
    const listeners = new Set<(event: MediaQueryListEvent) => void>()
    return {
      matches: false,
      media: query,
      onchange: null,
      addEventListener(_type: 'change', listener: (event: MediaQueryListEvent) => void) {
        listeners.add(listener)
      },
      removeEventListener(_type: 'change', listener: (event: MediaQueryListEvent) => void) {
        listeners.delete(listener)
      },
      addListener: () => {},
      removeListener: () => {},
      dispatchEvent() {
        return false
      },
    } as unknown as MediaQueryList
  }
}

// astryx popovers (toast viewport, menus) ride the Popover API. jsdom lacks
// it, so the astryx viewport's popover=manual element never leaves the a11y
// "hiding state": unless we mark it open, role queries find nothing inside.
const elementProto = globalThis.HTMLElement?.prototype as
  | ({ showPopover?: unknown; hidePopover?: unknown } & object)
  | undefined
if (elementProto && typeof elementProto.showPopover !== 'function') {
  elementProto.showPopover = function showPopover(this: HTMLElement) {
    this.setAttribute('popover-open', '')
  }
  elementProto.hidePopover = function hidePopover(this: HTMLElement) {
    this.removeAttribute('popover-open')
  }
}

// jsdom's UA stylesheet hides `[popover]:not(:popover-open)`, but jsdom does
// not implement the :popover-open pseudo-class, so even open popovers compute
// display:none. An author-origin override loses to the UA sheet; only
// !important wins. Closed popovers stay display:none (UA), open ones block.
const popoverStyle = document.createElement('style')
popoverStyle.textContent = '[popover][popover-open]{display:block !important}'
document.head.appendChild(popoverStyle)
