type TravelMode = "drive" | "light_truck" | "medium_truck" | "truck" | "heavy_truck" | "truck_dangerous_goods" | "long_truck" | "bus" | "scooter" | "motorcycle" | "bicycle" | "mountain_bike" | "road_bike" | "walk" | "hike" | "transit" | "approximated_transit";

type AvoidType = "tolls" | "tolls:importance" | "ferries" | "ferries:importance" | "highways" | "highways:importance" | "locations" | "location" | "location_lonlat";

type TrafficType = "free_flow" | "approximated";

type DistanceUnitType = "metric" | "imperial";

type RouteType = "balanced" | "short" | "less_maneuvers";

interface BreakData {
    duration?: number;
    time_windows: [number, number][];
}

interface AgentData {
    start_location?: [number, number];
    start_location_index?: number;
    end_location?: [number, number];
    end_location_index?: number;
    pickup_capacity?: number;
    delivery_capacity?: number;
    capabilities: string[];
    time_windows: [number, number][];
    breaks: BreakData[];
    id?: string;
    description?: string;
}

interface CoordinatesData {
    lon?: number;
    lat?: number;
}

interface AvoidData {
    type?: AvoidType;
    values: CoordinatesData[];
}

interface JobData {
    location?: [number, number];
    location_index?: number;
    priority?: number;
    duration?: number;
    pickup_amount?: number;
    delivery_amount?: number;
    requirements: string[];
    time_windows: [number, number][];
    id?: string;
    description?: string;
}

interface LocationData {
    id?: string;
    location?: [number, number];
}

interface ShipmentStepData {
    location?: [number, number];
    location_index?: number;
    duration?: number;
    time_windows: [number, number][];
}

interface ShipmentData {
    id?: string;
    pickup?: ShipmentStepData;
    delivery?: ShipmentStepData;
    requirements: string[];
    priority?: number;
    description?: string;
    amount?: number;
}

interface RoutePlannerInputData {
    mode?: TravelMode;
    agents: AgentData[];
    jobs: JobData[];
    shipments: ShipmentData[];
    locations: LocationData[];
    avoid: AvoidData[];
    traffic?: TrafficType;
    type?: RouteType;
    max_speed?: number;
    units?: DistanceUnitType;
}

interface GeometryResponseData {
    type: string;
    coordinates: [number, number][];
}

interface LegStepResponseData {
    distance: number;
    time: number;
    from_index: number;
    to_index: number;
}

interface LegResponseData {
    distance: number;
    time: number;
    steps: LegStepResponseData[];
    from_waypoint_index: number;
    to_waypoint_index: number;
}

interface ActionResponseData {
    type: string;
    start_time: number;
    duration: number;
    shipment_index?: number;
    shipment_id?: string;
    location_index?: number;
    location_id?: string;
    job_index?: number;
    job_id?: string;
    index?: number;
    waypoint_index?: number;
}

interface WaypointResponseData {
    original_location: [number, number];
    original_location_index?: number;
    original_location_id?: number;
    location: [number, number];
    start_time: number;
    duration: number;
    actions: ActionResponseData[];
    prev_leg_index?: number;
    next_leg_index?: number;
}

interface PropertiesResponseData {
    agent_index: number;
    agent_id: string;
    time: number;
    start_time: number;
    end_time: number;
    distance: number;
    mode: string;
    legs?: LegResponseData[];
    actions: ActionResponseData[];
    waypoints: WaypointResponseData[];
}

interface FeatureResponseData {
    geometry: GeometryResponseData;
    type: string;
    properties: PropertiesResponseData;
}

interface RoutePlannerResultResponseData {
    type: string;
    properties: {
        mode: string;
        params: {
            mode?: string;
            agents: AgentData[];
            jobs: JobData[];
            shipments: ShipmentData[];
            locations: LocationData[];
            avoid: AvoidData[];
            traffic?: string;
            type?: string;
            max_speed?: number;
            units?: string;
        };
        issues: {
            unassigned_agents: number[];
            unassigned_jobs: number[];
            unassigned_shipments: number[];
        };
    };
    features: FeatureResponseData[];
}

