import { getCountryUtcOffset } from "./countryTimezones";

export interface PlacePrediction {
  placeId: string;
  description: string;
}

export interface PlaceDetails {
  label: string;
  latitude: number;
  longitude: number;
  pincode: string;
  city?: string;
  state?: string;
  country?: string;
  timezone: number;
}

/*
|--------------------------------------------------------------------------
| Search (Google Places Autocomplete, proxied)
|--------------------------------------------------------------------------
*/

export async function searchPlaces(query: string): Promise<PlacePrediction[]> {
  if (!query.trim()) return [];

  try {
    const response = await fetch(`/api/places/autocomplete?input=${encodeURIComponent(query)}`);

    if (!response.ok) return [];

    const data = await response.json();

    return (data.predictions ?? []).map((p: any) => ({
      placeId: p.place_id,
      description: p.description,
    }));
  } catch {
    return [];
  }
}

/*
|--------------------------------------------------------------------------
| Details (Google Place Details, proxied) — resolves a picked
| prediction to coordinates + postal code + a per-country timezone
| approximation.
|--------------------------------------------------------------------------
*/

function findComponent(components: any[], type: string): any {
  return components.find((c) => c.types?.includes(type));
}

// Small/rural localities (villages, tehsils) frequently have no
// postal_code entry in their own Place Details address_components at
// all — confirmed live (e.g. "Bagwara, Rajasthan" resolves fine but
// carries no postal_code component). Reverse-geocoding the same
// lat/lng filtered to result_type=postal_code recovers it in most
// cases; a genuine ZERO_RESULTS from that call means there's really
// nothing to autofill, not a bug.
async function findPincodeByCoordinates(lat: number, lng: number): Promise<string> {
  try {
    const response = await fetch(`/api/places/geocode?lat=${lat}&lng=${lng}`);

    if (!response.ok) return "";

    const data = await response.json();

    const components = data.result?.address_components ?? [];

    return findComponent(components, "postal_code")?.long_name ?? "";
  } catch {
    return "";
  }
}

export async function getPlaceDetails(placeId: string): Promise<PlaceDetails | null> {
  try {
    const response = await fetch(`/api/places/details?place_id=${encodeURIComponent(placeId)}`);

    if (!response.ok) return null;

    const data = await response.json();

    const result = data.result;

    const location = result?.geometry?.location;

    if (!location) return null;

    const components = result.address_components ?? [];

    const countryComponent = findComponent(components, "country");

    let pincode = findComponent(components, "postal_code")?.long_name ?? "";

    if (!pincode) {
      pincode = await findPincodeByCoordinates(location.lat, location.lng);
    }

    return {
      label: result.formatted_address,
      latitude: location.lat,
      longitude: location.lng,
      pincode,
      city:
        findComponent(components, "locality")?.long_name ??
        findComponent(components, "administrative_area_level_2")?.long_name,
      state: findComponent(components, "administrative_area_level_1")?.long_name,
      country: countryComponent?.long_name,
      timezone: getCountryUtcOffset(countryComponent?.short_name),
    };
  } catch {
    return null;
  }
}
