// Reverse-geocode coordinates to a country via OpenStreetMap Nominatim.
// Results cached in localStorage keyed by rounded lat/lng (~1km precision)
// so we don't hammer Nominatim's 1 req/sec rate limit.

const CACHE_KEY = 'feeld_country_cache_v1';
const PRECISION = 2; // ~1km — country boundaries are coarse enough

export interface CountryLookup {
  country?: string;
  countryCode?: string; // ISO 3166-1 alpha-2, uppercase
  /** true if the lookup succeeded (cached or fresh); false if unresolved */
  resolved: boolean;
}

type CacheShape = Record<string, { country?: string; countryCode?: string; t: number }>;

function readCache(): CacheShape {
  try {
    const raw = localStorage.getItem(CACHE_KEY);
    if (!raw) return {};
    const parsed = JSON.parse(raw);
    return parsed && typeof parsed === 'object' ? parsed : {};
  } catch {
    return {};
  }
}

function writeCache(c: CacheShape) {
  try {
    localStorage.setItem(CACHE_KEY, JSON.stringify(c));
  } catch {
    // localStorage full or unavailable — ignore
  }
}

function cacheKey(lat: number, lng: number) {
  return `${lat.toFixed(PRECISION)},${lng.toFixed(PRECISION)}`;
}

// In-flight dedupe so parallel calls for the same coord share one HTTP request
const inflight = new Map<string, Promise<CountryLookup>>();

export async function reverseGeocode(lat: number, lng: number): Promise<CountryLookup> {
  if (!Number.isFinite(lat) || !Number.isFinite(lng)) {
    return { resolved: false };
  }
  const key = cacheKey(lat, lng);

  const cache = readCache();
  if (cache[key]) {
    return { country: cache[key].country, countryCode: cache[key].countryCode, resolved: true };
  }

  const existing = inflight.get(key);
  if (existing) return existing;

  const p = (async (): Promise<CountryLookup> => {
    try {
      const res = await fetch(
        `https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}&zoom=3&addressdetails=1`,
        { headers: { 'User-Agent': 'FeeldWebApp/1.0' } }
      );
      if (!res.ok) return { resolved: false };
      const data = await res.json();
      const addr = data?.address ?? {};
      const country: string | undefined = addr.country;
      const countryCode: string | undefined = addr.country_code
        ? String(addr.country_code).toUpperCase()
        : undefined;
      if (!country && !countryCode) return { resolved: false };

      const next = readCache();
      next[key] = { country, countryCode, t: Date.now() };
      writeCache(next);
      return { country, countryCode, resolved: true };
    } catch {
      return { resolved: false };
    } finally {
      inflight.delete(key);
    }
  })();

  inflight.set(key, p);
  return p;
}
