import { vueRouter } from "storybook-vue3-router";

import { makeDecorator } from "@storybook/addons";
import type { StoryContext, StoryFn } from "@storybook/types";

import {
  createRouter,
  createWebHashHistory,
  type NavigationGuard,
  type RouteLocationNormalizedLoaded,
  /* types */
  type Router,
  type RouterOptions,
} from "vue-router";

import { action } from "@storybook/addon-actions";
import type { RouteRecordRaw } from "vue-router";

type MockRouter = Router & { isMocked?: boolean };
type MockRoute = RouteLocationNormalizedLoaded & { isMocked?: boolean };

const Home = {
  template: `
    <div>
      <h2>Home</h2>

      <div style="display: flex; gap: 1em">
        <router-link to="/">Home</router-link>
        <router-link to="/about">About</router-link>
      </div>
    </div>
  `,
};

const About = {
  template: `
    <div>
      <h2>About</h2>
      <div style="display: flex; gap: 1em">
        <router-link to="/">Home</router-link>
        <router-link to="/about">About</router-link>
      </div>
    </div>
  `,
};

const defaultRoutes: RouteRecordRaw[] = [
  {
    path: "/",
    name: "home",
    component: Home,
    beforeEnter: (to, from) =>
      action("beforeEnter")({ to: to.fullPath, from: from.fullPath }),
  },
  {
    path: "/about",
    name: "about",
    component: About,
    beforeEnter: (to, from) =>
      action("beforeEnter")({ to: to.fullPath, from: from.fullPath }),
  },
];

export const withVueRouter = (
  app,
  /* optional: routes param - uses `defaultRoutes` if not provided */
  routes = defaultRoutes,
  /* optional: router options - used to pass `initialRoute` value, `beforeEach()` navigation guard methods and vue-router `createRouter` options */
  options?: {
    initialRoute?: string;
    beforeEach?: NavigationGuard;
    vueRouterOptions?: RouterOptions;
  }
) => {
  /* setup router var */
  let router;

  /* check if there is an existing router */
  const existingRouter = app.config.globalProperties.$router as MockRouter;
  const existingRoute = app.config.globalProperties.$route as MockRoute;
  if (
    (!existingRouter || existingRouter.isMocked === true) &&
    (!existingRoute || existingRoute.isMocked === true)
  ) {
    /* create vue router */
    router = createRouter({
      history: createWebHashHistory(),
      routes,
      ...options?.vueRouterOptions,
    });

    /* setup optional global router guards */
    // globalRouterGuardFn(router, options?.beforeEach)

    /* tell storybook to use vue router */
    app.use(router);
  } else {
    /* set router to value of existing router */
    //   router = existingRouter
    //   /* reset routes (remove old / add new) */
    //   resetRoutes(router, routes)
    //   /* setup optional global router guards (if provided and there is an existing router this will force a page reload) */
    //   globalRouterGuardFn(existingRouter, options?.beforeEach, true)
    // }
    // /* go to initial route */
    // initialRoute(router, options?.initialRoute)
  }
};
