/// <reference path="modules.d.ts" />

declare module "@arcgis/core/core/Warning" {
    interface Warning {}

    interface WarningConstructor {
        new (...args: unknown[]): Warning;
    }

    const Warning: WarningConstructor;
    export default Warning;
}

declare module "@arcgis/core/arcade/arcade" {
    export function parseAndExecuteScript(
        script: string,
        parameters: unknown,
        spatialReference: __esri.SpatialReference
    ): unknown | Promise<unknown>;
    export function parseScript(script: string, spatialReference?: __esri.SpatialReference): __esri.ArcadeScript;
    export function enableFeatureSetSupport(): Promise<void>;
    export function executeScript(arcadeScript: __esri.ArcadeScript, parameters: any): unknown | Promise<unknown>;
    export function scriptIsAsync(
        arcadeScript: __esri.ArcadeScript,
        scriptDependencies: undefined | unknown[]
    ): boolean;
    export function enableAsyncSupport(): Promise<void>;
    export function enableGeometrySupport(): Promise<void>;
    export function load(): Promise<void>;
}

declare module "@arcgis/core/support/arcadeUtils" {
    export interface ArcadeViewInfo {}
    export interface FeatureSetCollection {}
    export type ArcadeFunction = (context: ArcadeContext) => Promise<unknown> | unknown;
    export interface ArcadeContext {
        // Enable async Arcade.
        isAsync: boolean;
        // Enable the use of FeatureSets within Arcade.
        usesFeatureSet: boolean;
        // Arcade variables.
        vars: Record<string, unknown>;
    }

    export function createSyntaxTree(expression: string): __esri.ArcadeScript;
    export function hasVariable(syntaxTree: __esri.ArcadeScript, variable: string): boolean;
    export function loadScriptDependencies(
        syntaxTree: __esri.ArcadeScript,
        unknownBoolean: true,
        variables: string[]
    ): Promise<void>;
    export function getViewInfo(params: { spatialReference: __esri.SpatialReference }): ArcadeViewInfo;
    export function createFunction(syntaxTree: __esri.ArcadeScript, context: ArcadeContext): ArcadeFunction;
    export function executeAsyncFunction(arcadeFunction: ArcadeFunction, context: ArcadeContext): Promise<string>;
    export function createExecContext(graphic: Graphic, info: ArcadeViewInfo): ArcadeContext;
    export function convertMapToFeatureSetCollection(args: {
        map: __esri.Map;
        spatialReference: __esri.SpatialReference;
    }): FeatureSetCollection;
    export function convertFeatureLayerToFeatureSet(args: {
        layer: __esri.Layer | __esri.Sublayer;
        spatialReference: __esri.SpatialReference;
    }): FeatureSetCollection;
    export function convertServiceUrlToWorkspace(args: {
        url: string;
        spatialReference: __esri.SpatialReference;
    }): FeatureSetCollection;
}

declare module "@arcgis/core/support/basemapDefinitions.js" {
    interface BasemapDefinition {
        id: string;
        thumbnailUrl?: string;
        baseMapLayers: unknown[];
    }

    export const esriBasemapDefinitions: Record<string, BasemapDefinition>;
}

declare module "@arcgis/core/arcade/featureset/sources/FeatureLayerMemory" {
    interface createFeatureLayerMemoryParams {
        layerDefinition: {
            geometryType: string;
            fields: __esri.Field[];
            spatialReference: __esri.SpatialReference;
        };
        featureSet: {
            geometryType: string;
            features: any[];
        };
    }

    interface FeatureLayerMemory {}
    export function create(a: createFeatureLayerMemoryParams, b: __esri.SpatialReference): Promise<FeatureLayerMemory>;
}

declare module "@arcgis/core/arcade/functions/featuresetbase.js";

declare module "@arcgis/core/arcade/Feature" {
    interface Feature {
        attributes: any;
    }

    interface FeatureConstructor {
        new (): Feature;
        createFromGraphic(graphic: __esri.Graphic): Feature;
    }

    const Feature: FeatureConstructor;
    export { Feature };
}

declare module "@arcgis/core/arcade/Dictionary" {
    interface Dictionary {
        attributes: any;
        immutable: boolean;
        setField(key: string, value: unknown);
        castAsJsonAsync(abortSignal?: AbortSignal): Promise<Object>;
    }

    interface DictionaryProperties {
        attributes?: any;
    }

    interface DictionaryConstructor {
        new (properties?: DictionaryProperties): Dictionary;
        convertObjectToArcadeDictionary(object: Object): Dictionary;
    }

    const Dictionary: DictionaryConstructor;
    export default Dictionary;
}

declare module "@arcgis/core/views/draw/support/drawUtils" {
    export function cloneMove(geometry: Geometry, newX: number, newY: number, view: MapView): Geometry;

    export function scale(geometry: Geometry, scaleX: number, scaleY: number);
}

declare namespace __esri {
    export interface ArcadeScript {
        // Enable async Arcade within the script.
        isAsync: boolean | number;
        // Enable the use of FeatureSets within the script.
        usesFeatureSet: boolean | number;
        // Enable the use of FeatureSets within the script.
        usesGeometry: boolean | number;
    }

    export interface MapNotesSublayer extends __esri.GraphicsLayer {
        layer: MapNotesLayer;
    }
}
