declare module "@univerjs-pro/sheets-sparkline" {
  import type { IRange, ObjectMatrix } from "@univerjs/core";

  /**
   * Represents the configuration for a sparkline group.
   */
  interface ISparklineGroupConfig {
      /**
       * The type of sparkline
       */
      type?: SparklineTypeEnum;
      /**
       * The axis configuration of the sparkline
       */
      axis?: ISparklineAxisConfig;
      /**
       * The max extremum configuration of the sparkline
       */
      extremumMax?: ISparklineExtremumConfig;
      /**
       * The min extremum configuration of the sparkline
       */
      extremumMin?: ISparklineExtremumConfig;
      /**
       * The theme of the sparkline
       */
      themeType?: SparklineThemeTypeEnum;
      /**
       * How to display non-numeric values
       */
      nonNumShowAs?: SpacialShowAsEnum;
      /**
       * How to display empty values
       */
      emptyShowAs?: SpacialShowAsEnum;
      /**
       * Whether to display hidden cells
       */
      containHiddenCells?: boolean;
      /**
       * The color of the sparkline
       */
      seriesColor?: string;
      /**
       * The point configuration in sparklines
       */
      points?: ISparklinePoints;
      /**
       * The line width of the sparkline
       */
      lineWidth?: number;
      /**
       * Whether to display the gradient of the line chart
       */
      showGradient?: boolean;
      /**
       * Whether to display rounded corners of bar charts and profit and loss charts
       */
      showRadius?: boolean;
  }

  /**
   * Enumerates various sparkline theme types.
   */
  enum SparklineThemeTypeEnum {
      /**
       * Standard theme
       */
      STANDARD = "standard",
      /**
       * Specialty theme
       */
      SPECIALTY = "specialty",
      /**
       * Distinctive theme
       */
      DISTINCTIVE = "distinctive",
      /**
       * Soft theme
       */
      SOFT = "soft",
      /**
       * Fresh theme
       */
      FRESH = "fresh",
      /**
       * Custom theme
       */
      CUSTOM = "custom"
  }

  /**
   * Enumerates various sparkline types.
   */
  enum SparklineTypeEnum {
      /**
       * Line Sparkline
       */
      LINE_CHART = 1,
      /**
       * Bar Sparkline
       */
      BAR_CHART = 2,
      /**
       * Profit and Loss Sparkline
       */
      PROFIT_AND_LOSS_CHART = 3,
      /**
       * Pie Sparkline
       */
      PIE_CHART = 4
  }

  enum SpacialShowAsEnum {
      /**
       * Display as a spacing
       */
      SPACING = "spacing",
      /**
       * Display as a zero value
       */
      ZERO_VALUE = "zero_value",
      /**
       * Display as a connect with line
       */
      CONNECT_WITH_LINE = "connect_with_line"
  }

  interface ISparklinePoints {
      /**
       * The configuration of the high point
       */
      highPoint?: ISparklinePointConfig;
      /**
       * The configuration of the low point
       */
      lowPoint?: ISparklinePointConfig;
      /**
       * The configuration of the first point
       */
      firstPoint?: ISparklinePointConfig;
      /**
       * The configuration of the last point
       */
      lastPoint?: ISparklinePointConfig;
      /**
       * The configuration of the negative point
       */
      negativePoint?: ISparklinePointConfig;
      /**
       * The configuration of the markers point
       */
      markersPoint?: ISparklinePointConfig;
  }

  interface ISparklinePointConfig {
      /**
       * Display the point
       */
      visible?: boolean;
      /**
       * The color of the point
       */
      color?: string;
  }

  interface ISparklineAxisConfig {
      /**
       * The color of the axis
       */
      color?: string;
      /**
       * Display from right to left
       */
      reverse?: boolean;
      /**
       * Display the axis
       */
      visible?: boolean;
  }

  interface ISparklineExtremumConfig {
      /**
       * The type of extremum
       */
      type?: SparklineExtremumTypeEnum;
      value?: number;
  }

  enum SparklineExtremumTypeEnum {
      /**
       * Maximum value in a single sparkline
       */
      SELF_EXTREMUM = 1,
      /**
       * Maximum value in a group of sparklines
       */
      GROUP_EXTREMUM = 2,
      /**
       * Custom maximum value
       */
      CUSTOM_EXTREMUM = 3
  }

  /**
   * Represents a sparkline group.
   *
   * @property {ISparklineGroupConfig} config - The configuration for this sparkline group.
   * @property {ObjectMatrix<IRange>} sparklines - The matrix of defined ranges for this group.
   */
  interface ISparklineGroup {
      config: ISparklineGroupConfig;
      sparklines: ObjectMatrix<IRange>;
  }
}

