import * as mapbox_gl from 'mapbox-gl';
import { Map as Map$1, Marker as Marker$1, AnyLayer, AnySourceData, MarkerOptions, PopupOptions, Popup as Popup$1, LineLayout, LinePaint, LineLayer, GeoJSONSourceRaw, CircleLayout, CirclePaint, CircleLayer } from 'mapbox-gl';
import * as react from 'react';
import { Context, RefObject, PropsWithChildren, RefAttributes, CSSProperties } from 'react';
import * as react_jsx_runtime from 'react/jsx-runtime';
import { MapBoxSKDOptionsModel } from '@neshan-maps-platform/mapbox-gl/dist/src/parameters/parameters';

interface MapContextInterface {
    map: Map$1;
    marker?: Marker$1;
}
declare function createNeshanContext(map: Map$1): MapContextInterface;
declare function useNeshanContext(): MapContextInterface;
declare const MapContext: Context<MapContextInterface>;

type DisclosureFn = (open: boolean) => void;
type LifeCycleHook<E, P> = (element: MapElement<E>, context: MapContextInterface, props?: P, setOpen?: DisclosureFn) => void;
declare function createElementRef<E, P>(useElement: ElementHook<E, P>, useLifeCycle: LifeCycleHook<E, P>): (props: P, setOpen?: DisclosureFn) => ReturnType<ElementHook<E, P>>;

interface MapElement<T> {
    readonly instance: T;
    readonly context: MapContextInterface;
}
type ComponentElementHook<E, P> = (props: P, setOpen?: DisclosureFn) => RefObject<MapElement<E>>;
type ElementHook<E, P> = (props: P, context: MapContextInterface) => RefObject<MapElement<E>>;
type CreateElementFn<E, P> = (props: P, context: MapContextInterface) => MapElement<E>;
type UpdateElementFn<E, P> = (instance: E, props: P, prevProps: P) => void;
type ElementHookResult<E, P> = (props: P, context: MapContextInterface) => RefObject<MapElement<E>>;
declare function createElementHook<E, P>(createElement: CreateElementFn<E, P>, updateElement?: UpdateElementFn<E, P>): ElementHookResult<E, P>;
declare function createMapElement<T>(instance: T, context: MapContextInterface): MapElement<T>;

declare function createContainerComponent<E, P extends PropsWithChildren<RefAttributes<E>>>(useElement: ComponentElementHook<E, P>): (props: P) => string | number | bigint | boolean | Iterable<react.ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<react.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;

/**
 * Remove properties `K` from `T`.
 * Distributive for union types.
 *
 * @internal
 */
type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
/**
 * Changes the properties K from T to optional
 */
type PartiallyOptional<T, K extends keyof T> = DistributiveOmit<T, K> & {
    [P in K]?: T[P];
};
type LngLat = [number, number];

interface LayerImpl {
    addTo: (map: Map$1) => this;
    remove: () => this;
}
interface LayerOptions {
    sourceId?: string;
    layerId?: string;
}
declare class Layer<L extends AnyLayer, S extends AnySourceData> implements LayerImpl {
    protected _map: Map$1 | null | undefined;
    protected _layerId: string;
    protected _sourceId: string;
    protected _source: S;
    protected _layer: L;
    constructor(layer: PartiallyOptional<L, 'id'>, source: S, options?: LayerOptions);
    addTo(map: Map$1): this;
    getSource(): S;
    getSourceId(): string;
    getLayer(): L;
    getLayerId(): string;
    remove(): this;
    reset(): this;
    protected _init(): this;
    protected _setSource(source: S): this;
    protected _setLayer(layer: L): this;
}
declare function useLayerLifeCycle<L extends LayerImpl>(element: MapElement<L>, context: MapContextInterface): void;

declare function createLayerComponent<E extends LayerImpl, P extends PropsWithChildren>(createElement: CreateElementFn<E, P>, updateElement: UpdateElementFn<E, P>): (props: P) => string | number | bigint | boolean | Iterable<react.ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<react.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;

type MapType = Map$1;
interface MapProps extends Omit<MapBoxSKDOptionsModel, 'container' | 'style'>, PropsWithChildren<RefAttributes<MapType | null>> {
    style?: CSSProperties;
    id?: string;
    className?: string;
    fullscreen?: boolean;
}
declare function Map(props: MapProps): react_jsx_runtime.JSX.Element;

type MarkerType = Marker$1;
interface MarkerProps extends MarkerOptions, PropsWithChildren {
    lngLat: LngLat;
}
declare const Marker: (props: MarkerProps) => string | number | bigint | boolean | Iterable<react.ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<react.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;

type PopupType = Popup$1;
interface PopupProps extends PopupOptions, PropsWithChildren {
    show?: boolean;
    lngLat?: LngLat;
}
declare const Popup: react.ForwardRefExoticComponent<PopupProps & react.RefAttributes<Popup$1>>;

declare function createPopupComponent(createElement: CreateElementFn<PopupType, PopupProps>, useLifeCycle: LifeCycleHook<PopupType, PopupProps>): react.ForwardRefExoticComponent<PopupProps & react.RefAttributes<mapbox_gl.Popup>>;

