import type Accessor from "../../core/Accessor.js";
import type PortalItem from "../../portal/PortalItem.js";
import type LegendLayer from "./LegendLayer.js";
import type { PrintFileFormat, PrintLayoutTemplate, PrintReportTemplate } from "./types.js";
import type { PortalItemProperties } from "../../portal/PortalItem.js";

export interface PrintTemplateProperties extends Partial<Pick<PrintTemplate, "attributionVisible" | "exportOptions" | "forceFeatureAttributes" | "format" | "includeCharts" | "includeTables" | "layout" | "layoutOptions" | "outScale" | "report" | "reportOptions" | "scalePreserved" | "showLabels">> {
  /**
   * A custom layout hosted as a [portal item](https://developers.arcgis.com/javascript/latest/references/core/portal/PortalItem/). To use this property, the print service
   * must be hosted on an ArcGIS Server that is federated with the same portal as the portal item.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > This capability is only available with ArcGIS Enterprise 11.1 or later.
   *
   * @since 4.25
   * @see [Share custom layouts for printing from ArcGIS Pro](https://enterprise.arcgis.com/en/server/latest/publish-services/windows/tutorial-publish-additional-layouts-for-printing-with-arcgis-pro.htm)
   * @see [Federate an ArcGIS Server site with your portal](https://enterprise.arcgis.com/en/portal/latest/administer/windows/federate-an-arcgis-server-site-with-your-portal.htm)
   * @example
   * let item = new PortalItem({
   *   id: "affa021c51944b5694132b2d61fe1057"
   * });
   *
   * // specify your own print service
   * const printURL = "https://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task";
   *
   * const template = new PrintTemplate({
   *   layoutItem: item
   * });
   * const params = new PrintParameters({
   *   view,
   *   template
   * });
   *
   * print.execute(printURL, params).then(printResult, printError);
   */
  layoutItem?: PortalItemProperties | null;
  /**
   * A custom report template hosted as a [portal item](https://developers.arcgis.com/javascript/latest/references/core/portal/PortalItem/) for report printing.
   * Also requires a value to be set for [reportOptions](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#reportOptions) to print.
   *
   * To use this property, the print service must be hosted on an ArcGIS Server that is federated with the same portal as the portal item.
   * If this property is set, it will take precedence over the [report](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#report) property.
   *
   * Typically, a report will be printed with a map in a multi-page `pdf` file, but the [layout](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#layout) property
   * must be set to something other than `map-only` for the map to be printed with the report.
   * To only print a report without a map, set the appropriate value for [reportItem](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#reportItem), and either set [layout](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#layout) to `map-only`,
   * or do not set a value for `layout`. A value is not required for `layout` since it defaults to `map-only`.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > Currently, reports can only be printed in `pdf` format.
   * > The print template and the print service must be configured to support reports.
   * > This capability is only available with ArcGIS Enterprise version 11.2 or later.
   *
   * @since 4.28
   * @see [report](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#report)
   * @see [reportOptions](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#reportOptions)
   * @see [Reports in ArcGIS Pro](https://pro.arcgis.com/en/pro-app/latest/help/reports/reports-in-arcgis-pro.htm)
   * @see [Blog: Print reports from ArcGIS Enterprise web apps](https://www.esri.com/arcgis-blog/products/arcgis-enterprise/mapping/print-reports-from-arcgis-enterprise-web-apps/)
   * @example
   * const template = new PrintTemplate({
   *   layout: "map-only",
   *   format: "pdf",
   *   reportItem: {id: "9a7aefd5bcd24bf7891264e0c5ecgbb8"},
   *   reportOptions: {}
   * });
   */
  reportItem?: PortalItemProperties | null;
}

export interface ExportOption {
  /**
   * Map width. Default value is 800. If the `dpi` value is modified,
   * then the `width` and `height` will be modified proportional to the `dpi` change.
   * If the `width` value is modified independently, the `dpi` and `height` values will not be modified.
   */
  width?: number;
  /**
   * Map height. Default value is 1100. If the `dpi` value is modified,
   * then the `width` and `height` will be modified proportional to the `dpi` change.
   * If the `height` value is modified independently, the `dpi` and `width` values will not be modified.
   */
  height?: number;
  /**
   * Resolution in dots per inch. Default value is 96.
   * If the `dpi` value is modified, then the `width` and `height` will be modified proportional to the `dpi` change.
   */
  dpi?: number;
}

