import type BinParametersBase from "./BinParametersBase.js";
import type DateBinTimeInterval from "./DateBinTimeInterval.js";
import type { BinParametersBaseProperties } from "./BinParametersBase.js";
import type { DateBinTimeIntervalProperties } from "./DateBinTimeInterval.js";

export interface DateBinParametersProperties extends BinParametersBaseProperties, Partial<Pick<DateBinParameters, "end" | "returnFullIntervalBin" | "snapToData" | "start">> {
  /** Defines a length of time in one of the temporal units such as `days`, `weeks`, or `years`. */
  interval?: DateBinTimeIntervalProperties;
  /**
   * Defines an offset to the bin's starting position. For example, with a bin unit of day and an offset of 12 hours, bins run from noon to noon.
   * The offset can be positive or negative.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * > Only `days`, `hours`, `minutes`, `seconds` are supported for offset [unit](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-DateBinTimeInterval.html#unit).
   * > The `offset` is only supported with server-side [FeatureLayers](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html).
   */
  offset?: DateBinTimeIntervalProperties | null;
}

/**
 * DateBinParameters specifies [AttributeBinsQuery#binParameters](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-AttributeBinsQuery.html#binParameters) on [AttributeBinsQuery](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-AttributeBinsQuery.html) object.
 * For date bins, the intervals are based on calendar units. For example, with monthly intervals, each bin corresponds to the full month. Date bins always start
 * at the beginning of the calendar unit, not at the first item in the dataset.
 *
 * When dates are binned, they start at the beginning of the temporal unit as follows:
 * * An hour starts at minute 00.
 * * A day starts at 12 a.m.
 * * A week starts on Sunday
 * * A month starts on the first day of the month
 * * A quarter starts on the first month of the quarter (January, April, July, or October).
 * * A year starts on January 1st.
 *
 * For example, if you want to get the total number of accidents in the USA by month for the year 2021, you can use the following bin parameters:
 *
 * ```js
 * // Query total accidents in the USA by month for the year 2021.
 * // TSODate field values are used to bin the data into monthly intervals.
 * // Request the binning results in pacific time zone.
 * const binQuery = new AttributeBinsQuery({
 *   binParameters: new DateBinParameters({
 *     field: "TSODate", // timestamp-offset field containing the date of each accident
 *     start: "2021-01-01T00:00:00+00:00", // the lower boundary of the first bin
 *     end: "2021-12-31T00:00:00+00:00", // the upper boundary of the last bin
 *     interval: { // the interval size for each bin. One month
 *       value: 1,
 *       units: "months"
 *     }
 *   }),
 *   outTimeZone: "America/Los_Angeles", // Get the binning results in pacific time zone
 * });
 * ```
 *
 * <figure>
 *   <img src="https://developers.arcgis.com/javascript/latest/assets/img/apiref/rest/binQuery/date-bin.png" alt="color-blend" style="width:400px;"/>
 *   <figcaption>Total accidents in the USA by month for the year 2021. Each bin represents the number of accidents that occurred during each month. The results are presented in Pacific time zone. The chart is based on the results of the binQuery shown above.</figcaption>
 * </figure>
 *
 * @since 4.32
 * @see [AttributeBinsQuery](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-AttributeBinsQuery.html)
 * @see [Sample - Attribute Bins Query](https://developers.arcgis.com/javascript/latest/sample-code/query-attribute-bins/)
 */
export default class DateBinParameters extends BinParametersBase {
  constructor(properties?: DateBinParametersProperties);
  /** The end date value for bins to generate. ISO date strings can be passed when the bin field is `timestamp-offset`, `date-only`, and `time-only` field. */
  accessor end: string | number | Date | null | undefined;
  /** Defines a length of time in one of the temporal units such as `days`, `weeks`, or `years`. */
  get interval(): DateBinTimeInterval;
  set interval(value: DateBinTimeIntervalProperties);
  /**
   * Defines an offset to the bin's starting position. For example, with a bin unit of day and an offset of 12 hours, bins run from noon to noon.
   * The offset can be positive or negative.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * > Only `days`, `hours`, `minutes`, `seconds` are supported for offset [unit](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-DateBinTimeInterval.html#unit).
   * > The `offset` is only supported with server-side [FeatureLayers](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html).
   */
  get offset(): DateBinTimeInterval | null | undefined;
  set offset(value: DateBinTimeIntervalProperties | null | undefined);
  /**
   * Indicates whether the last bin should match the specified interval size exactly. When set to `false`, the last bin may have a different interval size than the others.
   * For example, if the bins are set to a monthly interval, the last bin could be shorter than a full month if the end date doesn’t align with the end of the month.
   * When set to `true`, all bins will have the same interval size, including the first and last bins. For example, if the bins are set to a monthly interval and
   * `returnFullIntervalBin` is set to `true`, the first and last bins will have a full month interval. This means that even if the first or last date doesn’t align perfectly
   * with the start or end of the month, the first bin will start from the beginning of the month, and the last bin will cover the full month, potentially extending beyond the
   * actual data range to ensure consistent bin sizes.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * > The `returnFullIntervalBin` is only supported with server-side [FeatureLayers](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html).
   *
   * @default false
   */
  accessor returnFullIntervalBin: boolean;
  /**
   * This property determines how the bins are aligned relative to the data points. It can be set to either the `first` or `last` data point.
   * When set to `first`, the binning will start from the earliest date in your dataset and move forward in time.
   * When set to `last`, the binning will start from the most recent date and move backward in time.
   * For example, if the bins are set to a monthly interval and the data starts on January 18th:
   *  - When `snapToData` is set to `first`: The binning starts from the earliest date in the dataset and progresses forward in time.
   * Each bin will cover a full month. However, the last bin may not be a full month if the end date does not align perfectly with the interval.
   *  - When `snapToData` is set to `last`: The binning starts from the most recent date in the dataset and moves backward in time. Each bin will cover a full month.
   * However, the first bin may not be a full month if the start date does not align perfectly with the interval.
   *
   * @see [Time binning](https://doc.arcgis.com/en/arcgis-online/create-maps/line-chart-mv.htm#ESRI_SECTION2_84DA22621BD042E48A5972C8CD7D0403)
   */
  accessor snapToData: "first" | "last" | null | undefined;
  /** The start date value for bins to generate. ISO date strings can be passed when the bin field is `timestamp-offset`, `date-only`, and `time-only` field. */
  accessor start: string | number | Date | null | undefined;
  /** The type of bin parameters. */
  readonly type: "date";
}