import type Accessor from "../../../core/Accessor.js";
import type VisibleElements from "../VisibleElements.js";
import type { Icon } from "@esri/calcite-components/components/calcite-icon";
import type { TimeZone } from "../../../time/types.js";
import type { TextAlign, ColumnTableMenuConfig, Direction } from "./types.js";
import type { FormatFunction } from "../support/types.js";

export interface ColumnProperties extends Partial<Pick<Column, "autoWidth" | "description" | "direction" | "flexGrow" | "hidden" | "icon" | "iconText" | "label" | "labelTooltipText" | "sortable" | "textAlign" | "textWrap" | "timeZone" | "topLayerDisabled" | "visibleElements" | "width">> {
  /** The unique field name as defined by the data source. */
  fieldName?: string;
  /** Indicates the initial sort priority of the column when first rendered. */
  initialSortPriority?: number | null;
  /** Indicates whether the column is in an invalid state. */
  invalid?: boolean | null;
}

/**
 * The `Column` class works with the [FeatureTable](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/) and provides much of the underlying logic for column behavior. `Column` and its subclasses, ie. [FieldColumn](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/FieldColumn/), [GroupColumn](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/GroupColumn/), [ActionColumn](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/ActionColumn/), [AttachmentsColumn](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/AttachmentsColumn/), and [RelationshipColumn](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/RelationshipColumn/),  contain information about the current table state after it has been rendered. This includes the column's header, cell content, and any associated menu items.
 *
 * > [!WARNING]
 * >
 * > This class should be used for observing potential changes. Any configuration and changes to the
 * > columns should be handled via the [TableTemplate](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/support/TableTemplate/) and the [ColumnTemplate](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/support/ColumnTemplate/) class.
 *
 * @since 4.30
 * @see [FeatureTable](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/)
 * @see [FeatureTableViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/FeatureTableViewModel/)
 * @see [ColumnTemplate](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/support/ColumnTemplate/)
 */
