import { queryFeaturesByIds } from "@/utils/mapQueryService";
import config from "@config/config";

export type PipeDiameterMap = Record<string, number | null | undefined>;

const diameterCache = new Map<string, PipeDiameterMap>();
const diameterRequestCache = new Map<string, Promise<PipeDiameterMap>>();

const normalizePipeIds = (pipeIds: string[]) =>
  [...new Set(pipeIds.map((pipeId) => String(pipeId).trim()).filter(Boolean))];

export const getPipeDiameterQueryKey = (pipeIds: string[]) =>
  [
    config.MAP_URL,
    config.MAP_WORKSPACE,
    ...normalizePipeIds(pipeIds).sort(),
  ].join("\u0000");

export const getCachedPipeDiameters = (pipeIds: string[]) =>
  diameterCache.get(getPipeDiameterQueryKey(pipeIds));

export const clearPipeDiameterCache = () => {
  diameterCache.clear();
  diameterRequestCache.clear();
};

export const loadPipeDiameters = async (
  pipeIds: string[],
): Promise<PipeDiameterMap> => {
  const normalizedPipeIds = normalizePipeIds(pipeIds);
  if (normalizedPipeIds.length === 0) {
    return {};
  }

  const queryKey = getPipeDiameterQueryKey(normalizedPipeIds);
  const cachedDiameters = diameterCache.get(queryKey);
  if (cachedDiameters) {
    return cachedDiameters;
  }

  const cachedRequest = diameterRequestCache.get(queryKey);
  if (cachedRequest) {
    return cachedRequest;
  }

  const request = (async () => {
    let features = await queryFeaturesByIds(
      normalizedPipeIds,
      "geo_pipes_mat",
    );
    const foundPipeIds = new Set(
      features.map((feature) => String(feature.getProperties().id)),
    );
    const missingPipeIds = normalizedPipeIds.filter(
      (pipeId) => !foundPipeIds.has(pipeId),
    );

    if (missingPipeIds.length > 0) {
      const fallbackFeatures = await queryFeaturesByIds(
        missingPipeIds,
        "geo_pipes",
      );
      features = [...features, ...fallbackFeatures];
    }

    const diameters: PipeDiameterMap = Object.fromEntries(
      normalizedPipeIds.map((pipeId) => [pipeId, null]),
    );
    features.forEach((feature) => {
      const properties = feature.getProperties();
      const pipeId = String(properties.id);
      const diameter = Number(properties.diameter);
      if (pipeId in diameters) {
        diameters[pipeId] = Number.isFinite(diameter) ? diameter : null;
      }
    });

    diameterCache.set(queryKey, diameters);
    return diameters;
  })();

  diameterRequestCache.set(queryKey, request);
  try {
    return await request;
  } finally {
    if (diameterRequestCache.get(queryKey) === request) {
      diameterRequestCache.delete(queryKey);
    }
  }
};

export const getPipeDiameterDisplay = (
  pipeIds: string[] | undefined,
  diameters: PipeDiameterMap | undefined,
  loading = false,
): string => {
  if (loading) {
    return "查询中...";
  }

  if (!pipeIds?.length) {
    return "N/A";
  }

  const values = pipeIds.map((pipeId) => {
    const diameter = diameters?.[pipeId];
    const displayValue =
      typeof diameter === "number" && Number.isFinite(diameter)
        ? `${diameter} mm`
        : "N/A";

    return pipeIds.length === 1 ? displayValue : `${pipeId}: ${displayValue}`;
  });

  return values.join("；");
};
