/**
 * Reverse-geocode helpers — match a Nominatim result against the data.gov.il
 * cities list cached in R2 by the existing /api/address/cities proxy.
 *
 * Returns the canonical { city, cityCode } if a confident match is found, or
 * { city: null, cityCode: null } if no match (out-of-Israel, foreign locality,
 * etc.). Never throws — callers report a generic "couldn't detect" to the UI.
 */

export interface CitiesEntry {
  /** סמל ישוב code (string of digits). */
  סמל_ישוב: string;
  /** Canonical Hebrew name, possibly with hyphen, e.g. "תל אביב-יפו". */
  שם_ישוב: string;
}

export interface CitiesPayload {
  result?: { records?: CitiesEntry[] };
}

export interface CityMatch {
  city: string | null;
  cityCode: string | null;
}

/** Normalize Hebrew city names for fuzzy compare. */
export function normalizeCityName(name: string): string {
  return name
    .replace(/[\s‎‏]+/g, ' ') // collapse whitespace + bidi marks
    .replace(/[-־–—]/g, ' ') // various dashes → space (regular hyphen, maqaf, en/em-dash)
    .replace(/['"'׳״]/g, '') // strip apostrophes (geresh, gershayim)
    .trim()
    .toLowerCase();
}

/**
 * Look up canonical city + cityCode for a Nominatim-returned name.
 * Returns nulls if no entry normalizes to the same string.
 */
export function matchCity(rawName: string | null | undefined, cities: CitiesEntry[]): CityMatch {
  if (!rawName) return { city: null, cityCode: null };
  const target = normalizeCityName(rawName);
  if (!target) return { city: null, cityCode: null };
  for (const entry of cities) {
    if (normalizeCityName(entry.שם_ישוב) === target) {
      return { city: entry.שם_ישוב.trim(), cityCode: entry.סמל_ישוב };
    }
  }
  return { city: null, cityCode: null };
}

/** Pick the best "locality" field from a Nominatim address payload. */
export function pickLocality(addr: Record<string, unknown> | undefined): string | null {
  if (!addr) return null;
  for (const k of ['city', 'town', 'village', 'municipality', 'hamlet']) {
    const v = addr[k];
    if (typeof v === 'string' && v.length > 0) return v;
  }
  return null;
}