export default class Column extends Accessor {
  constructor(properties?: ColumnProperties);
  /**
   * Indicates if the column width will automatically adjust to account for large content.
   * The column ignores the current [width](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#width) property when `autoWidth` is `true`.
   *
   * @default false
   */
  accessor autoWidth: boolean;
  /** Contains information describing the purpose of each column. */
  accessor description: string | null | undefined;
  /**
   * Controls the sort order of the column. This property will only be honored on one column in the FeatureTable widget.
   * If direction is specified on more than one column in the same FeatureTable,
   * it will only be honored on the column with the highest index.
   *
   * This is used in combination with the [initialSortPriority](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#initialSortPriority) and [FeatureTable.multiSortEnabled](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/#multiSortEnabled) properties to set sorting functionality for multiple columns.
   *
   * Possible Value | Description
   * ---------------|------------
   * asc | Sorts the column in ascending order.
   * desc | Sorts the column in descending order.
   * null | No sort is applied to the column.
   *
   * @see [FeatureTable.multiSortEnabled](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/#multiSortEnabled)
   * @see [initialSortPriority](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#initialSortPriority)
   */
  accessor direction: Direction;
  /**
   * The sanitized [description](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#description) string, describing the purpose of each column.
   *
   * @since 4.31
   */
  get effectiveDescription(): string | null | undefined;
  /**
   * The sanitized [label](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#label) string safe for display in the header cell. Defaults to
   * using [fieldName](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#fieldName) if a [label](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#label) is not defined on the column.
   */
  get effectiveLabel(): string;
  /** The unique field name as defined by the data source. */
  get fieldName(): string;
  /**
   * Controls the [flex-grow](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow) property for the column. When set to `0`, cell width is fixed.
   *
   * @default 1
   */
  accessor flexGrow: number;
  /**
   * Custom function for rendering cell content that is called when the column is rendered in the table. The function should return the formatted content to display within a table's cell. This can be a string, number, an HTML element, or equivalent node type (e.g. a [Calcite component](https://developers.arcgis.com/calcite-design-system/components/)). If the content is an HTML element, it is appended to the root element. If the content is a string or number, it is set as the `innerHTML` of the root element. If the content is `null`, the root element is cleared. If the content is `undefined`, the root element is not modified. This property is useful when you want to customize the cell content. For example, you can use this property to create a custom cell renderer that displays a progress bar in the cell. The progress bar can be used to show the progress of a task.
   *
   * @example
   * // The following example demonstrates how to use the formatFunction property to create a custom cell renderer that displays a progress bar in the cell. The progress bar can be used to show the progress of a task.
   * column.formatFunction = ({ column, feature, index, value })=> {
   *   const progress = document.createElement("progress");
   *   progress.max = 100;
   *   progress.value = value;
   *   return progress;
   * };
   */
  get formatFunction(): FormatFunction | null | undefined;
  /**
   * Indicates if the the column is frozen in place at the beginning of the table.
   * Column must be first in the FeatureTable's [column's](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/#columns), or next to other frozen columns.
   *
   * @default false
   */
  get frozen(): boolean;
  /**
   * Indicates if the column is frozen in place at the end of the table.
   * Column must be last in the FeatureTable's [column's](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/#columns), or next to other columns with `frozenToEnd` set to `true`.
   *
   * @default false
   */
  get frozenToEnd(): boolean;
  /**
   * Indicates whether the column is visible.
   *
   * @default false
   */
  accessor hidden: boolean;
  /**
   * The string value indicating the [icon](https://developers.arcgis.com/calcite-design-system/icons/) displayed in the header cell of the column.
   *
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   */
  accessor icon: Icon["icon"] | null | undefined;
  /**
   * The string value displayed when hovering over the associated [icon](https://developers.arcgis.com/calcite-design-system/icons/) displayed in the header cell of the column.
   * When a value is not provied, the column label is displayed instead. A value for 'icon' must also be set on the column.
   *
   * @since 4.32
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   */
  accessor iconText: string | null | undefined;
  /** Indicates the initial sort priority of the column when first rendered. */
  get initialSortPriority(): number | null | undefined;
  /** Indicates whether the column is in an invalid state. */
  get invalid(): boolean;
  set invalid(value: boolean | null | undefined);
  /** The default label displayed in the column header cell. */
  accessor label: string | null | undefined;
  /**
   * Text displayed when hovering over the column header label.
   * Defaults to the typical column label when a value is not provided.
   */
  accessor labelTooltipText: string | null | undefined;
  /** The element representing the field column's menu. */
  get menu(): HTMLElement;
  /**
   * Configuration options for the column's menu.
   *
   * [FeatureTable.tableTemplate](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/#tableTemplate).
   */
  get menuConfig(): ColumnTableMenuConfig | null | undefined;
  /**
   * Indicates whether the column's menu is currently open.
   *
   * @since 4.30
   */
  get menuIsOpen(): boolean;
  /**
   * Indicates whether the Column's menu will be displayed.
   *
   * @since 4.30
   */
  get menuIsVisible(): boolean;
  /**
   * Indicates whether the column is resizable.
   *
   * @default true
   */
  get resizable(): boolean;
  /**
   * Indicates whether the column is sortable.
   *
   * @default false
   */
  accessor sortable: boolean;
  /**
   * The [FeatureTable.timeZone](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/#timeZone) of the parent table widget.
   *
   * @since 4.31
   */
  get tableTimeZone(): TimeZone | null | undefined;
  /**
   * Aligns the columns cell content horizontally.
   *
   * @default "start"
   */
  accessor textAlign: TextAlign;
  /**
   * Indicates cell content should be wrapped and displayed on multiple lines within the cell.
   * Warning: this causes rows to expand when tall content is visible in the viewport.
   * Scrolling tall cells into the viewport may cause the table to visually jump depending on the height of the expanding rows.
   *
   * @default false
   */
  accessor textWrap: boolean;
  /**
   * The [storage IANA time zone](https://www.iana.org/time-zones) of the column.
   *
   * @see [Wikipedia - List of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
   * @see [Date-time queries | Time zone properties](https://developers.arcgis.com/rest/services-reference/enterprise/query-feature-service-layer/#time-zone-properties)
   */
  accessor timeZone: TimeZone | null | undefined;
  /**
   * @default false
   * @internal
   */
  accessor topLayerDisabled: boolean;
  /** The [visible elements](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/VisibleElements/) of the column's associated FeatureTable. */
  accessor visibleElements: VisibleElements | null | undefined;
  /**
   * Width of the column in pixels. If providing value as a string, the string must include `"px"` suffix.
   * This value is only honored when there are enough columns to fill the viewport, or [flexGrow](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#flexGrow) has been set to `0`.
   *
   * @default 200
   */
  accessor width: number | string;
  /**
   * Convenience method for closing the column menu.
   *
   * @see [openMenu()](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#openMenu)
   * @see [FeatureTable.visibleElements.columnMenus](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/VisibleElements/)
   */
  closeMenu(): void;
  /**
   * Convenience method for opening the column menu. This has no effect if the menu is not visible or has no menu items.
   * It follows the [direction](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#direction) pattern of ascending, to descending, then no sort order.
   *
   * @see [direction](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#direction)
   * @see [closeMenu()](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#closeMenu)
   * @see [FeatureTable.visibleElements.columnMenus](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/VisibleElements/)
   */
  openMenu(): void;
  /**
   * Convenience method for sorting the current column. It has no effect if the column is not [sortable](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#sortable).
   *
   * @see [initialSortPriority](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTable/Grid/Column/#initialSortPriority)
   */
  sort(): void;
}