/**
 * Table template utilities for the map viewer application.
 *
 * @experimental
 * @internal
 */
import type CSVLayer from "../../layers/CSVLayer.js";
import type FeatureLayer from "../../layers/FeatureLayer.js";
import type GeoJSONLayer from "../../layers/GeoJSONLayer.js";
import type ImageryLayer from "../../layers/ImageryLayer.js";
import type SceneLayer from "../../layers/SceneLayer.js";
import type WFSLayer from "../../layers/WFSLayer.js";
import type CatalogFootprintLayer from "../../layers/catalog/CatalogFootprintLayer.js";
import type KnowledgeGraphSublayer from "../../layers/knowledgeGraph/KnowledgeGraphSublayer.js";
import type AttributeTableTemplate from "../../tables/AttributeTableTemplate.js";
import type TableTemplate from "../../widgets/FeatureTable/support/TableTemplate.js";
import type FeatureTable from "../../widgets/FeatureTable.js";
import type { FieldType } from "../../layers/support/types.js";
import type { FeatureTableSupportedLayer } from "../../widgets/FeatureTable/support/types.js";

/**
 * Syncs a provided AttributeTableTemplate with the current state of a provided FeatureTable, using the 'columns' Collection on FeatureTable specifically.
 * Replaces `elements` and `orderByFields` based on the table's current configuration.
 *
 * @param table - Table widget used to update the template.
 * @param template - Template to update with the provided table.
 * @param includeHiddenColumns - Indicates hidden columns should be included in orderByFields (defaults to true).
 * @returns The updated template.
 * @experimental
 * @internal
 */
export function syncAttributeTableTemplate(table: FeatureTable, template: AttributeTableTemplate, includeHiddenColumns?: boolean): AttributeTableTemplate;

/**
 * Generates an AttributeTableTemplate based on the default layer fields.
 * Similar to 'createPopupTemplate()' since this uses 'createFieldInfos()'.
 * Also loads the provided layer to ensure field information is correct.
 * Automatically includes elements for 'Attachments' and 'Relationships' if supported by the layer.
 *
 * @param options - Method parameters.
 * @returns Newly generated AttributeTableTemplate.
 * @experimental
 * @internal
 */
export function createDefaultAttributeTableTemplateFromLayer(options: CreateDefaultAttributeTableTemplateFromLayerOptions): Promise<AttributeTableTemplate>;

/**
 * @experimental
 * @internal
 */
export interface CreateDefaultAttributeTableTemplateFromLayerOptions {
  /**
   * Layer from which to generate a default template.
   *
   * @experimental
   */
  layer: CatalogFootprintLayer | CSVLayer | FeatureLayer | GeoJSONLayer | ImageryLayer | KnowledgeGraphSublayer | SceneLayer | WFSLayer;
  /**
   * Indicates 'attachment' columns should be excluded.
   *
   * @experimental
   */
  excludeAttachments?: boolean;
  /**
   * Indicates 'relationship' columns should be excluded.
   *
   * @experimental
   */
  excludeRelationships?: boolean;
  /**
   * Indicates field types that should be excluded. Defaults to: ["geometry", "blob", "raster", "guid", "xml"].
   *
   * @experimental
   */
  excludedFieldTypesOverride?: FieldType[];
}

/**
 * Generates a TableTemplate based on the default layer fields.
 * Similar to 'createPopupTemplate()' since this uses 'createFieldInfos()'
 * Also loads the provided layer to ensure field information is correct.
 * Automatically includes columns for Attachments and Relationships if supported by the layer.
 *
 * @param options - Method parameters.
 * @returns Newly generated TableTemplate.
 * @experimental
 * @internal
 */
export function createDefaultTableTemplateFromLayer(options: CreateDefaultTableTemplateFromLayerOptions): Promise<TableTemplate>;

/**
 * @experimental
 * @internal
 */
export interface CreateDefaultTableTemplateFromLayerOptions {
  /**
   * Layer from which to generate a default template.
   *
   * @experimental
   */
  layer: FeatureTableSupportedLayer;
  /**
   * Indicates 'attachment' columns should be excluded.
   *
   * @experimental
   */
  excludeAttachments?: boolean;
  /**
   * Indicates 'relationship' columns should be excluded.
   *
   * @experimental
   */
  excludeRelationships?: boolean;
  /**
   * Indicates field types that should be excluded. Defaults to: ["geometry", "blob", "raster", "guid", "xml"].
   *
   * @experimental
   */
  excludedFieldTypesOverride?: FieldType[];
}

/**
 * Generates a TableTemplate based on a pre-existing AttributeTableTemplate.
 * Accounts for column order, sort order, and visibility.
 * If 'includeHiddenFields is true, the resulting TableTemplate will contain column templates for
 * non-visible columns, so that the columns can be turned on in the UI. This is because non-visible
 * columns are not included in 'AttributeTableTemplate.elements'.
 *
 * @param parameters - Method parameters.
 * @returns Newly generated TableTemplate.
 * @experimental
 * @internal
 */
export function createTableTemplateFromAttributeTableTemplate(parameters: CreateTableTemplateFromAttributeTableTemplateParameters): Promise<TableTemplate>;

/**
 * @experimental
 * @internal
 */
export interface CreateTableTemplateFromAttributeTableTemplateParameters {
  /**
   * Layer from which to generate a default template.
   *
   * @experimental
   */
  layer: FeatureTableSupportedLayer;
  /**
   * Instance of an AttributeTableTemplate used to configure a new TableTemplate.
   *
   * @experimental
   */
  template: AttributeTableTemplate;
  /**
   * Indicates columns should be generated for fields without associated elements.
   *
   * @experimental
   */
  includeHiddenFields?: boolean;
  /**
   * Indicates field types that should be excluded. Defaults to: ["geometry", "blob", "raster", "guid", "xml"].
   *
   * @experimental
   */
  excludedFieldTypesOverride?: FieldType[];
}