import { computed } from "vue";
import type { RouteLocationNormalizedLoaded, Router } from "vue-router";
import type { MdtodoTaskStatus } from "@/api";

export type MdtodoViewMode = "workspace" | "queue";
export type MdtodoMobileTab = "tasks" | "document" | "report";
export type MdtodoTaskStatusFilter = "all" | MdtodoTaskStatus;

function queryValue(route: RouteLocationNormalizedLoaded, key: string): string {
  const value = route.query[key];
  return typeof value === "string"
    ? value
    : Array.isArray(value)
      ? value[0] || ""
      : "";
}

function normalizeStatusFilter(value: string): MdtodoTaskStatusFilter {
  if (value === "in_progress") return value;
  if (value === "completed") return value;
  return value === "open" ? value : "all";
}

export function useMdtodoViewState(
  router: Router,
  route: RouteLocationNormalizedLoaded,
) {
  const view = computed<MdtodoViewMode>(() =>
    queryValue(route, "view") === "queue" ? "queue" : "workspace",
  );
  const tab = computed<MdtodoMobileTab>(() => {
    const value = queryValue(route, "tab");
    return value === "tasks" || value === "report" ? value : "document";
  });
  const search = computed(() => queryValue(route, "q"));
  const status = computed<MdtodoTaskStatusFilter>(() => normalizeStatusFilter(queryValue(route, "status")));

  async function update(
    next: {
      view?: MdtodoViewMode;
      tab?: MdtodoMobileTab;
      search?: string;
      status?: MdtodoTaskStatusFilter;
    },
    replace = false,
  ): Promise<void> {
    const query = { ...route.query };
    if (next.view !== undefined)
      next.view === "workspace" ? delete query.view : (query.view = next.view);
    if (next.tab !== undefined)
      next.tab === "document" ? delete query.tab : (query.tab = next.tab);
    if (next.search !== undefined)
      next.search.trim() ? (query.q = next.search.trim()) : delete query.q;
    if (next.status !== undefined)
      next.status === "all"
        ? delete query.status
        : (query.status = next.status);
    const navigation = {
      name: route.name || undefined,
      params: route.params,
      query,
    };
    const resolved = router.resolve(navigation);
    if (resolved.fullPath === route.fullPath) return;
    if (replace) await router.replace(navigation);
    else await router.push(navigation);
  }

  return { view, tab, search, status, update };
}