export interface LayoutOption {
  /** The text used for the author if the specified layout contains an author text element. */
  authorText?: string | null;
  /** The text used for the copyright if the specified layout contains a copyright text element. */
  copyrightText?: string | null;
  /**
   * An array of name-value pair objects. Use this property to update the text for custom text elements
   * on the page layout. Values must be strings. The custom text elements must exist in the print service. All out-of-the-box print service layout
   * templates contain a text element named `date` that gets populated by default with the system date-time, but can be overwritten.
   */
  customTextElements?: Record<string, string>[] | null;
  /** An object containing optional elements from the print service that can be updated. */
  elementOverrides?: object | null;
  /**
   * An array of [LegendLayer](https://developers.arcgis.com/javascript/latest/references/core/rest/support/LegendLayer/)
   * containing the ids of the layers that will be included in the legend. [GraphicsLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/GraphicsLayer/) will not appear in the
   * legend. If `legendLayers` is not specified, all layers where `legendEnabled` is `true`, except GraphicsLayer,
   * will be present in the legend. To specify that no layers will be included in the legend, set `legendLayer = []`.
   */
  legendLayers?: LegendLayer[] | null;
  /**
   * The unit used for the scalebar.
   *
   * @default Miles
   */
  scalebarUnit?: "Miles" | "Kilometers" | "Meters" | "Feet" | null;
  /** The text used for the map title if the specified layout contains a title text element. */
  titleText?: string | null;
}

/**
 * Defines the layout template options used by [print](https://developers.arcgis.com/javascript/latest/references/core/rest/print/)
 * and the [PrintViewModel.print()](https://developers.arcgis.com/javascript/latest/references/core/widgets/Print/PrintViewModel/#print)
 * method to generate the print page.
 *
 * @since 4.20
 */
