declare module "@univerjs/core/facade" {
  import type { ISheetsHyperlinkEventParamConfig } from "@univerjs/sheets-hyper-link/facade";

  interface IFSheetsHyperlinkEventNameMixin {
      /**
       * Event triggered before adding a link
       * @see {@link IBeforeSheetLinkAddEventParams}
       * @example
       * ```ts
       * const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetLinkAdd, (params) => {
       *   const { workbook, worksheet, row, col, link } = params;
       *   console.log('before sheet link add', params);
       *
       *   // Cancel the sheet link add operation
       *   params.cancel = true;
       * });
       *
       * // Remove the event listener, use `disposable.dispose()`
       * ```
       */
      readonly BeforeSheetLinkAdd: 'BeforeSheetLinkAdd';
      /**
       * Event triggered before canceling a link
       * @see {@link IBeforeSheetLinkCancelEventParams}
       * @example
       * ```ts
       * const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetLinkCancel, (params) => {
       *   const { workbook, worksheet, row, column, id } = params;
       *   console.log('before sheet link cancel', params);
       *
       *   // Cancel the sheet link cancel operation
       *   params.cancel = true;
       * });
       *
       * // Remove the event listener, use `disposable.dispose()`
       * ```
       */
      readonly BeforeSheetLinkCancel: 'BeforeSheetLinkCancel';
      /**
       * Event triggered before updating a link
       * @see {@link IBeforeSheetLinkUpdateEventParams}
       * @example
       * ```ts
       * const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetLinkUpdate, (params) => {
       *   const { workbook, worksheet, row, column, id, payload } = params;
       *   console.log('before sheet link update', params);
       *
       *   // Cancel the sheet link update operation
       *   params.cancel = true;
       * });
       *
       * // Remove the event listener, use `disposable.dispose()`
       * ```
       */
      readonly BeforeSheetLinkUpdate: 'BeforeSheetLinkUpdate';
  }
}

declare module "@univerjs/sheets-hyper-link" {
  import type { Nullable } from "@univerjs/core";

  interface ISheetUrlParams {
      gid?: string;
      range?: string;
      rangeid?: string;
      unitid?: string;
  }

  interface ISheetHyperLinkInfo {
      type: SheetHyperLinkType;
      name: string;
      url: string;
      searchObj: Nullable<ISheetUrlParams>;
  }

  enum SheetHyperLinkType {
      SHEET = "gid",
      RANGE = "range",
      DEFINE_NAME = "rangeid",
      INVALID = "invalid",
      URL = "url"
  }

  interface ICellLinkContent {
      /**
       * #gid=sheet1&range=A1
       * sub sheet: #gid=sheet1
       * namedRange: #rangeid=123
       * http: https://baidu.com
       * file: file://a.xlsx
       */
      payload: string;
      /**
       * only for notify, if you wan't to read the display of text, use cell-value of cell-matrix instead
       */
      display?: string;
  }

  interface ISheetHyperLink extends ICellLinkContent {
      /**
       * unique id
       */
      id: string;
      /**
       * row of link
       */
      row: number;
      /**
       * col of link
       */
      column: number;
  }
}

declare module "@univerjs/sheets-hyper-link/facade" {
  import type { IEventBase } from "@univerjs/core/facade";

  import type { ICellLinkContent, ISheetHyperLink, ISheetHyperLinkInfo } from "@univerjs/sheets-hyper-link";

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

  class FSheetsHyperlinkEventNameMixin {
      get BeforeSheetLinkAdd(): 'BeforeSheetLinkAdd';
      get BeforeSheetLinkCancel(): 'BeforeSheetLinkCancel';
      get BeforeSheetLinkUpdate(): 'BeforeSheetLinkUpdate';
  }

  interface IBeforeSheetLinkAddEventParams extends IEventBase {
      /** The workbook instance */
      workbook: FWorkbook;
      /** The worksheet where the link will be added */
      worksheet: FWorksheet;
      /** The row index of the target cell */
      row: number;
      /** The column index of the target cell */
      col: number;
      /** The hyperlink information to be added */
      link: ISheetHyperLink;
  }

  interface IBeforeSheetLinkCancelEventParams extends IEventBase {
      /** The workbook instance */
      workbook: FWorkbook;
      /** The worksheet containing the link */
      worksheet: FWorksheet;
      /** The row index of the cell */
      row: number;
      /** The column index of the cell */
      column: number;
      /** The unique identifier of the hyperlink */
      id: string;
  }

  interface IBeforeSheetLinkUpdateEventParams extends IEventBase {
      /** The workbook instance */
      workbook: FWorkbook;
      /** The worksheet containing the link */
      worksheet: FWorksheet;
      /** The row index of the cell */
      row: number;
      /** The column index of the cell */
      column: number;
      /** The unique identifier of the hyperlink */
      id: string;
      /** The new hyperlink content/information */
      payload: ICellLinkContent;
  }