interface RouteActionData {
    type: string;
    start_time: number;
    duration: number;
    shipment_index?: number;
    shipment_id?: string;
    location_index?: number;
    location_id?: string;
    job_index?: number;
    job_id?: string;
    index?: number;
    waypoint_index?: number;
}

interface WaypointData {
    original_location: [number, number];
    original_location_index?: number;
    original_location_id?: number;
    location: [number, number];
    start_time: number;
    duration: number;
    actions: RouteActionData[];
    prev_leg_index?: number;
    next_leg_index?: number;
}

interface RouteLegStepData {
    distance: number;
    time: number;
    from_index: number;
    to_index: number;
}

interface RouteLegData {
    time: number;
    distance: number;
    steps: RouteLegStepData[];
    from_waypoint_index: number;
    to_waypoint_index: number;
}

interface AgentSolutionData {
    agentIndex: number;
    agentId: string;
    time: number;
    start_time: number;
    end_time: number;
    distance: number;
    mode: string;
    legs: RouteLegData[];
    actions: RouteActionData[];
    waypoints: WaypointData[];
}

interface RoutePlannerResultData {
    agents: AgentSolutionData[];
    inputData: RoutePlannerInputData;
    unassignedAgents: number[];
    unassignedJobs: number[];
    unassignedShipments: number[];
}

declare class Break {
    private raw;
    constructor(raw?: BreakData);
    getRaw(): BreakData;
    setRaw(value: BreakData): this;
    addTimeWindow(start: number, end: number): this;
    setDuration(duration: number): this;
}

declare class Agent {
    private raw;
    constructor(raw?: AgentData);
    getRaw(): AgentData;
    setRaw(value: AgentData): this;
    setStartLocation(lon: number, lat: number): this;
    setStartLocationIndex(value: number): this;
    setEndLocation(lon: number, lat: number): this;
    setEndLocationIndex(value: number): this;
    setPickupCapacity(value: number): this;
    setDeliveryCapacity(value: number): this;
    addCapability(value: string): this;
    addTimeWindow(start: number, end: number): this;
    addBreak(value: Break): this;
    setId(value: string): this;
    setDescription(value: string): this;
}

declare class Avoid {
    private raw;
    constructor(raw?: AvoidData);
    getRaw(): AvoidData;
    setRaw(value: AvoidData): this;
    setType(type: AvoidType): this;
    addValue(lon: number, lat: number): this;
}

declare class Coordinates {
    private raw;
    constructor(raw?: CoordinatesData);
    getRaw(): CoordinatesData;
    setRaw(value: CoordinatesData): this;
    setLat(lat: number): this;
    setLon(lon: number): this;
}

declare class Job {
    private raw;
    constructor(raw?: JobData);
    getRaw(): JobData;
    setRaw(value: JobData): this;
    setLocation(lon: number, lat: number): this;
    setLocationIndex(value: number): this;
    setPriority(value: number): this;
    setDuration(value: number): this;
    setPickupAmount(value: number): this;
    setDeliveryAmount(value: number): this;
    addRequirement(value: string): this;
    addTimeWindow(start: number, end: number): this;
    setId(value: string): this;
    setDescription(value: string): this;
}

declare class Location {
    private raw;
    constructor(raw?: LocationData);
    getRaw(): LocationData;
    setRaw(value: LocationData): this;
    setId(id: string): this;
    setLocation(lon: number, lat: number): this;
}

declare class ShipmentStep {
    private raw;
    constructor(raw?: ShipmentStepData);
    getRaw(): ShipmentStepData;
    setRaw(value: ShipmentStepData): this;
    setLocation(lon: number, lat: number): this;
    setLocationIndex(value: number): this;
    setDuration(value: number): this;
    addTimeWindow(start: number, end: number): this;
}

declare class Shipment {
    private raw;
    constructor(raw?: ShipmentData);
    getRaw(): ShipmentData;
    setRaw(value: ShipmentData): this;
    setId(id: string): this;
    setPickup(value: ShipmentStep): this;
    setDelivery(value: ShipmentStep): this;
    addRequirement(value: string): this;
    setPriority(value: number): this;
    setDescription(value: string): this;
    setAmount(value: number): this;
}

