declare module "@arcgis/core/core/accessorSupport/tracking" {
    export function trackAccess(accessorProp: unknown): void;
}

declare module "@arcgis/core/core/accessorSupport/Property" {
    export class Property {
        constructor(propertyName: string, metadata: unknown);
        propertyName: string;
        observe(observer: unknown): IHandle;
        invalidate(): void;
        commit(): void;
        onInvalidated(): void;
    }
}

declare module "@arcgis/core/core/workers/utils";
declare module "@arcgis/core/core/Warning" {
    interface Warning {}

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

    const Warning: WarningConstructor;
    export default Warning;
}

declare module "@arcgis/core/networks/UtilityNetwork" {
    interface UtilityNetwork extends __esri.JSONSupport, __esri.UtilityNetwork, __esri.Network {}
    interface UtilityNetworkConstructor {
        new (properties?: any): UtilityNetwork;
        fromJSON(json: any): UtilityNetwork;
    }

    const UtilityNetwork: UtilityNetworkConstructor;
    export default UtilityNetwork;
}

declare module "@arcgis/core/layers/support/source/DataLayerSource" {
    export interface DataLayerSource extends __esri.JSONSupport, __esri.DynamicDataLayer {}
    export interface DataLayerSourceConstructor {
        new (properties?: any): DataLayerSource;
    }

    export const DataLayerSource: DataLayerSourceConstructor;
}
declare module "@arcgis/core/layers/support/source/MapLayerSource" {
    export interface MapLayerSource extends __esri.JSONSupport, __esri.DynamicMapLayer {}
    export interface MapLayerSourceConstructor {
        new (properties?: any): MapLayerSource;
    }

    export const MapLayerSource: MapLayerSourceConstructor;
}

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/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 default 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/2d/layers/KMLLayerView2D" {
    interface KMLLayerView2D extends __esri.LayerView {
        _featuresMap: Map<
            __esri.KMLSublayer,
            { points: __esri.Graphic[]; polylines: __esri.Graphic[]; polygons: __esri.Graphic[] }
        >;
    }

    interface KMLLayerView2DProperties {
        layer?: __esri.KMLLayer;
    }

    interface KMLLayerView2DConstructor {
        new (properties?: KMLLayerView2DProperties): KMLLayerView2D;
    }

    const KMLLayerView2D: KMLLayerView2DConstructor;
    export default KMLLayerView2D;
}

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 module "esri/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 FieldsContent {
        /**
         * Property will be populated when used for Arcade popup elements of
         * type "fields", otherwise it will be null.
         */
        attributes: Record<string, unknown>;
    }

    export interface MediaContent {
        /**
         * Property will be populated when used for Arcade popup elements of
         * type "media", otherwise it will be null.
         */
        attributes: Record<string, unknown>;
    }

    // ESRI429 - Check if the extended interfaces below are still necessary.

    export interface SceneLayer {
        associatedLayer: __esri.FeatureLayer;
    }

    export interface WFSLayerInfo {
        geometryField: string;
    }

    export interface WMSLayer {
        mapUrl: string;
        resourceInfo:
            | {
                  supportedImageFormatTypes: string[] | undefined;
              }
            | undefined;
    }

    export interface WMSLayerProperties {
        mapUrl?: string;
    }

    export interface FeatureLayer {
        mode: number;
    }

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

    export interface MapNotesLayer {
        multipointLayer: MapNotesSublayer;
        pointLayer: MapNotesSublayer;
        polygonLayer: MapNotesSublayer;
        polylineLayer: MapNotesSublayer;
        textLayer: MapNotesSublayer;
        sublayers: Collection<MapNotesSublayer>;
    }

    export interface SubtypeSublayer extends Accessor {
        listMode: "show" | "hide" | "hide-children";
        parent: __esri.SubtypeGroupLayer;
        layer: __esri.SubtypeGroupLayer;
    }

    export interface Renderer {
        clone(): this;
    }

    // Check if VectorFieldRenderer extends Renderer.
    export interface VectorFieldRenderer extends Renderer {}

    export interface locatorSuggestLocationsParams {
        searchExtent: Extent;
        maxSuggestions: number;
        countryCode: string;
    }

    export interface BuildingSublayer {
        layer: __esri.BuildingSceneLayer;
    }

    export interface BuildingComponentSublayer {
        fields: __esri.Field[];
        objectIdField: string;
        geometryType: __esri.Geometry["type"];
        capabilities: BuildingComponentSublayerCapabilities;
        loaded: boolean;
    }

    export interface BuildingComponentSublayerCapabilitiesData {
        isVersioned: boolean;
        supportsM: boolean;
        supportsZ: boolean;
    }

    export interface BuildingComponentSublayerCapabilities {
        /**
         * Describes characteristics of the data in the layer.
         *
         * [Read
         * more...](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-CSVLayer.html#capabilities)
         */
        data: BuildingComponentSublayerCapabilitiesData;
    }

    export interface StreamLayerView {
        createQuery(): __esri.supportQuery;
        view: __esri.MapView | __esri.SceneView;
    }

    export interface SceneLayerView {
        view: __esri.MapView | __esri.SceneView;
    }

    export interface CSVLayerView {
        view: __esri.MapView | __esri.SceneView;
    }

    export interface FeatureLayerView {
        view: __esri.MapView | __esri.SceneView;
    }

    export interface PointCloudLayerView {
        view: __esri.MapView | __esri.SceneView;
    }

    export interface BuildingComponentSublayerView {
        view: __esri.MapView | __esri.SceneView;
    }

    export interface FeatureLayerView {
        view: __esri.MapView | __esri.SceneView;
    }

    export interface GeoJSONLayerView {
        view: __esri.MapView | __esri.SceneView;
    }

    export interface EditsResult {
        addFeatureResults: __esri.FeatureEditResult[];
        deleteFeatureResults: __esri.FeatureEditResult[];
        updateFeatureResults: __esri.FeatureEditResult[];
    }

    export interface Symbol3DLayerProperties {
        // The type property is required for autocasting to work.
        type: Symbol3DLayer["type"];
    }

    export interface Accessor {
        get<T = unknown>(propertyPath: string): T;
    }
}
