import type { KernelFileTreeProjection } from "@/lib/kernel-file-tree";

export const FILE_TREE_SEARCH_MAX_RESULTS = 80;
export const FILE_TREE_SEARCH_EMPTY_STATE_TEXT = "没有匹配结果";

export type FileTreeProjectionSearchRequestMeta = {
  query: string | null;
  maxResults: number | null;
  maxResultsRule: "matches_only_before_ancestor_completion";
  ancestorCompletion: "include_all_ancestors_after_match_truncation";
  ordering: "kernel_file_tree_preorder";
  emptyStateText: typeof FILE_TREE_SEARCH_EMPTY_STATE_TEXT;
  asyncVisibility: {
    source: "kernel.project_view";
    requestKey: string | null;
  };
  coveredResourceKinds: ["index", "asset", "asset_folder", "mindmap", "book", "pdf"];
};

export type FetchKernelFileTreeProjectionInput = {
  workspaceId: string;
  rootNodeId?: string | null;
  depth?: number | null;
  query?: string | null;
  maxResults?: number | null;
};

function normalizeQuery(value: string | null | undefined): string | null {
  const query = value?.trim() ?? "";
  return query.length > 0 ? query : null;
}

function normalizeMaxResults(value: number | null | undefined): number | null {
  if (typeof value !== "number" || !Number.isFinite(value)) {
    return null;
  }
  return Math.min(FILE_TREE_SEARCH_MAX_RESULTS, Math.max(1, Math.floor(value)));
}

export function buildFileTreeProjectionSearchRequestMeta(
  input: Pick<FetchKernelFileTreeProjectionInput, "workspaceId" | "query" | "maxResults">,
): FileTreeProjectionSearchRequestMeta {
  const query = normalizeQuery(input.query);
  const maxResults = normalizeMaxResults(input.maxResults);
  return {
    query,
    maxResults,
    maxResultsRule: "matches_only_before_ancestor_completion",
    ancestorCompletion: "include_all_ancestors_after_match_truncation",
    ordering: "kernel_file_tree_preorder",
    emptyStateText: FILE_TREE_SEARCH_EMPTY_STATE_TEXT,
    asyncVisibility: {
      source: "kernel.project_view",
      requestKey: query ? `${input.workspaceId}:${query}` : null,
    },
    coveredResourceKinds: ["index", "asset", "asset_folder", "mindmap", "book", "pdf"],
  };
}

export async function fetchKernelFileTreeProjection(
  input: FetchKernelFileTreeProjectionInput,
): Promise<KernelFileTreeProjection> {
  const params = new URLSearchParams();
  params.set("workspaceId", input.workspaceId);
  const rootNodeId = input.rootNodeId?.trim();
  if (rootNodeId) {
    params.set("rootNodeId", rootNodeId);
  }
  if (typeof input.depth === "number" && Number.isFinite(input.depth)) {
    params.set("depth", String(input.depth));
  }
  const query = normalizeQuery(input.query);
  if (query) {
    params.set("query", query);
  }
  const maxResults = normalizeMaxResults(input.maxResults);
  if (maxResults != null) {
    params.set("maxResults", String(maxResults));
  }

  const response = await fetch(`/api/tree/projections/file?${params.toString()}`, {
    method: "GET",
    credentials: "include",
  });

  if (!response.ok) {
    const payload = await response.json().catch(() => ({}));
    const message =
      typeof payload?.error === "string" ? payload.error : "获取 file_tree projection 失败";
    throw new Error(message);
  }

  const payload = (await response.json()) as { result?: KernelFileTreeProjection };
  if (!payload.result) {
    throw new Error("file_tree projection 响应缺少 result");
  }
  return payload.result;
}
