import { afterEach, expect, test, vi } from "vitest";
import { screen, within } from "@testing-library/react";
import { Route, Routes } from "react-router-dom";

import { renderApp } from "../test/render";
import { VocabulariesPage } from "./vocabularies-page";
import { VocabularyTerms } from "./vocabulary-terms";
import { SelectVocabularyPrompt } from "./select-vocabulary-prompt";

function setViewport(wide: boolean) {
  Object.defineProperty(window, "matchMedia", {
    value: (query: string): MediaQueryList =>
      ({
        matches: wide && query === "(min-width: 1024px)",
        media: query,
        onchange: null,
        addEventListener: () => {},
        removeEventListener: () => {},
        addListener: () => {},
        removeListener: () => {},
        dispatchEvent: () => false,
      }) as MediaQueryList,
    writable: true,
  });
}

afterEach(() => vi.restoreAllMocks());

function tree() {
  return (
    <Routes>
      <Route path="/vocabularies" element={<VocabulariesPage />}>
        <Route index element={<SelectVocabularyPrompt />} />
        <Route path=":id" element={<VocabularyTerms />} />
      </Route>
    </Routes>
  );
}

test("narrow: a selected vocabulary's detail renders in a portaled drawer", async () => {
  setViewport(false);
  renderApp(tree(), { route: "/vocabularies/v-material" });

  const body = within(document.body);
  expect(
    await body.findByRole("button", { name: /close detail/i }, { timeout: 5000 }),
  ).toBeInTheDocument();
});

test("wide: a selected vocabulary renders inline, with no detail drawer", async () => {
  setViewport(true);
  renderApp(tree(), { route: "/vocabularies/v-material" });

  // VocabularyTerms renders its "Terms" caption inline in the right pane.
  await screen.findByText(/terms/i);
  expect(screen.queryByRole("button", { name: /close detail/i })).toBeNull();
});
