/**
 * Shared template utils for Components.
 *
 * @internal
 * @internal
 */
import type SharedTemplate from "../../editing/sharedTemplates/SharedTemplate.js";
import type SharedTemplateMetadata from "../../editing/sharedTemplates/SharedTemplateMetadata.js";
import type FeatureLayer from "../../layers/FeatureLayer.js";
import type SubtypeGroupLayer from "../../layers/SubtypeGroupLayer.js";
import type FeatureTemplate from "../../layers/support/FeatureTemplate.js";
import type FeatureService from "../../rest/featureService/FeatureService.js";
import type View from "../../views/View.js";
import type { LayerWithFeatureTemplatesUnion } from "../../layers/types.js";
import type { MapViewOrSceneView } from "../../views/MapViewOrSceneView.js";

/**
 * @internal
 * @internal
 */
export type AnyLoadedEditingTemplate = FeatureTemplate | LoadedSharedTemplate;

/**
 * @internal
 * @internal
 */
export type LoadedSharedTemplate = SharedTemplate
  & {
  /**
   * The definition of the template
   *
   * @internal
   */
  definition: object;
  /**
   * The feature service from which the template was loaded
   *
   * @internal
   */
  featureService: FeatureService;
  /**
   * The layer which the template is associated with.
   *
   * @internal
   */
  layer: FeatureLayer | SubtypeGroupLayer | null;
  /**
   * The view for which the template has been loaded for.
   *
   * @internal
   */
  view: MapViewOrSceneView;
};

/**
 * @internal
 * @internal
 */
export type AnyEditingTemplateInfo = FeatureTemplate | SharedTemplateMetadata;

/**
 * @internal
 * @internal
 */
export interface LayerTemplateInfos {
  /**
   * Layer which supports feature templates.
   *
   * @internal
   */
  layer: LayerWithFeatureTemplatesUnion;
  /**
   * Standard and shared templates for the given layer.
   *
   * @internal
   */
  templates: AnyEditingTemplateInfo[];
}

/**
 * @internal
 * @internal
 */
export interface QuerySharedTemplatesParameters {
  /** @internal */
  layers?: number[];
  /** @internal */
  restrictTemplatesToReferencedLayers?: boolean;
  /** @internal */
  returnVisibleTemplatesOnly?: boolean;
  /** @internal */
  templateIds?: number[];
  /** @internal */
  tags?: string[];
}

/**
 * Test if template is a Shared Group Template
 *
 * @param template
 * @internal
 * @internal
 */
export function isSharedGroupTemplate(template: FeatureTemplate | SharedTemplate | null | undefined): boolean;

/**
 * Test if template is a Shared Preset Template
 *
 * @param template
 * @internal
 * @internal
 */
export function isSharedPresetTemplate(template: FeatureTemplate | SharedTemplate | null | undefined): boolean;

/**
 * Test if template is a standard Feature Template
 *
 * @param template
 * @internal
 * @internal
 */
export function isStandardFeatureTemplate(template: FeatureTemplate | SharedTemplateMetadata | null | undefined): template is FeatureTemplate;

/**
 * Test if template is a shared feature template
 *
 * @param template
 * @internal
 * @internal
 */
export function isSharedFeatureTemplate(template: FeatureTemplate | SharedTemplate | null | undefined): template is FeatureTemplate;

/**
 * Test if template info is Meta data for a Shared Template
 *
 * @param template
 * @internal
 * @internal
 */
export function isSharedTemplateMetadata(template: FeatureTemplate | SharedTemplateMetadata | null | undefined): template is SharedTemplateMetadata;

/**
 * Test if template is a Shared Template
 *
 * @param template
 * @internal
 * @internal
 */
export function isSharedTemplate(template: FeatureTemplate | SharedTemplateMetadata | null | undefined): template is SharedTemplate;

/**
 * Test if template is a Template or Template Info
 *
 * @param template
 * @internal
 * @internal
 */
export function isSharedTemplateOrMetadata(template: FeatureTemplate | SharedTemplateMetadata | null | undefined): template is SharedTemplateMetadata;

/**
 * Load a full template definition from its meta data
 *
 * @param view
 * @param templateInfo
 * @internal
 * @internal
 */
export function getFullTemplate(view: MapViewOrSceneView, templateInfo: FeatureTemplate | SharedTemplateMetadata): Promise<AnyLoadedEditingTemplate | null>;

/**
 * Create the set of attributes specified in a template
 *
 * @param template
 * @param overrides
 * @internal
 * @internal
 */
export function getCreationAttributes(template: FeatureTemplate | SharedTemplate | null | undefined, overrides?: Record<string, unknown>): Record<string, unknown>;

/**
 * Retrieves all standard and shared templates for the provided layers
 *
 * @param layers
 * @param view
 * @param signal
 * @param queryOptions
 * @internal
 * @internal
 */
export function getTemplatesForLayers(layers: LayerWithFeatureTemplatesUnion[], view?: View | null | undefined, signal?: AbortSignal, queryOptions?: Omit<QuerySharedTemplatesParameters, "layers">): Promise<LayerTemplateInfos[]>;