declare module '@joshtwc/react-places-autocomplete' {
  import * as React from 'react';

  // Suggestion interface
  export interface Suggestion {
    id: string;
    description: string;
    placeId: string;
    active: boolean;
    index: number;
    formattedSuggestion: {
      mainText: string;
      secondaryText: string;
    };
    matchedSubstrings?: google.maps.places.PredictionSubstring[];
    terms?: google.maps.places.PredictionTerm[];
    types?: string[];
  }

  // Search options interface
  export interface SearchOptions {
    bounds?: google.maps.LatLngBounds | google.maps.LatLngBoundsLiteral;
    location?: google.maps.LatLng | google.maps.LatLngLiteral;
    offset?: number | string;
    radius?: number | string;
    types?: string[];
    region?: string;
    includedRegionCodes?: string[];
    fields?: string[];
    inputOffset?: string[];
    language?: string;
    locationBias?: google.maps.LatLng | google.maps.LatLngLiteral;
  }

  // Render props interface
  export interface RenderProps {
    getInputProps: <T = {}>(options?: T) => T & {
      type: string;
      autoComplete: string;
      role: string;
      'aria-autocomplete': string;
      'aria-expanded': boolean;
      'aria-activedescendant'?: string;
      disabled: boolean;
      onKeyDown: (event: React.KeyboardEvent) => void;
      onBlur: (event: React.FocusEvent) => void;
      value: string;
      onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
    };
    getSuggestionItemProps: <T = {}>(
      suggestion: Suggestion,
      options?: T
    ) => T & {
      key: string;
      id?: string;
      role: string;
      onMouseEnter: (event: React.MouseEvent) => void;
      onMouseLeave: (event: React.MouseEvent) => void;
      onMouseDown: (event: React.MouseEvent) => void;
      onMouseUp: (event: React.MouseEvent) => void;
      onTouchStart: (event: React.TouchEvent) => void;
      onTouchEnd: (event: React.TouchEvent) => void;
      onClick: (event: React.MouseEvent) => void;
    };
    loading: boolean;
    suggestions: Suggestion[];
  }

  // PlacesAutocomplete props interface
  export interface PlacesAutocompleteProps {
    value: string;
    onChange: (value: string) => void;
    children: (props: RenderProps) => React.ReactNode;
    onError?: (status: string, clearSuggestions: () => void) => void;
    onSelect?: (address: string, placeId: string | null, suggestion: Suggestion | null) => void;
    onSuggestions?: (suggestions: Suggestion[]) => void;
    searchOptions?: SearchOptions;
    debounce?: number;
    highlightFirstSuggestion?: boolean;
    shouldFetchSuggestions?: boolean;
    googleCallbackName?: string;
  }

  // Main component
  export default class PlacesAutocomplete extends React.Component<PlacesAutocompleteProps> {}

  // Utility functions
  export function geocodeByAddress(address: string): Promise<google.maps.GeocoderResult[]>;

  export function geocodeByPlaceId(placeId: string): Promise<google.maps.GeocoderResult[]>;

  export function geocodeByCoordinates(lat: number, lng: number): Promise<google.maps.GeocoderResult[]>;

  export function getLatLng(result: google.maps.GeocoderResult): Promise<{
    lat: number;
    lng: number;
  }>;
}