declare module "@univerjs-pro/sheets-sparkline/facade" {
  import type { ISparklineGroup, ISparklineGroupConfig, SparklineTypeEnum } from "@univerjs-pro/sheets-sparkline";

  import type { IRange } from "@univerjs/core";

  /**
   * The facade class for the sparkline group.Which uses to setting multiple sparklines, all sparkline in the same group will share the configs.
   * @hideconstructor
   */
  class FSparklineGroup {
      /**
       * @description Modify the data source of the sparkline group
       * @param {IRange[]} sourceRanges Location of new data source
       * @param {IRange[]} targetRanges New placement
       * @returns {FSparklineGroup | undefined} Return this, for chaining
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Create a sparkline in the range A10, with the data source in the range A1:A7.
       * const sparkline = fWorksheet.addSparkline(
       *   [fWorksheet.getRange('A1:A7').getRange()],
       *   [fWorksheet.getRange('A10').getRange()]
       * );
       *
       * // Get sparkline group by cell A10
       * const sparklineGroup = fWorksheet.getSparklineGroupByCell(9, 0);
       *
       * setTimeout(() => {
       *   // Modify the data source of the sparkline group to the range B1:B7 after 3 seconds.
       *   sparklineGroup.changeDataSource(
       *     [fWorksheet.getRange('B1:B7').getRange()],
       *     [fWorksheet.getRange('A10').getRange()]
       *   );
       * }, 3000);
       * ```
       */
      changeDataSource(sourceRanges: IRange[], targetRanges: IRange[]): FSparklineGroup | undefined;
      /**
       * @description Delete the sparkline group
       * @returns {void}
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Create a sparkline in the range A10, with the data source in the range A1:A7.
       * const sparkline = fWorksheet.addSparkline(
       *   [fWorksheet.getRange('A1:A7').getRange()],
       *   [fWorksheet.getRange('A10').getRange()]
       * );
       *
       * // Get sparkline group by cell A10
       * const sparklineGroup = fWorksheet.getSparklineGroupByCell(9, 0);
       *
       * setTimeout(() => {
       *   // Remove sparkline group after 3 seconds.
       *   sparklineGroup.removeSparklineGroup();
       * }, 3000);
       * ```
       */
      removeSparklineGroup(): void;
      /**
       * @description Modify the configuration of the current sparkline group
       * @param {ISparklineGroupConfig} config new sparkline group config
       * @returns {FSparklineGroup} Return this instance, for chaining
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Create a sparkline in the range A10, with the data source in the range A1:A7.
       * const sparkline = fWorksheet.addSparkline(
       *   [fWorksheet.getRange('A1:A7').getRange()],
       *   [fWorksheet.getRange('A10').getRange()]
       * );
       *
       * // Get sparkline group by cell A10
       * const sparklineGroup = fWorksheet.getSparklineGroupByCell(9, 0);
       *
       * // Set sparkline type to bar chart after 3 seconds
       * setTimeout(() => {
       *   sparklineGroup.setConfig({
       *     type: univerAPI.Enum.SparklineTypeEnum.BAR_CHART
       *   });
       * }, 3000);
       * ```
       */
      setConfig(config: ISparklineGroupConfig): FSparklineGroup;
  }

  /**
   * The facade class for the sparkline.
   * @hideconstructor
   */
  class FSparkline {
      /**
       * @description Modify the data source of the sparkline in the current cell
       * @param {IRange} sourceRange Location of new data source
       * @param {IRange} targetRange New placement
       * @returns {FSparkline | undefined} Return this, for chaining
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Create a sparkline in the range A10, with the data source in the range A1:A7.
       * const sparkline = fWorksheet.addSparkline(
       *   [fWorksheet.getRange('A1:A7').getRange()],
       *   [fWorksheet.getRange('A10').getRange()]
       * );
       *
       * // Modify the data source of the sparkline to the range B1:B7, and move it to the range B10 after 3 seconds.
       * setTimeout(() => {
       *   sparkline.changeDataSource(
       *     fWorksheet.getRange('B1:B7').getRange(),
       *     fWorksheet.getRange('B10').getRange()
       *   );
       * }, 3000);
       * ```
       */
      changeDataSource(sourceRange: IRange, targetRange: IRange): FSparkline | undefined;
      /**
       * @description Delete the sparkline in the current cell
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Create a sparkline in the range A10, with the data source in the range A1:A7.
       * const sparkline = fWorksheet.addSparkline(
       *   [fWorksheet.getRange('A1:A7').getRange()],
       *   [fWorksheet.getRange('A10').getRange()]
       * );
       *
       * // Remove the sparkline after 3 seconds.
       * setTimeout(() => {
       *   sparkline.removeSparkline();
       * }, 3000);
       * ```
       */
      removeSparkline(): void;
  }

