import { AdaptableForm } from '../AdaptableState/Common/AdaptableForm';
import { FormContext } from '../AdaptableState/Common/FormContext';
import { Report, ReportColumn, ReportData, ReportFormatType, ReportNameType, SystemReportFormat, SystemReportName } from '../AdaptableState/ExportState';
import { AdaptableColumn, BaseContext, AdaptableColumnContext } from '../types';
import { TypeHint } from '../AdaptableState/Common/Types';
import { CsvCell, ExcelCell, ExcelDataType, ExcelRow, IRowNode } from 'ag-grid-enterprise';
/**
 * Options regarding Exporting data from AdapTable
 */
export interface ExportOptions<TData = any> {
    /**
     * Sets 'rawValue' or 'formattedValue' as Data format in Reports; can be set for whole grid, per Data Type, or per Column (via a function)
     *
     * @defaultValue rawValue
     */
    exportDataFormat?: DataFormatType | DataFormatDataType | ((context: AdaptableColumnContext<TData>) => DataFormatType);
    /**
     * Optional custom format for Date columns when exporting
     *
     * @defaultValue undefined
     * @gridInfoItem
     */
    exportDateFormat?: string;
    /**
     * User-provided Report Destinations (in addition to those shipped in AdapTable)
     */
    customDestinations?: CustomDestination[];
    /**
     * System Reports to use; leave blank for all, empty array for none
     *
     * @defaultValue  'All Data', 'Current Layout', 'Selected Data',
     * @gridInfoItem
     */
    systemReportNames?: SystemReportName[];
    /**
     * System Report Formats to use; leave blank for all, empty array for none
     *
     * @defaultValue 'Excel', 'VisualExcel', 'CSV', 'JSON'
     * @gridInfoItem
     */
    systemReportFormats?: SystemReportFormat[];
    /**
     * Export destinations to use; leave blank for all, empty array for none
     *
     * @defaultValue 'Download', 'Clipboard'
     * @gridInfoItem
     */
    systemExportDestinations?: SystemExportDestination[];
    /**
     * Whether to add a timestamp as a suffix to exported file name
     *
     * @defaultValue false
     * @gridInfoItem
     */
    appendFileTimestamp?: boolean;
    /**
     * Provide a bespoke file name for the Report
     * @param reportFileNameContext context about report being run
     */
    reportFilename?: (reportFileNameContext: ReportFileNameContext) => string;
    /**
     * Whether a Column is included in System Reports and available in UI for selection
     * @defaultValue true
     */
    isColumnExportable?: (context: AdaptableColumnContext) => boolean;
    /**
     * Separator for CSV exports
     *
     * @defaultValue ','
     * @gridInfoItem
     */
    csvSeparator?: string | ((csvSeparatorContext: BaseExportContext) => string);
    /**
     * Whether to exclude Column Headers from the exported data
     * @defaultValue false
     */
    skipColumnHeaders?: boolean | ((skipColumnHeadersContext: BaseExportContext) => boolean);
    /**
     * Function to provide the Detail Rows when exporting in Master-Detail grids. This function will be invoked for each master row node.
     */
    getDetailRows?: (context: GetDetailRowsContext<TData>) => CsvDetailRow[] | ExcelDetailRow[] | undefined;
    /**
     * Provides custom handling of the Export process before the default export is executed.
     *
     * @returns A Promise resolving to one of:
     *   - `true` - Continue with the default export process
     *   - `false` - Cancel the export process
     *   - `ExportResultData` - Custom export data (useful for server-side data)
     */
    processExport?: (processExportContext: ProcessExportContext) => Promise<ExportResultData | boolean>;
}
/**
 * Detail Row Data in a CSV format; technically an array of AG Grid {@link https://www.ag-grid.com/javascript-data-grid/csv-export/#csvcell | CsvCell}s
 */
export type CsvDetailRow = CsvCell[];
/**
 * Detail Row Data in a Excel format; technically an equivalent of AG Grid's {@link https://www.ag-grid.com/javascript-data-grid/excel-export-api/#reference-ExcelExportParams-getCustomContentBelowRow | ExcelRow}
 */
