import { GeocodingResponseOutput } from '@azure-rest/maps-search';
import { SearchPlaceIndexForTextCommandOutput, LocationClientConfig } from '@aws-sdk/client-location';

type LocationMap = {
    country?: string;
    state?: string;
    county?: string;
    city?: string;
    postal_code?: string;
    street?: string | string[];
};

type MapSearchParams = {
    query: string;
    locationType?: keyof LocationMap;
};

type GeocodeResult = {
    type?: keyof LocationMap;
    country?: string;
    geometry?: {
        type: 'Point';
        coordinates: number[];
    };
    label?: string;
    municipality?: string;
    postalcode?: string;
    region?: string;
    street?: string;
    subregion?: string;
    resultbbox?: number[];
};

/**
 * This is the type returned by any of the map service providers
 */
type IMapConnectorTInput = GeocodingResponseOutput | SearchPlaceIndexForTextCommandOutput;

/**
 * Map Connector interface (contract) for any map provider
 * TInput: Input type for the "transform" method and, therefore, the output
 * type for the "forwardGeocode" function.
 */
interface IMapConnector<TInput> {
    forwardGeocode: (query: string, locationType?: keyof LocationMap) => Promise<TInput>;
    transform(data: TInput, locationType?: keyof LocationMap): GeocodeResult;
}

declare class MapSearchService {
    private readonly connector;
    /**
     * @param connector - A connector that implements the MapConnector interface.
     */
    constructor(connector: IMapConnector<IMapConnectorTInput>);
    /**
     * Forward geocode using the injected connector.
     * Note: It returns the best match according to params.
     */
    forwardGeocode(params: MapSearchParams): Promise<GeocodeResult>;
}

declare class AmazonConnector implements IMapConnector<SearchPlaceIndexForTextCommandOutput> {
    private readonly client;
    constructor(authConfiguration?: Partial<LocationClientConfig>);
    /**
     * Amazon Location forward geocode method
     */
    forwardGeocode(query: string, locationType?: keyof LocationMap): Promise<SearchPlaceIndexForTextCommandOutput>;
    /**
     * Transform Amazon Location response to map search response
     */
    transform(rawData: SearchPlaceIndexForTextCommandOutput, locationType: keyof LocationMap): GeocodeResult;
}

type AuthConfiguration = {
    apiKey?: string;
};
declare class AzureConnector implements IMapConnector<GeocodingResponseOutput> {
    private readonly client;
    constructor(authConfiguration?: AuthConfiguration);
    /**
     * Azure Location forward geocode method
     */
    forwardGeocode(query: string, locationType?: keyof LocationMap): Promise<GeocodingResponseOutput>;
    /**
     * Transform Azure Location response to map search response
     */
    transform(rawData: GeocodingResponseOutput, locationType: keyof LocationMap): GeocodeResult;
}

/**
 * Get map connector instance from environment variables.
 * @returns IMapConnector
 */
declare function getMapConnector(): IMapConnector<IMapConnectorTInput>;

declare const LOCATION_INDEX_NAME = "Qrvey_LocationIndex";
declare const CLOUD_PROVIDERS: {
    AMAZON: string;
    AZURE: string;
    GOOGLE: string;
    MAPBOX: string;
};
declare const GEOPROPERTIES_MAPPING: {
    AMAZON: {
        country: string;
        state: string;
        county: string;
        city: string;
        postal_code: string;
        street: string[];
    };
    MAPBOX: {
        country: string;
        state: string;
        county: string;
        city: string;
        postal_code: string;
        street: string;
    };
};

export { AmazonConnector, AzureConnector, CLOUD_PROVIDERS, GEOPROPERTIES_MAPPING, LOCATION_INDEX_NAME, MapSearchService, getMapConnector };