  interface ISheetsHyperlinkEventParamConfig {
      BeforeSheetLinkAdd: IBeforeSheetLinkAddEventParams;
      BeforeSheetLinkCancel: IBeforeSheetLinkCancelEventParams;
      BeforeSheetLinkUpdate: IBeforeSheetLinkUpdateEventParams;
  }

  interface ICellHyperLink {
      id: string;
      row: number;
      column: number;
      url: string;
      label: string;
  }

  interface IFRangeSheetsHyperlinkMixin {
      /**
       * Set a hyperlink for this range top left cell.
       * The hyperlink can be a URL, a range link, or a sheet link.
       * When the hyperlink is a range link or a sheet link, the url should be the url of the target range or sheet.
       * @param {string} url - The hyperlink url, can be a URL, a range link, or a sheet link.
       * @param {string} [label] - The display text of the hyperlink. If not provided, the url will be used as the display text.
       * @return {Promise<boolean>} A promise that resolves to true if the hyperlink is set successfully, otherwise false.
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Create a hyperlink to Univer on cell A1
       * const fRange = fWorksheet.getRange('A1');
       * await fRange.setHyperLink('https://univer.ai/', 'Univer');
       *
       * // Create a hyperlink to Sheet1 range B2:D4 on cell A2
       * const fRange2 = fWorksheet.getRange('A2');
       * const rangeUrl = fWorksheet.getRange('B2:D4').getUrl();
       * await fRange2.setHyperLink(rangeUrl, 'Link to B2:D4');
       *
       * // Create a hyperlink to another sheet range on cell A3
       * const anotherSheet = fWorkbook.getSheetByName('Another Sheet');
       * if (anotherSheet) {
       *   const anotherSheetUrl = anotherSheet.getUrl();
       *   const fRange3 = fWorksheet.getRange('A3');
       *   await fRange3.setHyperLink(anotherSheetUrl, 'Link to Another Sheet');
       * }
       *
       * // Create a hyperlink to a defined name on cell A4
       * const fRange4 = fWorksheet.getRange('A4');
       * const definedNameHyperlinkUrl = fWorkbook.getUrlOfDefineName('MyDefinedName');
       * await fRange4.setHyperLink(definedNameHyperlinkUrl, 'Link to MyDefinedName');
       * ```
       */
      setHyperLink(url: string, label?: string): Promise<boolean>;
      /**
       * Get all hyperlinks in this range.
       * @return {ICellHyperLink[]} An array of hyperlinks in this range.
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       * console.log(fWorksheet.getRange('A1:T100').getHyperLinks());
       * ```
       */
      getHyperLinks(): ICellHyperLink[];
      /**
       * Update the hyperlink of this range top left cell.
       * @param {string} url - The new hyperlink url, can be a URL, a range link, or a sheet link.
       * @param {string} [label] - The new display text of the hyperlink. If not provided, the url will be used as the display text.
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Create a hyperlink to Univer on cell A1
       * const fRange = fWorksheet.getRange('A1');
       * await fRange.setHyperLink('https://univer.ai/', 'Univer');
       *
       * // Update hyperlink after 3 seconds
       * await new Promise((resolve) => setTimeout(resolve, 3000));
       *
       * const rangeUrl = fWorksheet.getRange('B2:D4').getUrl();
       * await fRange.updateHyperLink(rangeUrl, 'Link to B2:D4');
       * ```
       */
      updateHyperLink(url: string, label?: string): Promise<boolean>;
      /**
       * Cancel all hyperlinks in this range. If a hyperlink is provided, only cancel the specified hyperlink.
       * @param {ICellHyperLink} [hyperlink] - The hyperlink to be cancelled. If not provided, all hyperlinks in this range will be cancelled.
       * @return {boolean} True if the hyperlink(s) is cancelled successfully, otherwise false.
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Cancel the hyperlink in cell A1
       * const fRange = fWorksheet.getRange('A1');
       * fRange.cancelHyperLink();
       *
       * // Cancel all hyperlinks in range A2:B4
       * const fRange2 = fWorksheet.getRange('A2:B4');
       * fRange2.cancelHyperLink();
       *
       * // Cancel a specific hyperlink in range A1:T100
       * const fRange3 = fWorksheet.getRange('A1:T100');
       * const hyperlinks = fRange3.getHyperLinks();
       * if (hyperlinks.length > 1) {
       *   fRange3.cancelHyperLink(hyperlinks[1]);
       * }
       * ```
       */
      cancelHyperLink(hyperlink?: ICellHyperLink): boolean;
      /**
       * Create a hyperlink url to this range
       * @returns {string} The hyperlink url of this range
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       * const fRange = fWorksheet.getRange('A1');
       * const url = fRange.getUrl();
       * console.log(url);
       * ```
       */
      getUrl(): string;
  }

