// SPEC: PJ2026-01040409 MDTODO前端重写; draft-2026-06-26-p0-mdtodo-web-rewrite.
// Responsibility: URL is the authority for source/file/task/report selection; RESTful deep-link restore.

import { ref } from "vue";
import type { Router, RouteLocationNormalized } from "vue-router";

export type RouteName = "ProjectMdtodo" | "ProjectMdtodoFile" | "ProjectMdtodoTask" | "ProjectMdtodoReport";

export interface MdtodoRouteSelection {
  sourceId: string | null;
  fileRef: string | null;
  taskId: string | null;
  linkId: string | null;
}

export interface UseMdtodoRouteSelectionOptions {
  router: Router;
  route: RouteLocationNormalized;
}

/**
 * URL is the authority for selection state. Components may cache fold widths and
 * edit drafts locally, but source/file/task/report business selection must be
 * restorable from the URL after refresh, back/forward or web-probe deep links.
 */
export function useMdtodoRouteSelection({ router, route }: UseMdtodoRouteSelectionOptions) {
  const applyingRouteSelection = ref(false);

  function routeParam(key: string): string | null {
    const value = (route.params as Record<string, unknown>)[key];
    const text = Array.isArray(value) ? value[0] : value;
    return typeof text === "string" && text.trim() ? text.trim() : null;
  }

  function readSelection(): MdtodoRouteSelection {
    return {
      sourceId: routeParam("sourceId"),
      fileRef: routeParam("fileRef"),
      taskId: routeParam("taskId"),
      linkId: routeParam("linkId")
    };
  }

  function routeSelectionOptions(updateRoute: boolean): { fileRef?: string | null; taskId?: string | null; reportLinkId?: string | null; updateRoute: boolean } {
    return {
      fileRef: routeParam("fileRef"),
      taskId: routeParam("taskId"),
      reportLinkId: routeParam("linkId"),
      updateRoute
    };
  }

  async function syncSelectionRoute(options: {
    sourceId: string | null;
    fileRef: string | null;
    taskId?: string | null;
    reportLinkId?: string | null;
    replace?: boolean;
  }): Promise<void> {
    const { sourceId, fileRef, taskId, reportLinkId, replace } = options;
    if (!sourceId || !fileRef) return;
    const name: RouteName = reportLinkId && taskId ? "ProjectMdtodoReport" : taskId ? "ProjectMdtodoTask" : "ProjectMdtodoFile";
    const params: Record<string, string> = { sourceId, fileRef };
    if (taskId) params.taskId = taskId;
    if (reportLinkId) params.linkId = reportLinkId;
    const navigation = { name, params, query: route.query };
    const resolved = router.resolve(navigation);
    if (resolved.fullPath === route.fullPath) return;
    if (replace) await router.replace(navigation);
    else await router.push(navigation);
  }

  return {
    applyingRouteSelection,
    readSelection,
    routeSelectionOptions,
    syncSelectionRoute
  };
}