  interface IFWorksheetSparklineMixin {
      /**
       * @description Add sparkline to the worksheet.
       * @param {IRange[]} sourceRanges Source data location for sparklines
       * @param {IRange[]} targetRanges Where to place sparklines
       * @param {SparklineTypeEnum} type The type of Sparklines
       * @returns {FSparkline | undefined} Returns the sparkline instance for the next call
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Create a sparkline in the range A10, with the data source in the range A1:A7.
       * const sourceRanges = [fWorksheet.getRange('A1:A7').getRange()];
       * const targetRanges = [fWorksheet.getRange('A10').getRange()];
       * const sparkline = fWorksheet.addSparkline(sourceRanges, targetRanges, univerAPI.Enum.SparklineTypeEnum.LINE_CHART);
       * console.log('sparkline instance', sparkline);
       * ```
       */
      addSparkline(sourceRanges: IRange[], targetRanges: IRange[], type: SparklineTypeEnum.LINE_CHART): FSparkline | undefined;
      /**
       * @description Get all sparklines in the worksheet.
       * @returns {Map<string, ISparklineGroup> | undefined} - The key is sparkline group id.
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Get all sparklines in the current worksheet
       * const allSparkline = fWorksheet.getAllSubSparkline();
       * console.log('allSparkline', allSparkline);
       * ```
       */
      getAllSubSparkline(): Map<string, ISparklineGroup> | undefined;
      /**
       * @description Group the sparklines in the selection into a new sparkline group
       * @param {IRange[]} ranges - The selection range to be grouped
       * @returns {void}
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Create a sparkline in the range A10, with the data source in the range A1:A7.
       * const firstSparkline = fWorksheet.addSparkline(
       *   [fWorksheet.getRange('A1:A7').getRange()],
       *   [fWorksheet.getRange('A10').getRange()]
       * );
       * // Create a sparkline in the range B10, with the data source in the range B1:B7.
       * const secondSparkline = fWorksheet.addSparkline(
       *   [fWorksheet.getRange('B1:B7').getRange()],
       *   [fWorksheet.getRange('B10').getRange()]
       * );
       * console.log('debugger', fWorksheet.getAllSubSparkline().size); // 2
       *
       * // Compose the two sparklines into one group after 3 seconds
       * setTimeout(() => {
       *   fWorksheet.composeSparkline([fWorksheet.getRange('A10:B10').getRange()]);
       *   console.log('debugger', fWorksheet.getAllSubSparkline().size); // 1
       * }, 3000);
       * ```
       */
      composeSparkline(ranges: IRange[]): void;
      /**
       * @description Split the sparkline group within the current selection
       * @param {IRange[]} ranges - The selection range to be ungrouped
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Create a sparkline in the range A10, with the data source in the range A1:A7.
       * const firstSparkline = fWorksheet.addSparkline(
       *   [fWorksheet.getRange('A1:A7').getRange()],
       *   [fWorksheet.getRange('A10').getRange()]
       * );
       * // Create a sparkline in the range B10, with the data source in the range B1:B7.
       * const secondSparkline = fWorksheet.addSparkline(
       *   [fWorksheet.getRange('B1:B7').getRange()],
       *   [fWorksheet.getRange('B10').getRange()]
       * );
       *
       * // Compose the two sparklines into one group
       * fWorksheet.composeSparkline([fWorksheet.getRange('A10:B10').getRange()]);
       * console.log('debugger', fWorksheet.getAllSubSparkline().size); // 1
       *
       * // Uncompose the sparkline group after 3 seconds
       * setTimeout(() => {
       *   fWorksheet.unComposeSparkline([fWorksheet.getRange('A10:B10').getRange()]);
       *   console.log('debugger', fWorksheet.getAllSubSparkline().size); // 2
       * }, 3000);
       * ```
       */
      unComposeSparkline(ranges: IRange[]): void;
      /**
       * @description Get the sparkline instance of the current cell
       * @param {number} row - The row index of the cell, start at 0.
       * @param {number} col - The column index of the cell, start at 0.
       * @returns {FSparkline | undefined} Returns the sparkline instance for the next call
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Create a sparkline in the range A10, with the data source in the range A1:A7.
       * const sourceRanges = [fWorksheet.getRange('A1:A7').getRange()];
       * const targetRanges = [fWorksheet.getRange('A10').getRange()];
       * const sparkline = fWorksheet.addSparkline(sourceRanges, targetRanges);
       *
       * console.log('Cell A10: ', fWorksheet.getSparklineByCell(9, 0));
       * console.log('Cell A11: ', fWorksheet.getSparklineByCell(10, 0));
       * ```
       */
      getSparklineByCell(row: number, col: number): FSparkline | undefined;
      /**
       * @description Get the sparkline groups instance of the current cell
       * @param {number} row - The row index of the cell, start at 0.
       * @param {number} col - The column index of the cell, start at 0.
       * @returns {FSparklineGroup | undefined} Returns the sparkline group instance for the next call
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Create a sparkline in the range A10, with the data source in the range A1:A7.
       * const firstSparkline = fWorksheet.addSparkline(
       *   [fWorksheet.getRange('A1:A7').getRange()],
       *   [fWorksheet.getRange('A10').getRange()]
       * );
       * // Create a sparkline in the range B10, with the data source in the range B1:B7.
       * const secondSparkline = fWorksheet.addSparkline(
       *   [fWorksheet.getRange('B1:B7').getRange()],
       *   [fWorksheet.getRange('B10').getRange()]
       * );
       * console.log('Cell A10: ', fWorksheet.getSparklineGroupByCell(9, 0));
       *
       * // Compose the two sparklines into one group after 3 seconds
       * setTimeout(() => {
       *   fWorksheet.composeSparkline([fWorksheet.getRange('A10:B10').getRange()]);
       *   console.log('Cell A10: ', fWorksheet.getSparklineGroupByCell(9, 0));
       * }, 3000);
       * ```
       */
      getSparklineGroupByCell(row: number, col: number): FSparklineGroup | undefined;
  }

