import { afterEach, describe, expect, it, jest } from "@jest/globals";

describe("frontend entrypoint and router", () => {
  afterEach(() => {
    jest.resetModules();
    jest.restoreAllMocks();
  });

  it("registers the router, mounts the app, and starts auth", async () => {
    const use = jest.fn();
    const mount = jest.fn();
    const createApp = jest.fn(() => ({ use, mount }));
    const initAuth = jest.fn();
    const router = { name: "router" };
    const app = { name: "App" };

    jest.doMock("vue", () => ({ createApp }));
    jest.doMock("../../../frontend/src/App.vue", () => ({ __esModule: true, default: app }));
    jest.doMock("../../../frontend/src/router", () => ({ __esModule: true, default: router }));
    jest.doMock("../../../frontend/src/auth", () => ({ initAuth }));

    await import("../../../frontend/src/main.js");

    expect(createApp).toHaveBeenCalledWith(app);
    expect(use).toHaveBeenCalledWith(router);
    expect(mount).toHaveBeenCalledWith("#app");
    expect(initAuth).toHaveBeenCalledTimes(1);
  });

  it("declares the application routes and ai redirect", async () => {
    jest.dontMock("../../../frontend/src/router");
    for (const view of [
      "HomeView",
      "AboutView",
      "AiView",
      "AiPlanView",
      "MoneroView",
      "AppsView",
      "AccountView",
      "RequestAccessView",
      "OnboardingView",
    ]) {
      jest.doMock(`../../../frontend/src/views/${view}.vue`, () => ({ __esModule: true, default: { name: view } }));
    }
    const createWebHistory = jest.fn(() => ({ mode: "history" }));
    const createRouter = jest.fn((config) => ({ ...config, ready: true }));
    jest.doMock("vue-router", () => ({ createRouter, createWebHistory }), { virtual: true });

    const router = (await import("../../../frontend/src/router.js")).default;

    expect(createWebHistory).toHaveBeenCalledTimes(1);
    expect(createRouter).toHaveBeenCalledWith(expect.objectContaining({ history: { mode: "history" } }));
    expect(router.routes.map((route) => route.path)).toEqual([
      "/",
      "/about",
      "/dev",
      "/:focus(devops|developer|sdet)",
      "/:focus(devops|developer|sdet)/about",
      "/ai",
      "/ai/chat",
      "/ai/roadmap",
      "/monero",
      "/apps",
      "/account",
      "/request-access",
      "/onboarding",
    ]);
    expect(router.routes.find((route) => route.path === "/ai")).toMatchObject({ redirect: "/ai/chat" });
    expect(router.routes.find((route) => route.path === "/dev")).toMatchObject({ redirect: "/developer" });
    expect(router.routes.find((route) => route.name === "home-focus").component).toBeDefined();
    expect(router.routes.find((route) => route.name === "about-focus").component).toBeDefined();
    expect(router.routes.find((route) => route.name === "account").component).toBeDefined();
  });
});