export default class PrintTemplate extends Accessor {
  constructor(properties?: PrintTemplateProperties);
  /**
   * When `false`, the attribution is not displayed on the printout.
   * This only applies when the [layout](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#layout) value is `map-only`.
   * Reference our policies on [Licensing & Attribution](https://developers.arcgis.com/javascript/latest/licensing/) for specific attribution requirements.
   *
   * @default true
   */
  accessor attributionVisible: boolean;
  /**
   * Define the map width, height and dpi. Required when `layout = 'map-only'`. See the object specification
   * table below for available options to set for exportOptions.
   */
  accessor exportOptions: ExportOption;
  /**
   * When true, the feature's attributes are included in feature collection layers even when they are not needed for
   * rendering. By default they are removed to reduce the request size. Only applicable to custom print services
   * which use the feature attributes, for example to display a table of features and their attributes.
   *
   * @default false
   */
  accessor forceFeatureAttributes: boolean;
  /**
   * The output format for the printed map.
   *
   * @default "png32"
   */
  accessor format: PrintFileFormat;
  /**
   * When `true`, charts will be included in the printout request.
   * Charts are stored inside an operational layer definition.
   *
   * Use this property with [layoutOptions.elementOverrides](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#layoutOptions).
   * The required properties are: `elementName`, `sourceChartId`, `sourceLayerId`.
   *
   * The `elementName` can be found from the `Get Layout Templates Info` task on the GPServer.
   * The `sourceChartId` can be found in the `id` property of the `charts` property of the operational layer.
   * The `sourceLayerId` can be found in the `id` property of the operational layer.
   * The default value of the `visible` property can be found from the `Get Layout Templates Info` task on the GPServer. This must be set to `true` for the printed charts to display if the default is `false`.
   * Lastly, the `filterType` property is read from the `Get Layout Templates Info` task on the GPServer and does not require a value, but it can also be overwritten. Possible values are: `all`, `visible`, and `selected`.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > The print template must be configured to support charts.
   * > This capability is only available with ArcGIS Server version 11.2 or later.
   * > Currently, charts can only be printed when published as part of a [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/) hosted on ArcGIS Enterprise.
   *
   * @default false
   * @since 4.28
   * @see [Make a chart](https://pro.arcgis.com/en/pro-app/latest/help/analysis/geoprocessing/charts/make-a-chart.htm)
   * @see [Configure charts](https://enterprise.arcgis.com/en/portal/latest/use/configure-charts-mv.htm)
   * @example
   * const template = new PrintTemplate({
   *   layout: "A4 Portrait with Chart",
   *   format: "png32",
   *   includeCharts: true,
   *   layoutOptions: {
   *     elementOverrides: {
   *        "line_chart_frame_1": {
   *           "sourceLayerId": "188dad6022b4-layer-2",
   *           "sourceChartId": "Chart 168786106706"
   *        },
   *        "bar_chart_frame_2": {
   *           "sourceLayerId": "188dad6022b4-layer-2",
   *           "sourceChartId": "Chart 168786109405"
   *        }
   *     }
   *   }
   * });
   */
  accessor includeCharts: boolean;
  /**
   * When `true`, tables will be included in the printout request.
   * A table is a non-spatial dataset in a feature service or map service.
   *
   * Note that for the table to display in the printout, the print
   * template must be configured to support tables.
   *
   * @default false
   * @since 4.26
   * @see [Map.tables](https://developers.arcgis.com/javascript/latest/references/core/Map/#tables)
   * @see [FeatureLayer.isTable](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#isTable)
   */
  accessor includeTables: boolean;
  /**
   * The layout used for the print output. When the value is `map-only` or is empty, the output map does not contain any page layout
   * surroundings (for example, title, legend, scale bar and so forth). The print service provides out-of-the-box templates listed in possible values.
   * The server administrator can add additional templates to the print service.
   *
   * Possible values are listed below:
   * Value | Description
   * | --- | ---
   * map-only | Map does not contain any layout elements. Only map image is printed.
   * a3-landscape | A3 Landscape
   * a3-portrait | A3 Portrait
   * a4-landscape | A4 Landscape
   * a4-portrait | A4 Portrait
   * letter-ansi-a-landscape | Letter ANSI A Landscape
   * letter-ansi-a-portrait | Letter ANSI A Portrait
   * tabloid-ansi-b-landscape| Tabloid ANSI B Landscape
   * tabloid-ansi-b-portrait | Tabloid ANSI B Portrait
   *
   * @default "map-only"
   */
  accessor layout: PrintLayoutTemplate | null | undefined;
  /**
   * A custom layout hosted as a [portal item](https://developers.arcgis.com/javascript/latest/references/core/portal/PortalItem/). To use this property, the print service
   * must be hosted on an ArcGIS Server that is federated with the same portal as the portal item.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > This capability is only available with ArcGIS Enterprise 11.1 or later.
   *
   * @since 4.25
   * @see [Share custom layouts for printing from ArcGIS Pro](https://enterprise.arcgis.com/en/server/latest/publish-services/windows/tutorial-publish-additional-layouts-for-printing-with-arcgis-pro.htm)
   * @see [Federate an ArcGIS Server site with your portal](https://enterprise.arcgis.com/en/portal/latest/administer/windows/federate-an-arcgis-server-site-with-your-portal.htm)
   * @example
   * let item = new PortalItem({
   *   id: "affa021c51944b5694132b2d61fe1057"
   * });
   *
   * // specify your own print service
   * const printURL = "https://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task";
   *
   * const template = new PrintTemplate({
   *   layoutItem: item
   * });
   * const params = new PrintParameters({
   *   view,
   *   template
   * });
   *
   * print.execute(printURL, params).then(printResult, printError);
   */
  get layoutItem(): PortalItem | null | undefined;
  set layoutItem(value: PortalItemProperties | null | undefined);
  /**
   * Defines the layout elements. It's an object with the following properties:
   *
   * @example
   * layoutOptions: {
   *   titleText: "My Print",
   *   authorText: "Sam",
   *   copyrightText: "My Company",
   *   scalebarUnit: "Miles",
   *   // the following text elements must
   *   // exist in the print service to appear
   *   customTextElements: [
   *     {"description": "My description"},
   *     {"location": "My Location"},
   *     {"date": "11/11/2020, 11:11:20 AM"}
   *   ],
   *   elementOverrides: {
   *     "North Arrow": {
   *       "visible": true
   *     }
   *   }
   * }
   */
  accessor layoutOptions: LayoutOption | null | undefined;
  /**
   * The optional map scale of the printed map. Only applies when `scalePreserved` is `true`.
   * If `outScale` is 0, then the printed map will use the scale of the input map.
   *
   * @default 0
   */
  accessor outScale: number;
  /**
   * The name of the report template. Also requires a value to be set for [reportOptions](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#reportOptions) to print.
   * Typically, a report will be printed with a map in a multi-page `pdf` file, but the [layout](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#layout) property
   * must be set to something other than `map-only` for the map to be printed with the report.
   *
   * There is no `report_only` template.
   * To only print a report without a map, set the appropriate value for [report](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#report), and either set [layout](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#layout) to `map-only`,
   * or do not set a value for `layout`. A value is not required for `layout` since it defaults to `map-only`.
   *
   * When publishing a print service with reports, the print service provides possible names for out-of-the-box report templates.
   * Possible values can be found from:
   * the report template parameter at the `Export Web Map` task on the GPServer,
   * the `Get Report Templates Info` task on the GPServer,
   * or from a custom report template hosted as a [portal item](https://developers.arcgis.com/javascript/latest/references/core/portal/PortalItem/) using [reportItem](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#reportItem).
   * If [reportItem](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#reportItem) property is set, [report](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#report) will be ignored.
   *
   * Some possible values are listed below:
   * Value | Description
   * | --- | ---
   * attribute-list-letter-ansi-a-landscape | "Attribute List Letter ANSI A Landscape"
   * attribute-list-letter-ansi-a-portrait | "Attribute List Letter ANSI A Portrait"
   * attribute-list-with-group-letter-ansi-a-landscape | "Attribute List With Group Letter ANSI A Landscape"
   * attribute-list-with-group-letter-ansi-a-portrait | "Attribute List With Group Letter ANSI A Portrait"
   * page-per-feature-letter-ansi-a-landscape | "Page per Feature Letter ANSI A Landscape"
   * page-per-feature-letter-ansi-a-portrait | "Page per Feature Letter ANSI A Portrait"
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > Currently, reports can only be printed in `pdf` format.
   * > The print template and the print service must be configured to support reports.
   * > This capability is only available with ArcGIS Server version 11.2 or later.
   *
   * @since 4.28
   * @see [reportItem](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#reportItem)
   * @see [reportOptions](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#reportOptions)
   * @see [Reports in ArcGIS Pro](https://pro.arcgis.com/en/pro-app/latest/help/reports/reports-in-arcgis-pro.htm)
   * @see [Blog: Print reports from ArcGIS Enterprise web apps](https://www.esri.com/arcgis-blog/products/arcgis-enterprise/mapping/print-reports-from-arcgis-enterprise-web-apps/)
   * @example
   * const template = new PrintTemplate({
   *   layout: "A4 Landscape",
   *   report: "Theme Parks A4 Landscape",
   *   format: "pdf",
   *   reportOptions: {}
   * });
   */
  accessor report: PrintReportTemplate | null | undefined;
  /**
   * A custom report template hosted as a [portal item](https://developers.arcgis.com/javascript/latest/references/core/portal/PortalItem/) for report printing.
   * Also requires a value to be set for [reportOptions](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#reportOptions) to print.
   *
   * To use this property, the print service must be hosted on an ArcGIS Server that is federated with the same portal as the portal item.
   * If this property is set, it will take precedence over the [report](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#report) property.
   *
   * Typically, a report will be printed with a map in a multi-page `pdf` file, but the [layout](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#layout) property
   * must be set to something other than `map-only` for the map to be printed with the report.
   * To only print a report without a map, set the appropriate value for [reportItem](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#reportItem), and either set [layout](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#layout) to `map-only`,
   * or do not set a value for `layout`. A value is not required for `layout` since it defaults to `map-only`.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > Currently, reports can only be printed in `pdf` format.
   * > The print template and the print service must be configured to support reports.
   * > This capability is only available with ArcGIS Enterprise version 11.2 or later.
   *
   * @since 4.28
   * @see [report](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#report)
   * @see [reportOptions](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#reportOptions)
   * @see [Reports in ArcGIS Pro](https://pro.arcgis.com/en/pro-app/latest/help/reports/reports-in-arcgis-pro.htm)
   * @see [Blog: Print reports from ArcGIS Enterprise web apps](https://www.esri.com/arcgis-blog/products/arcgis-enterprise/mapping/print-reports-from-arcgis-enterprise-web-apps/)
   * @example
   * const template = new PrintTemplate({
   *   layout: "map-only",
   *   format: "pdf",
   *   reportItem: {id: "9a7aefd5bcd24bf7891264e0c5ecgbb8"},
   *   reportOptions: {}
   * });
   */
  get reportItem(): PortalItem | null | undefined;
  set reportItem(value: PortalItemProperties | null | undefined);
  /**
   * This object links the various report elements to their data source.
   * To be used with a valid [report](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#report) or [reportItem](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#reportItem) value.
   *
   * This property requires the developer to know the names and values of the report elements and their data sources, as well as how they are organized in the report template.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > Currently, reports can only be printed in `pdf` format.
   * > The print template and the print service must be configured to support reports.
   * > This capability is only available with ArcGIS Server version 11.2 or later.
   *
   * @since 4.28
   * @see [report](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#report)
   * @see [reportItem](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PrintTemplate/#reportItem)
   * @see [Reports in ArcGIS Pro](https://pro.arcgis.com/en/pro-app/latest/help/reports/reports-in-arcgis-pro.htm)
   * @see [Blog: Print reports from ArcGIS Enterprise web apps](https://www.esri.com/arcgis-blog/products/arcgis-enterprise/mapping/print-reports-from-arcgis-enterprise-web-apps/)
   * @example
   * const template = new PrintTemplate({
   *   layout: "A4 Landscape",
   *   report: "Theme Parks A4 Landscape",
   *   format: "pdf",
   *   reportOptions: {
   *     "reportSectionOverrides": {
   *       "Related Report": {
   *         "fieldElements": {
   *           "Related Field 1":"AttractionName",
   *           "Related Field 2":"Description"
   *         },
   *         "fieldLabelElements": {
   *           "Related Field Label 1":"Name",
   *           "Related Field Label 2":"Description"
   *          },
   *          "groupSections": {
   *            "[related-report-name]: Group Header: [group-field-value]":"AttractionType"
   *          },
   *          "relatedId":"R0L1Parks_ReportL0_ReportBase",
   *          "sourceId":"18a86753b0-layer-2"
   *       },
   *       "Report Section":{
   *         "fieldElements":{
   *           "Field 1":"Website",
   *           "Field 2":"City",
   *           "Field 3":"State",
   *           "Field 4":"OpeningTime",
   *           "Field 5":"ChildPrice",
   *           "Field 6":"AdultPrice"
   *         },
   *         "groupSections":{
   *           "Group field: [group-field-value]":"Name"
   *         },
   *         "name":"USA Theme Parks",
   *         "sourceId":"12a387780ai-layer-1",
   *         "statisticElements":{
   *           "Count Statistic 1":"Name"
   *         }
   *       }
   *     }
   *   }
   * });
   */
  accessor reportOptions: Object | null | undefined;
  /**
   * Define whether the printed map should preserve map scale or map extent. If `true`, the printed map will use the `outScale`
   * property or default to the scale of the input map. If `false`, the printed map will use the same extent as the input map and
   * thus scale might change.
   *
   * @default true
   */
  accessor scalePreserved: boolean;
  /**
   * When `true`, labels will be shown on the layout.
   *
   * @default true
   */
  accessor showLabels: boolean;
}