  class FWorksheetSparklineMixin {
      addSparkline(sourceRanges: IRange[], targetRanges: IRange[], type: SparklineTypeEnum.LINE_CHART): FSparkline | undefined;
      getAllSubSparkline(): Map<string, ISparklineGroup> | undefined;
      composeSparkline(ranges: IRange[]): void;
      unComposeSparkline(ranges: IRange[]): void;
      getSparklineByCell(row: number, col: number): FSparkline | undefined;
      getSparklineGroupByCell(row: number, col: number): FSparklineGroup | undefined;
  }
}

declare module "@univerjs/core/facade" {
  import { SparklineTypeEnum } from "@univerjs-pro/sheets-sparkline";

  import type { ISparklineGroup } from "@univerjs-pro/sheets-sparkline";

  import type { FWorkbook, FWorksheet } from "@univerjs/sheets/facade";

  interface IFSheetsSparklineEnumMixin {
      SparklineTypeEnum: typeof SparklineTypeEnum;
  }

  interface IFSheetsSparklineEventNameMixin {
      /**
       * Trigger this event after the sparkline changes.
       * Type of the event parameter is {@link IFSheetSparklineChangedEventParams}
       *
       * @example
       * ```ts
       * const disposable = univerAPI.addEvent(univerAPI.Event.SheetSparklineChanged, (params) => {
       *   console.log('SheetSparklineChanged', params);
       *   const { workbook, worksheet, sparklines } = params;
       * });
       *
       * // Remove the event listener, use `disposable.dispose()`.
       * ```
       */
      readonly SheetSparklineChanged: 'SheetSparklineChanged';
  }

  interface IFSheetSparklineChangedEventParams extends IEventBase {
      /**
       * The workbook instance currently being operated on. {@link FWorkbook}
       */
      workbook: FWorkbook;
      /**
       * The worksheet instance currently being operated on. {@link FWorksheet}
       */
      worksheet: FWorksheet;
      /**
       * The sparkline array that have been changed. {@link ISparklineGroup}
       */
      sparklines: ISparklineGroup[];
  }

  interface ISheetsSparklineEventParamConfig {
      SheetSparklineChanged: IFSheetSparklineChangedEventParams;
  }
}

declare module "@univerjs/core/facade" {
  import { SparklineTypeEnum } from "@univerjs-pro/sheets-sparkline";

  import type { ISparklineGroup } from "@univerjs-pro/sheets-sparkline";

  import type { FWorkbook, FWorksheet } from "@univerjs/sheets/facade";

  interface FEnum extends IFSheetsSparklineEnumMixin {
  }
}

declare module "@univerjs/core/facade" {
  import { SparklineTypeEnum } from "@univerjs-pro/sheets-sparkline";

  import type { ISparklineGroup } from "@univerjs-pro/sheets-sparkline";

  import type { FWorkbook, FWorksheet } from "@univerjs/sheets/facade";

  interface FEventName extends IFSheetsSparklineEventNameMixin {
  }

  interface IEventParamConfig extends ISheetsSparklineEventParamConfig {
  }
}

declare module "@univerjs/sheets/facade" {
  import type { IFWorksheetSparklineMixin } from "@univerjs-pro/sheets-sparkline/facade";

  interface FWorksheet extends IFWorksheetSparklineMixin {
  }
}
