// #region Imports
import { MapProvider } from '../../../Types/MapProvider';
/**
 * Creates an OpenStreetMap provider (default).
 *
 * @public
 */
export function createOpenStreetMapProvider() {
    return {
        getEmbedUrl: (lat, lng, zoom) => {
            const bbox = computeOsmBbox(lat, lng, zoom);
            const u = new URL('https://www.openstreetmap.org/export/embed.html');
            u.searchParams.set('bbox', `${bbox.west},${bbox.south},${bbox.east},${bbox.north}`);
            u.searchParams.set('layer', 'mapnik');
            u.searchParams.set('marker', `${lat},${lng}`);
            return u.toString();
        }
    };
}
/**
 * Creates a Google Maps provider (no API key; basic embed).
 *
 * @public
 */
export function createGoogleProvider() {
    return {
        getEmbedUrl: (lat, lng, zoom, label) => {
            const u = new URL('https://www.google.com/maps');
            u.searchParams.set('q', label ? `${label} @ ${lat},${lng}` : `${lat},${lng}`);
            u.searchParams.set('z', String(zoom));
            u.searchParams.set('output', 'embed');
            return u.toString();
        }
    };
}
/**
 * Creates a Bing Maps provider (no key required for basic embed).
 *
 * @public
 */
export function createBingProvider() {
    return {
        getEmbedUrl: (lat, lng, zoom) => {
            const u = new URL('https://www.bing.com/maps/embed');
            u.searchParams.set('cp', `${lat}~${lng}`);
            u.searchParams.set('lvl', String(zoom));
            // d=road map, r=road style
            u.searchParams.set('typ', 'd');
            u.searchParams.set('sty', 'r');
            return u.toString();
        }
    };
}
/**
 * Creates a HERE WeGo provider (basic URL without key).
 *
 * @public
 */
export function createHereProvider() {
    return {
        getEmbedUrl: (lat, lng, zoom, label) => {
            const u = new URL('https://wego.here.com/directions/mix//');
            u.searchParams.set('map', `${lat},${lng},${zoom},normal`);
            u.searchParams.set('m', `${lat},${lng}`);
            if (label)
                u.searchParams.set('descr', label);
            return u.toString();
        }
    };
}
/**
 * Creates an Apple Maps provider (basic URL).
 *
 * @public
 */
export function createAppleProvider() {
    return {
        getEmbedUrl: (lat, lng, zoom, label) => {
            const u = new URL('https://maps.apple.com/');
            u.searchParams.set('ll', `${lat},${lng}`);
            u.searchParams.set('z', String(zoom));
            if (label)
                u.searchParams.set('q', label);
            return u.toString();
        }
    };
}
/**
 * Resolves a provider factory by MapProvider value.
 *
 * @public
 */
export function resolveProviderFactory(provider) {
    switch (provider) {
        case MapProvider.Google:
            return createGoogleProvider();
        case MapProvider.Bing:
            return createBingProvider();
        case MapProvider.Here:
            return createHereProvider();
        case MapProvider.Apple:
            return createAppleProvider();
        case MapProvider.OpenStreetMap:
        case MapProvider.Default:
        default:
            return createOpenStreetMapProvider();
    }
}
// #region OSM helpers
function computeOsmBbox(lat, lng, zoom) {
    const halfSpanBase = 0.02; // degrees at around zoom ~12
    const scale = Math.pow(2, 12 - zoom);
    const halfSpan = clamp(halfSpanBase * scale, 0.0005, 0.5);
    const north = clamp(lat + halfSpan, -90, 90);
    const south = clamp(lat - halfSpan, -90, 90);
    const east = wrapLongitude(lng + halfSpan);
    const west = wrapLongitude(lng - halfSpan);
    return {
        west,
        south,
        east,
        north
    };
}
function clamp(value, min, max) {
    return Math.min(max, Math.max(min, value));
}
function wrapLongitude(lng) {
    let x = lng;
    while (x < -180)
        x += 360;
    while (x > 180)
        x -= 360;
    return x;
}
// #endregion
//# sourceMappingURL=MapProviders.js.map