import { createPinia, setActivePinia } from "pinia";
import { beforeEach, describe, expect, vi } from "vitest";

import { START_LOCATION } from "vue-router";
import { useUserStore } from "../../stores/user";
import { onboardingRedirect } from "../onboarding";

describe("Onboarding", () => {
  afterEach(() => {
    vi.restoreAllMocks();
  });

  beforeEach(() => {
    setActivePinia(createPinia());
  });

  it("redirect guest", () => {
    const user = useUserStore();
    user.loggedIn = false;
    const mock = vi.fn();
    onboardingRedirect(routeLocation("accountConfirm", "uk"), START_LOCATION, mock);
    expect(mock).toHaveBeenCalledWith({
      name: "accountCreate",
      params: { courseType: "uk" },
    });
  });

  it("redirect logged-in user from accountCreate to accountConfirm", () => {
    const user = useUserStore();
    user.loggedIn = true;
    const mockNext = vi.fn();
    onboardingRedirect(routeLocation("accountCreate", "uk"), START_LOCATION, mockNext);
    expect(mockNext).toHaveBeenCalledWith({
      name: "accountConfirm",
      params: { courseType: "uk" },
    });
  });

  it("UK: redirect to profile next route for logged-in user with organisation", () => {
    const user = useUserStore();
    user.loggedIn = true;
    user.organisation = 1;
    const mockNext = vi.fn();
    onboardingRedirect(routeLocation("accountProfile", "uk"), START_LOCATION, mockNext);
    expect(mockNext).toHaveBeenCalledWith({
      name: "setupComplete",
      params: { courseType: "uk" },
    });
  });

  it("VV: redirect to profile next route for logged-in user with organisation", () => {
    const testCases = ["vv-de", "vv-it", "vv-fr"];
    testCases.forEach((testCase) => {
      const user = useUserStore();
      user.loggedIn = true;
      user.organisation = 1;
      const mockNext = vi.fn();
      onboardingRedirect(
        routeLocation("accountProfile", testCase),
        START_LOCATION,
        mockNext
      );
      expect(mockNext).toHaveBeenCalledWith({
        name: "checkoutAddress",
        params: { courseType: testCase },
      });
    });
  });

  it("no redirect for logged-in user without organisation to accountConfirm", () => {
    const user = useUserStore();
    user.loggedIn = true;
    user.organisation = null;
    const mockNext = vi.fn();
    onboardingRedirect(routeLocation("accountConfirm", "uk"), START_LOCATION, mockNext);
    expect(mockNext).toHaveBeenCalledWith(); // No arguments passed means no redirection
  });

  it("no redirect for logged-in user to a non-relevant route", () => {
    const user = useUserStore();
    user.loggedIn = true;
    const mockNext = vi.fn();
    onboardingRedirect(routeLocation("someOtherRoute", "uk"), START_LOCATION, mockNext);
    expect(mockNext).toHaveBeenCalledWith(); // No arguments passed means no redirection
  });

  it("no redirect for guest on accountCreate page", () => {
    const user = useUserStore();
    user.loggedIn = false;
    const mockNext = vi.fn();
    onboardingRedirect(routeLocation("accountCreate", "uk"), START_LOCATION, mockNext);
    expect(mockNext).toHaveBeenCalledWith(); // No arguments passed means no redirection
  });
});

function routeLocation(name: string, courseType: string) {
  return {
    fullPath: "",
    hash: "",
    matched: [],
    meta: {},
    name: name,
    params: {
      courseType,
    },
    path: "",
    query: {},
    redirectedFrom: undefined,
  };
}
