import { ArticleModel } from "./models";

export type View =
  | "home"
  | "auth"
  | "article"
  | "editor"
  | "profile"
  | "create";

export type ViewNode = {
  parent: View | null;
  children?: View[];
};

export const VIEW_TREE: Record<View, ViewNode> = {
  home: {
    parent: null,
    children: ["auth", "article", "profile", "create"],
  },

  auth: {
    parent: "home",
  },

  article: {
    parent: "home",
    children: ["editor"],
  },

  editor: {
    parent: "article",
  },

  profile: {
    parent: "home",
  },

  create: {
    parent: "home",
  },
};

export const VIEW_URL: Record<View, (ui?: any) => string> = {
  home: () => "/",

  auth: () => "/auth",

  profile: () => "/profile",

  create: () => "/create",

  article: (ui) => `/articles/${ui.selectedArticle._id ?? ""}`,

  editor: (ui) => `/articles/${ui.selectedArticle._id ?? ""}/edit`,
};

export function useViewRouter(setUI: any) {
  const navigate = (
    view: View,
    nextState?: any
  ) => {
    setUI((prev: any) => {
      const newState = { ...prev, ...nextState, view };

      // update URL
      const url = VIEW_URL[view](newState);
      window.history.pushState(newState, "", url);

      return newState;
    });

    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  // auto back logic from parent
  const goBack = (view: View) => {
    const parent = VIEW_TREE[view].parent;
    if (parent) navigate(parent);
  };

  const openArticle = (article: ArticleModel) => {
    setUI((prev: any) => {
      const newState = {
        ...prev,
        selectedArticle: article,
        view: "article",
      };

      const url = `/articles/${article._id}`;
      window.history.pushState(newState, "", url);

      return newState;
    });
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  // auto child navigators from children[]
  const navigateToChildren = (
    view: View,
    navigationMap?: Record<string, string>,
  ) => {
    const node = VIEW_TREE[view];
    const funcs: Record<string, () => void> = {};

    node.children?.forEach((child) => {
      const funcName = `open_${child}`;
      const customFuncName = navigationMap?.[funcName];
      funcs[funcName] = () => navigate(child);
      if (customFuncName) funcs[customFuncName] = () => navigate(child);
    });

    return funcs;
  };

  return { navigate, goBack, openArticle, navigateToChildren };
}