export type ExcelDetailRow = ExcelRow;
/**
 * Context provided to `ExportOptions.getDetailRows()` callback used when exporting Detail Rows
 */
export interface GetDetailRowsContext<TData = any> extends BaseExportContext {
    /**
     * Master Row Node
     */
    masterRowNode: IRowNode<TData>;
    /**
     * Data of Master Row Node
     */
    masterRowData: TData;
    /**
     * Column of Master Row Node
     */
    adaptableColumn: AdaptableColumn<TData>;
    /**
     * Whether the Master Row Node is expanded
     */
    isExpanded: boolean;
    /**
     * Factory function to create an Header Cell (either CSV or Excel)
     */
    createCellHeader: (cellContent: any) => ExcelCell;
    /**
     * Factory function to create a CSV Cell
     */
    createCellCsv: (cellContent: any) => CsvCell;
    /**
     * Factory function to create an Excel Cell
     */
    createCellExcel: (cellContent: any, cellType: ExcelDataType) => ExcelCell;
}
/**
 * Format of exported Data - 'rawValue' or 'formattedValue'
 */
export type DataFormatType = 'rawValue' | 'formattedValue';
/**
 * Defines a custom Export destination
 */
export interface CustomDestination {
    /**
     * Name of Custom Destination (mandatory)
     */
    name: string;
    /**
     * Optional Adaptable Form; if provided, it must include Buttons that will execute the Export
     */
    form?: AdaptableForm<ExportFormContext>;
    /**
     * Optional Function invoked when Export is applied (used if no form is supplied)
     */
    onExport?: (reportContext: ReportContext) => void;
}
/**
 * Context required by functions when using an Export Button
 */
export interface ExportFormContext extends FormContext {
    /**
     * The exported report
     */
    report: Report;
    /**
     * The data in the report
     */
    reportData: ReportData;
    /**
     * Custom Export destination
     */
    customDestination: CustomDestination;
}
/**
 * Type of Export result data: string (CSV), ReportData (JSON), or Blob (Excel)
 */
export type ExportResultData = {
    type: 'csv';
    data: string;
} | {
    type: 'json';
    data: ReportData;
} | {
    type: 'excel';
    data: Blob | string;
};
/**
 * Export Destinations provided by AdapTable
 */
export type SystemExportDestination = 
/**
 * Download report to local machine
 */
'Download'
/**
 * Copy report to clipboard
 */
 | 'Clipboard';
/**
 * Configures which destination Reports get exported to
 */
export type ExportDestinationType = TypeHint<string, SystemExportDestination>;
/**
 * Context information available in all Export-related functions
 */
export interface BaseExportContext extends BaseContext {
    /**
     * Name of the Report being run
     */
    reportName: ReportNameType;
    /**
     * The Report Configuration being run
     */
    report: Report;
    /**
     * Format of the Report being run
     */
    reportFormat: ReportFormatType;
    /**
     * Export Destination for the Report
     */
    exportDestination?: ExportDestinationType;
}
/**
 * Report Context sent when using Custom Export Destinations
 */
export interface ReportContext extends BaseExportContext {
    /**
     * Export Data for the Report
     */
    reportData: ExportResultData;
}
/**
 * Context used by the processExport function
 */
export interface ProcessExportContext extends BaseExportContext {
    /**
     * Returns Columns to export based on Report's `ReportColumnScope`
     */
    getReportColumns: () => ReportColumn[];
    /**
     * Converts the Report Data to Excel format
     */
    convertToExcel: (reportData: ReportData) => Blob;
    /**
     * Converts the Report Data to CSV format
     */
    convertToCsv: (reportData: ReportData) => string;
}
/**
 * Context used for providing a custom filename for a Report
 */
export interface ReportFileNameContext extends BaseExportContext {
    /**
     * Default File Name to use
     */
    fileName: string;
}
/**
 * Defines the Format Data Types for all Data Types
 */
export interface DataFormatDataType {
    /**
     * Data Format type for String / Text columns
     */
    text?: DataFormatType;
    /**
     * Data Format type for Number columns
     */
    number?: DataFormatType;
    /**
     * Data Format type for Date columns
     */
    date?: DataFormatType;
}