declare class RouteLegStep {
    private readonly raw;
    constructor(raw?: RouteLegStepData);
    getRaw(): RouteLegStepData;
    getDistance(): number;
    getTime(): number;
    getFromIndex(): number;
    getToIndex(): number;
}

declare class RouteLeg {
    private readonly raw;
    constructor(raw?: RouteLegData);
    getRaw(): RouteLegData;
    getTime(): number;
    getDistance(): number;
    getSteps(): RouteLegStep[];
    getFromWaypointIndex(): number;
    getToWaypointIndex(): number;
}

declare class RouteAction {
    private readonly raw;
    constructor(raw?: RouteActionData);
    getRaw(): RouteActionData;
    getType(): string;
    getStartTime(): number;
    getDuration(): number;
    getShipmentIndex(): number | undefined;
    getShipmentId(): string | undefined;
    getLocationIndex(): number | undefined;
    getLocationId(): string | undefined;
    getJobIndex(): number | undefined;
    getJobId(): string | undefined;
    getIndex(): number | undefined;
    getWaypointIndex(): number | undefined;
}

declare class Waypoint {
    private readonly raw;
    constructor(raw?: WaypointData);
    getRaw(): WaypointData;
    getOriginalLocation(): [number, number];
    getOriginalLocationIndex(): number | undefined;
    getOriginalLocationId(): number | undefined;
    getLocation(): [number, number];
    getStartTime(): number;
    getDuration(): number;
    getActions(): RouteAction[];
    getPrevLegIndex(): number | undefined;
    getNextLegIndex(): number | undefined;
}

declare class AgentSolution {
    private readonly raw;
    constructor(raw?: AgentSolutionData);
    getRaw(): AgentSolutionData;
    getAgentIndex(): number;
    getAgentId(): string;
    getTime(): number;
    getStartTime(): number;
    getEndTime(): number;
    getDistance(): number;
    getMode(): string;
    getLegs(): RouteLeg[];
    getActions(): RouteAction[];
    getWaypoints(): Waypoint[];
}

declare class RouteActionInfo {
    private readonly raw;
    constructor(raw?: RouteActionInfoData);
    getRaw(): RouteActionInfoData;
    getAgentId(): string;
    getAction(): RouteAction;
    getAgent(): AgentSolution;
}

declare class RoutePlannerError extends Error {
    errorName: string;
    constructor(errorName: string, message: string);
}

interface RouteActionInfoData {
    agentId: string;
    action: RouteAction;
    agent: AgentSolution;
}

interface RoutePlannerOptions {
    apiKey: string;
    baseUrl?: string;
    httpOptions?: Record<string, any>;
}

/**
 * Provides convenient methods for reading Route Planner API results.
 */
declare class RoutePlannerResult {
    private readonly rawData;
    private readonly options;
    constructor(options: RoutePlannerOptions, rawData: RoutePlannerResultData);
    /**
     * Returns the raw API response.
     */
    getRaw(): RoutePlannerResultData;
    /**
     * Returns a list of all assigned agent solutions.
     */
    getAgentSolutions(): AgentSolution[];
    /**
     * Finds an agent's solution by their ID.
     */
    getAgentSolution(agentId: string): AgentSolution | undefined;
    /**
     * Retrieves all waypoints of a specific agent.
     */
    getAgentWaypoints(agentId: string): Waypoint[];
    /**
     * Retrieves all route actions of a specific agent.
     */
    getAgentRouteActions(agentId: string): RouteAction[];
    /**
     * Retrieves all route legs of a specific agent.
     */
    getAgentRouteLegs(agentId: string): RouteLeg[];
    /**
     * Retrieves the options used to generate the result.
     */
    getOptions(): RoutePlannerOptions;
    /**
    * Retrieves all jobs assigned to a specific agent.
    */
    getAgentJobs(agentId: string): string[];
    /**
     * Retrieves all shipments assigned to a specific agent.
     */
    getAgentShipments(agentId: string): string[];
    /**
     * Retrieves unassigned agents.
     */
    getUnassignedAgents(): number[];
    /**
     * Retrieves unassigned jobs.
     */
    getUnassignedJobs(): number[];
    /**
     * Retrieves unassigned shipments.
     */
    getUnassignedShipments(): number[];
    /**
     * Retrieves detailed information about a specific job.
     */
    getJobInfo(jobId: string): RouteActionInfo | undefined;
    /**
     * Retrieves detailed information about a specific shipment.
     */
    getShipmentInfo(shipmentId: string): RouteActionInfo | undefined;
    /**
     * Retrieves the route for a specific agent.
     * @param agentId - The ID of the agent.
     * @param mode
     */
    getAgentRoute(agentId: string, mode: TravelMode): Promise<any | undefined>;
}

