// @vitest-environment jsdom
/**
 * Tests for PageLayout sticky behavior per TZ §4.1.13 Table 22:
 *
 * Desktop/tablet:
 * - Breadcrumbs: NOT sticky (position: relative on __header).
 * - Page title + section-switcher: NOT sticky (inside __header, relative).
 * - Filter (left column): sticky on desktop (≥1051px).
 *   On tablet (≤1050px, stacked layout) layout reverts to relative — matches Angular reference.
 * - Day-tabs / Week-tabs (stickyContent): sticky on desktop + tablet (≥641px).
 * - On mobile (≤640px): nothing sticky.
 *
 * NOTE: jsdom does not compute CSS layout, so assertions here are on DOM structure
 * (class names, data attributes) rather than computed styles.
 * Visual regression (actual sticky scroll behavior) must be verified separately in
 * a real browser environment.
 */
import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import { PageLayout } from "./PageLayout.js";

// Suppress SCSS imports
vi.mock("./PageLayout.scss", () => ({}));
vi.mock("./Breadcrumbs.scss", () => ({}));
vi.mock("./ScrollUpButton.scss", () => ({}));

// Mock sub-components
vi.mock("@/i18n/provider.js", () => ({
  useTranslation: () => ({ t: (k: string) => k }),
}));

vi.mock("./ScrollUpButton.js", () => ({
  ScrollUpButton: () => null,
}));

vi.mock("./Breadcrumbs.js", () => ({
  Breadcrumbs: ({ items }: { items: { label: string }[] }) => (
    <nav data-testid="breadcrumbs">{items.map(i => i.label).join(" / ")}</nav>
  ),
}));

describe("4.1.13-R-Sticky: PageLayout DOM structure per TZ Table 22", () => {
  it("header row is NOT sticky — __header has position:relative semantics (not sticky class)", () => {
    render(<PageLayout title={<h1>Title</h1>} />);
    const header = document.querySelector(".page-layout__header");
    expect(header).toBeTruthy();
    // The header must NOT carry a sticky class or inline sticky style
    expect(header?.classList.contains("sticky")).toBe(false);
    expect((header as HTMLElement | null)?.style?.position).not.toBe("sticky");
  });

  it("filter left column has the CSS class that carries sticky positioning on desktop", () => {
    // jsdom cannot evaluate @media queries, but we verify the class is applied
    // so the CSS rule (position: sticky at desktop) can activate in the browser.
    render(<PageLayout contentLeft={<div data-testid="filter">Filter</div>} />);
    const filter = screen.getByTestId("filter");
    const aside = filter.closest("aside");
    expect(aside).toBeTruthy();
    expect(aside?.classList.contains("page-layout__column-left")).toBe(true);
    // NOTE: Visual regression test required in a real browser to assert position:sticky
    // is active at viewport ≥1051px and deactivated at ≤1050px (matching Angular reference).
  });

  it("stickyContent is wrapped in __sticky-content which carries sticky positioning at ≥641px", () => {
    render(
      <PageLayout
        stickyContent={<div data-testid="day-tabs">Day Tabs</div>}
      />,
    );
    const dayTabs = screen.getByTestId("day-tabs");
    const stickyWrapper = dayTabs.closest(".page-layout__sticky-content");
    expect(stickyWrapper).toBeTruthy();
    // NOTE: The CSS applies position:sticky via @include screen.gt-mobile (≥641px).
    // Visual regression required in a real browser to confirm sticky is active on desktop/tablet.
  });

  it("scroll-overlay is rendered when stickyContent is provided", () => {
    render(
      <PageLayout stickyContent={<div>Tabs</div>} />,
    );
    const overlay = document.querySelector(".page-layout__scroll-overlay");
    expect(overlay).toBeTruthy();
    expect(overlay?.getAttribute("aria-hidden")).toBe("true");
  });

  it("scroll-overlay is NOT rendered when no stickyContent", () => {
    render(<PageLayout />);
    const overlay = document.querySelector(".page-layout__scroll-overlay");
    expect(overlay).toBeNull();
  });

  it("stickyContent is NOT rendered when not provided", () => {
    render(<PageLayout />);
    const stickyWrapper = document.querySelector(".page-layout__sticky-content");
    expect(stickyWrapper).toBeNull();
  });

  it("breadcrumbs are rendered inside __title (header, not sticky)", () => {
    render(
      <PageLayout
        breadcrumbs={[{ label: "Online Board", url: "/ru/onlineboard" }]}
        title={<h1>My Page</h1>}
      />,
    );
    const breadcrumbs = screen.getByTestId("breadcrumbs");
    // Must be inside the header, not in the sticky content area
    const headerRight = breadcrumbs.closest(".page-layout__header-right");
    expect(headerRight).toBeTruthy();
    const stickyWrapper = breadcrumbs.closest(".page-layout__sticky-content");
    expect(stickyWrapper).toBeNull();
  });

  it("title content is inside __header-right (not sticky)", () => {
    render(<PageLayout title={<h1 data-testid="page-title">Расписание</h1>} />);
    const title = screen.getByTestId("page-title");
    const headerRight = title.closest(".page-layout__header-right");
    expect(headerRight).toBeTruthy();
    // Confirm NOT inside stickyContent
    const stickyWrapper = title.closest(".page-layout__sticky-content");
    expect(stickyWrapper).toBeNull();
  });

  it("headerLeft content is inside __header-left (not sticky)", () => {
    render(
      <PageLayout headerLeft={<div data-testid="page-tabs">Tabs</div>} />,
    );
    const tabs = screen.getByTestId("page-tabs");
    const headerLeft = tabs.closest(".page-layout__header-left");
    expect(headerLeft).toBeTruthy();
    const stickyWrapper = tabs.closest(".page-layout__sticky-content");
    expect(stickyWrapper).toBeNull();
  });

  it("main content renders inside __column-right (scrollable content area)", () => {
    render(
      <PageLayout>
        <div data-testid="flight-list">Flights</div>
      </PageLayout>,
    );
    const flightList = screen.getByTestId("flight-list");
    const columnRight = flightList.closest(".page-layout__column-right");
    expect(columnRight).toBeTruthy();
    // Confirm it's in the content section, not the header
    const contentRow = flightList.closest(".page-layout__content");
    expect(contentRow).toBeTruthy();
  });
});
