import { getRelevantHeaders } from './get-relevant-headers'
import type {
  AllExternalSources,
  GeoJSONSource,
  Source,
} from '../../providers/sources/types'

/**
 * Builds the base React Query key for a single source.
 *
 * Used by both the reactive `useQueryKey` hook and the imperative
 * `getModelQueryOptions` factory so the key produced in both paths is
 * byte-for-byte identical — guaranteeing a value cached imperatively (e.g.
 * via `queryClient.prefetchQuery(getCategories(...))`) is later read by
 * the corresponding hook.
 */
export function buildQueryKey(
  queryKeyPrefix: string[],
  sourceId: string,
  source: Source | undefined,
): unknown[] {
  const key: unknown[] = [sourceId, ...queryKeyPrefix]

  const sourceData = getDataFingerprint(source)
  if (sourceData) {
    key.push(sourceData)
  }

  if (source && 'queryParameters' in source && source.queryParameters) {
    key.push(JSON.stringify(source.queryParameters))
  }

  const headers = (source as Source<AllExternalSources>)?.headers
  const relevantHeaders = getRelevantHeaders(headers)
  if (relevantHeaders) {
    key.push(JSON.stringify(relevantHeaders))
  }

  return key
}

function getDataFingerprint(source: Source | undefined) {
  if (!source || !('data' in source) || !source.data) {
    return undefined
  }

  if (source.type === 'geojson') {
    const geoJsonSource = source as Source<GeoJSONSource>
    if (Array.isArray(geoJsonSource.data)) {
      const data = geoJsonSource.data
      const fingerprint = {
        type: 'geojson',
        length: data.length,
        first: data.at(0),
        last: data.at(-1),
      }
      return JSON.stringify(fingerprint)
    }
  }

  return source.data
}
