/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict
 */

import type {LexicalNode, MutationListener} from 'lexical';

import {MenuOption} from '@lexical/react/LexicalTypeaheadMenuPlugin';
import type {LexicalCommand, LexicalEditor, NodeKey, TextNode} from 'lexical';
import * as React from 'react';
import {createCommand} from 'lexical';
import type {MenuRenderFn} from './LexicalTypeaheadMenuPlugin';

export type EmbedMatchResult = {
  url: string,
  id: string,
};

export interface EmbedConfig {
  // Used to identify this config e.g. youtube, tweet, google-maps.
  type: string;
  // Determine if a given URL is a match and return url data.
  parseUrl: (text: string) => EmbedMatchResult | null;
  // Create the Lexical embed node from the url data.
  insertNode: (editor: LexicalEditor, result: EmbedMatchResult) => void;
}

export const URL_MATCHER: RegExp =
  /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;

export const INSERT_EMBED_COMMAND: LexicalCommand<EmbedConfig['type']> =
  createCommand('INSERT_EMBED_COMMAND');

type LexicalAutoEmbedPluginProps<TEmbedConfig> = {
  embedConfigs: Array<TEmbedConfig>,
  onOpenEmbedModalForConfig: (embedConfig: TEmbedConfig) => void,
  getMenuOptions: (
    activeEmbedConfig: TEmbedConfig,
    embedFn: () => void,
    dismissFn: () => void,
  ) => Array<AutoEmbedOption>,
  menuRenderFn: MenuRenderFn<AutoEmbedOption>,
};

declare export class AutoEmbedOption extends MenuOption {
  title: string;
  icon: React.MixedElement;
  onSelect: (targetNode: LexicalNode | null) => void;
  constructor(
    title: string,
    options: {
      icon: React.MixedElement,
      onSelect: (targetNode: LexicalNode | null) => void,
    },
  ): void;
}

declare export function LexicalAutoEmbedPlugin<TEmbedConfig>(
  LexicalAutoEmbedPluginProps<TEmbedConfig>,
): React.MixedElement | null;