import { describe, it, expect, vi, beforeEach } from "vitest";
import { screen, waitFor } from "@testing-library/react";
import { matrixServiceMock, runtimeMock, resetWailsMocks } from "../test/mocks/wails";
import { renderWithMantine } from "../test/utils";

vi.mock("../../wailsjs/go/main/MatrixService", () => matrixServiceMock);
vi.mock("../../wailsjs/runtime/runtime", () => runtimeMock);

import App from "../App";

describe("App routing", () => {
  beforeEach(() => resetWailsMocks());

  it("renders LoginScreen when there is no last user id", async () => {
    matrixServiceMock.GetLastUserID.mockResolvedValueOnce("");

    renderWithMantine(<App />);

    expect(
      await screen.findByRole("button", { name: /sign in with matrix/i }),
    ).toBeInTheDocument();
  });

  it("renders LoginScreen when session is invalid (has_token false)", async () => {
    matrixServiceMock.GetLastUserID.mockResolvedValueOnce("@alice:server");
    matrixServiceMock.GetSession.mockResolvedValueOnce({
      user_id: "@alice:server",
      device_id: "D",
      homeserver_url: "https://h",
      has_token: false,
    } as any);

    renderWithMantine(<App />);

    expect(
      await screen.findByRole("button", { name: /sign in with matrix/i }),
    ).toBeInTheDocument();
  });

  it("renders HomeScreen when there is a valid session", async () => {
    matrixServiceMock.GetLastUserID.mockResolvedValueOnce("@alice:server");
    matrixServiceMock.GetSession.mockResolvedValueOnce({
      user_id: "@alice:server",
      device_id: "D",
      homeserver_url: "https://h",
      has_token: true,
    } as any);
    // Keep Start pending so HomeScreen mounts but doesn't trigger errors.
    matrixServiceMock.Start.mockImplementation(() => new Promise(() => {}));

    renderWithMantine(<App />);

    await waitFor(() => {
      expect(screen.getByText(/matrix_client_pc/i)).toBeInTheDocument();
      // Header is HomeScreen-specific.
      expect(screen.getByRole("button", { name: /logout/i })).toBeInTheDocument();
    });
  });
});
