/**
 * #23 — the panel-only entry. `parseViewWindowParams` validates the
 * `?panel=&project=` query, and `ViewWindow` resolves the project through the
 * gateway then renders only the requested view (here: the tickets view).
 */
import { describe, it, expect } from "vitest";
import { render, screen, waitFor } from "@testing-library/react";

import { DIProvider } from "@/app/di";
import {
  MockAgentGateway,
  MockProjectGateway,
  MockSystemGateway,
  MockTicketGateway,
} from "@/adapters/mock";
import type { Gateways } from "@/ports";
import { ViewWindow, parseViewWindowParams } from "./ViewWindow";

describe("parseViewWindowParams (#23)", () => {
  it("parses a valid panel + project", () => {
    expect(parseViewWindowParams("?panel=tickets&project=p-1")).toEqual({
      panel: "tickets",
      projectId: "p-1",
    });
  });

  it("rejects a missing project, missing panel, or the non-detachable projects panel", () => {
    expect(parseViewWindowParams("?panel=tickets")).toBeNull();
    expect(parseViewWindowParams("?project=p-1")).toBeNull();
    expect(parseViewWindowParams("?panel=projects&project=p-1")).toBeNull();
    expect(parseViewWindowParams("?panel=bogus&project=p-1")).toBeNull();
    expect(parseViewWindowParams("")).toBeNull();
  });
});

describe("ViewWindow (#23)", () => {
  it("resolves the project and renders only the requested view", async () => {
    const system = new MockSystemGateway();
    const project = new MockProjectGateway();
    const created = await project.createProject("alpha", "/p/a");
    const gateways = {
      system,
      project,
      agent: new MockAgentGateway(),
      ticket: new MockTicketGateway(system),
    } as unknown as Gateways;

    render(
      <DIProvider gateways={gateways}>
        <ViewWindow panel="tickets" projectId={created.id} />
      </DIProvider>,
    );

    // The window chrome shows the panel title and the resolved project name.
    expect(screen.getByRole("heading", { name: "Tickets" })).toBeTruthy();
    await waitFor(() => expect(screen.getByText("· alpha")).toBeTruthy());
    // The tickets view itself mounted (its search box is present).
    await waitFor(() =>
      expect(screen.getByLabelText("search tickets")).toBeTruthy(),
    );
  });
});