  class FRangeSheetsHyperlinkMixin {
      setHyperLink(url: string, label?: string): Promise<boolean>;
      getHyperLinks(): ICellHyperLink[];
      updateHyperLink(url: string, label?: string): Promise<boolean>;
      cancelHyperLink(hyperlink?: ICellHyperLink): boolean;
      getUrl(): string;
  }

  class FUniverSheetsHyperlinkMixin {
  }

  interface IFWorkbookHyperlinkMixin {
      /**
       * Create a hyperlink url for the defined name.
       * The defined name must exist in the current workbook and must be a reference to a range, otherwise an error will be thrown.
       * @param {string} name - The name of the defined name.
       * @returns {string} The hyperlink url of the defined name.
       *
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       *
       * // Create a defined name "TestRange" for the range A1:B10 of the active sheet
       * const definedNameParam = fWorkbook.newDefinedNameBuilder()
       *   .setName('TestRange')
       *   .setRef('Sheet1!$A$1:$B$10')
       *   .build();
       * fWorkbook.insertDefinedNameBuilder(definedNameParam);
       *
       * // Create a hyperlink to the defined name "TestRange" on cell C1
       * const url = fWorkbook.getUrlOfDefineName('TestRange');
       * console.log(url);
       * const fRange = fWorksheet.getRange('C1');
       * fRange.setHyperLink(url, 'Link to TestRange');
       *
       * // Create a hyperlink to the exiting defined name on cell C2
       * const definedNames = fWorkbook.getDefinedNames();
       * console.log(definedNames);
       * const exitsDefinedNameUrl = fWorkbook.getUrlOfDefineName(definedNames[0].getName());
       * console.log(exitsDefinedNameUrl);
       * const fRange2 = fWorksheet.getRange('C2');
       * fRange2.setHyperLink(exitsDefinedNameUrl, `Link to ${definedNames[0].getName()}`);
       * ```
       */
      getUrlOfDefineName(name: string): string;
      /**
       * Parse the hyperlink string to get the hyperlink info.
       * @param {string} hyperlink - The hyperlink string.
       * @returns {ISheetHyperLinkInfo} The hyperlink info.
       *
       * @example
       * ``` ts
       * // Create a hyperlink to the range A1:D10 of the current sheet
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       * const fRange = fWorksheet.getRange('A1:D10');
       * const hyperlink = fRange.getUrl();
       *
       * // Parse the hyperlink
       * const hyperlinkInfo = fWorkbook.parseSheetHyperlink(hyperlink);
       * console.log(hyperlinkInfo);
       * ```
       */
      parseSheetHyperlink(hyperlink: string): ISheetHyperLinkInfo;
  }

  class FWorkbookHyperlinkMixin {
      getUrlOfDefineName(name: string): string;
      parseSheetHyperlink(hyperlink: string): ISheetHyperLinkInfo;
  }

  interface IFWorksheetHyperlinkMixin {
      /**
       * Create a hyperlink url to this sheet
       * @returns {string} The hyperlink url of this sheet
       * @example
       * ```ts
       * const fWorkbook = univerAPI.getActiveWorkbook();
       * const fWorksheet = fWorkbook.getSheetByName('Sheet1');
       * if (!fWorksheet) return;
       * const url = fWorksheet.getUrl();
       * console.log(url);
       * ```
       */
      getUrl(): string;
  }

  class FWorksheetHyperlinkMixin {
      getUrl(): string;
  }
}

declare module "@univerjs/core/facade" {
  import type { ISheetsHyperlinkEventParamConfig } from "@univerjs/sheets-hyper-link/facade";

  interface FEventName extends IFSheetsHyperlinkEventNameMixin {
  }

  interface IEventParamConfig extends ISheetsHyperlinkEventParamConfig {
  }
}

declare module "@univerjs/sheets/facade" {
  import type { IFRangeSheetsHyperlinkMixin, IFWorkbookHyperlinkMixin, IFWorksheetHyperlinkMixin } from "@univerjs/sheets-hyper-link/facade";

  interface FRange extends IFRangeSheetsHyperlinkMixin {
  }
}

declare module "@univerjs/sheets/facade" {
  import type { IFRangeSheetsHyperlinkMixin, IFWorkbookHyperlinkMixin, IFWorksheetHyperlinkMixin } from "@univerjs/sheets-hyper-link/facade";

  interface FWorkbook extends IFWorkbookHyperlinkMixin {
  }
}

declare module "@univerjs/sheets/facade" {
  import type { IFRangeSheetsHyperlinkMixin, IFWorkbookHyperlinkMixin, IFWorksheetHyperlinkMixin } from "@univerjs/sheets-hyper-link/facade";

  interface FWorksheet extends IFWorksheetHyperlinkMixin {
  }
}
