export interface ParsedAddress {
  city: string;
  street: string;
  house: string;
  fullAddress: string;
}

const NOMINATIM_HEADERS = {
  'User-Agent': 'LendryID/1.0 (contact@lendry.ru)',
  Accept: 'application/json'
};

export async function reverseGeocode(lat: number, lng: number): Promise<ParsedAddress | null> {
  try {
    const url = `https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${encodeURIComponent(String(lat))}&lon=${encodeURIComponent(String(lng))}&accept-language=ru`;
    const response = await fetch(url, { headers: NOMINATIM_HEADERS });
    if (!response.ok) return null;
    const data = (await response.json()) as {
      display_name?: string;
      address?: Record<string, string | undefined>;
    };
    const addr = data.address ?? {};
    const city = addr.city || addr.town || addr.village || addr.municipality || addr.state || '';
    const street = addr.road || addr.pedestrian || addr.footway || addr.neighbourhood || '';
    const house = addr.house_number || '';
    return {
      city,
      street,
      house,
      fullAddress: data.display_name ?? formatParsed(city, street, house)
    };
  } catch {
    return null;
  }
}

export async function forwardGeocode(query: string): Promise<{ lat: number; lng: number; parsed: ParsedAddress } | null> {
  const trimmed = query.trim();
  if (!trimmed) return null;
  try {
    const url = `https://nominatim.openstreetmap.org/search?format=jsonv2&q=${encodeURIComponent(trimmed)}&limit=1&accept-language=ru`;
    const response = await fetch(url, { headers: NOMINATIM_HEADERS });
    if (!response.ok) return null;
    const data = (await response.json()) as Array<{
      lat: string;
      lon: string;
      display_name?: string;
      address?: Record<string, string | undefined>;
    }>;
    const first = data[0];
    if (!first) return null;
    const addr = first.address ?? {};
    const city = addr.city || addr.town || addr.village || addr.municipality || '';
    const street = addr.road || addr.pedestrian || '';
    const house = addr.house_number || '';
    return {
      lat: Number(first.lat),
      lng: Number(first.lon),
      parsed: {
        city,
        street,
        house,
        fullAddress: first.display_name ?? formatParsed(city, street, house)
      }
    };
  } catch {
    return null;
  }
}

function formatParsed(city: string, street: string, house: string) {
  const parts = [];
  if (city) parts.push(`г. ${city}`);
  if (street || house) parts.push([street, house].filter(Boolean).join(', '));
  return parts.join(', ');
}