declare class RoutePlanner {
    private raw;
    private options;
    constructor(options: RoutePlannerOptions, raw?: RoutePlannerInputData);
    getRaw(): RoutePlannerInputData;
    setRaw(value: RoutePlannerInputData): this;
    setMode(mode: TravelMode): this;
    addAgent(agent: Agent): this;
    addJob(job: Job): this;
    addLocation(location: Location): this;
    addShipment(shipment: Shipment): this;
    addAvoid(avoid: Avoid): this;
    setTraffic(traffic: TrafficType): this;
    setType(type: RouteType): this;
    setMaxSpeed(max_speed: number): this;
    setUnits(units: DistanceUnitType): this;
    plan(): Promise<RoutePlannerResult>;
}

declare class RoutePlannerResultEditor {
    private readonly result;
    constructor(result: RoutePlannerResult);
    /**
     * Assigns a job to an agent. Removes the job if it's currently assigned to another agent
     * @param agentId - The ID of the agent.
     * @param jobIds - The IDs of the jobs.
     * @returns {boolean} - Returns true if the job was successfully assigned.
     */
    assignJobs(agentId: string, jobIds: string[]): Promise<boolean>;
    /**
     * Assigns a shipment to an agent. Removes the shipment if it's currently assigned to another agent
     * @param shipmentIds - The IDs of the shipments.
     * @param agentId - The ID of the agent.
     * @returns {boolean} - Returns true if the shipment was successfully assigned.
     */
    assignShipments(agentId: string, shipmentIds: string[]): Promise<boolean>;
    /**
     * Removes a job from the plan.
     * @param jobIds - The IDs of the jobs to remove.
     * @returns {boolean} - Returns true if the job was successfully removed.
     */
    removeJobs(jobIds: string[]): Promise<boolean>;
    /**
     * Removes a shipment from the plan.
     * @param shipmentIds - The IDs of the shipments to remove.
     * @returns {boolean} - Returns true if the shipment was successfully removed.
     */
    removeShipments(shipmentIds: string[]): Promise<boolean>;
    /**
     * Adds new jobs to an agent's schedule.
     * @param jobs - An array of job objects to be added.
     * @param agentId - The ID of the agent.
     * @returns {boolean} - Returns true if jobs were successfully added.
     */
    addNewJobs(agentId: string, jobs: Job[]): Promise<boolean>;
    /**
     * Adds new shipments to an agent's schedule.
     * @param shipments - An array of shipment objects to be added.
     * @param agentId - The ID of the agent.
     * @returns {boolean} - Returns true if shipments were successfully added.
     */
    addNewShipments(agentId: string, shipments: Shipment[]): Promise<boolean>;
    /**
     * Returns the modified result.
     * @returns {RoutePlannerResult} - The modified result object.
     */
    getModifiedResult(): RoutePlannerResult;
}

export { type ActionResponseData, Agent, type AgentData, AgentSolution, type AgentSolutionData, Avoid, type AvoidData, type AvoidType, Break, type BreakData, Coordinates, type CoordinatesData, type DistanceUnitType, type FeatureResponseData, type GeometryResponseData, Job, type JobData, type LegResponseData, type LegStepResponseData, Location, type LocationData, type PropertiesResponseData, RouteAction, type RouteActionData, RouteActionInfo, type RouteActionInfoData, RouteLeg, type RouteLegData, RouteLegStep, type RouteLegStepData, RoutePlanner, RoutePlannerError, type RoutePlannerInputData, type RoutePlannerResultData, RoutePlannerResultEditor, type RoutePlannerResultResponseData, type RouteType, Shipment, type ShipmentData, ShipmentStep, type ShipmentStepData, type TrafficType, type TravelMode, Waypoint, type WaypointData, type WaypointResponseData, RoutePlanner as default };