interface PolylineTransitionOptions {
    opacity?: LinePaint['line-opacity-transition'];
    color?: LinePaint['line-color-transition'];
    translate?: LinePaint['line-translate-transition'];
    width?: LinePaint['line-width-transition'];
    gapWidth?: LinePaint['line-gap-width-transition'];
    offset?: LinePaint['line-offset-transition'];
    blur?: LinePaint['line-blur-transition'];
    dasharray?: LinePaint['line-dasharray-transition'];
    pattern?: LinePaint['line-pattern-transition'];
}
interface PolylineStyleOptions extends LineLayout {
    opacity?: LinePaint['line-opacity'];
    color?: LinePaint['line-color'];
    dasharray?: LinePaint['line-dasharray'];
    translate?: LinePaint['line-translate'];
    translateAnchor?: LinePaint['line-translate-anchor'];
    width?: LinePaint['line-width'];
    gapWidth?: LinePaint['line-gap-width'];
    offset?: LinePaint['line-offset'];
    blur?: LinePaint['line-blur'];
    pattern?: LinePaint['line-pattern'];
    gradient?: LinePaint['line-gradient'];
    transitions?: PolylineTransitionOptions;
}
interface PolylineOptions extends PolylineStyleOptions, LayerOptions {
}
type PolylineType = Polyline$1;
declare class Polyline$1 extends Layer<LineLayer, GeoJSONSourceRaw> {
    private _lngLats;
    constructor(lngLats: LngLat[] | LngLat[][], options?: PolylineOptions);
    getLatLngs(): LngLat[] | LngLat[][];
    setLatLngs(lngLats: LngLat[] | LngLat[][]): this;
    setStyles(options: PolylineStyleOptions): this;
    private _updateLayer;
    private _updateSource;
}

interface PolylineProps extends PolylineOptions, PropsWithChildren {
    lngLats: LngLat[] | LngLat[][];
}
declare const Polyline: (props: PolylineProps) => string | number | bigint | boolean | Iterable<react.ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<react.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;

declare function isFlat(lngLats: LngLat[] | LngLat[][]): lngLats is LngLat[];

interface CircleTransitionOptions {
    radius?: CirclePaint['circle-radius-transition'];
    color?: CirclePaint['circle-color-transition'];
    blur?: CirclePaint['circle-blur-transition'];
    opacity?: CirclePaint['circle-opacity-transition'];
    translate?: CirclePaint['circle-translate-transition'];
    strokeWidth?: CirclePaint['circle-stroke-width-transition'];
    strokeColor?: CirclePaint['circle-stroke-color-transition'];
    strokeOpacity?: CirclePaint['circle-stroke-opacity-transition'];
}
interface CircleStyleOptions extends CircleLayout {
    radius?: CirclePaint['circle-radius'];
    color?: CirclePaint['circle-color'];
    blur?: CirclePaint['circle-blur'];
    opacity?: CirclePaint['circle-opacity'];
    translate?: CirclePaint['circle-translate'];
    translateAnchor?: CirclePaint['circle-translate-anchor'];
    pitchScale?: CirclePaint['circle-pitch-scale'];
    pitchAlignment?: CirclePaint['circle-pitch-alignment'];
    strokeWidth?: CirclePaint['circle-stroke-width'];
    strokeColor?: CirclePaint['circle-stroke-color'];
    strokeOpacity?: CirclePaint['circle-stroke-opacity'];
    transitions?: CircleTransitionOptions;
}
interface CircleOptions extends CircleStyleOptions, LayerOptions {
}
type CircleType = Circle$1;
declare class Circle$1 extends Layer<CircleLayer, GeoJSONSourceRaw> {
    private _lngLat;
    constructor(lngLat: LngLat | LngLat[], options: CircleOptions);
    getLatLng(): LngLat | LngLat[];
    setLatLng(lngLat: LngLat | LngLat[]): this;
    setStyles(options: CircleStyleOptions): this;
    private _updateLayer;
    private _updateSource;
}

interface CircleProps extends CircleOptions, PropsWithChildren {
    lngLat: LngLat | LngLat[];
}
declare const Circle: (props: CircleProps) => string | number | bigint | boolean | Iterable<react.ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<react.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;

declare function isMultiPoint(LngLat: LngLat | LngLat[]): LngLat is LngLat[];

export { Circle, Circle$1 as CircleClass, type CircleOptions, type CircleProps, type CircleStyleOptions, type CircleTransitionOptions, type CircleType, type ComponentElementHook, type CreateElementFn, type DisclosureFn, type ElementHook, Layer, type LayerImpl, type LayerOptions, type LifeCycleHook, type LngLat, Map, MapContext, type MapContextInterface, type MapElement, type MapProps, type MapType, Marker, type MarkerProps, type MarkerType, Polyline, Polyline$1 as PolylineClass, type PolylineOptions, type PolylineProps, type PolylineStyleOptions, type PolylineTransitionOptions, type PolylineType, Popup, type PopupProps, type PopupType, type UpdateElementFn, createContainerComponent, createElementHook, createElementRef, createLayerComponent, createMapElement, createNeshanContext, createPopupComponent, isFlat, isMultiPoint, useLayerLifeCycle, useNeshanContext };
