import type {ContextMenuParams} from "electron";
import {remote} from "electron";

import * as t from "../../../common/translation-util";

const {clipboard, Menu} = remote;

export const contextMenu = (
  webContents: Electron.WebContents,
  event: Event,
  props: ContextMenuParams,
) => {
  const isText = props.selectionText !== "";
  const isLink = props.linkURL !== "";
  const linkURL = isLink ? new URL(props.linkURL) : undefined;

  const makeSuggestion = (suggestion: string) => ({
    label: suggestion,
    visible: true,
    async click() {
      await webContents.insertText(suggestion);
    },
  });

  let menuTemplate: Electron.MenuItemConstructorOptions[] = [
    {
      label: t.__("Add to Dictionary"),
      visible: props.isEditable && isText && props.misspelledWord.length > 0,
      click(_item) {
        webContents.session.addWordToSpellCheckerDictionary(
          props.misspelledWord,
        );
      },
    },
    {
      type: "separator",
      visible: props.isEditable && isText && props.misspelledWord.length > 0,
    },
    {
      label: `${t.__("Look Up")} "${props.selectionText}"`,
      visible: process.platform === "darwin" && isText,
      click(_item) {
        webContents.showDefinitionForSelection();
      },
    },
    {
      type: "separator",
      visible: process.platform === "darwin" && isText,
    },
    {
      label: t.__("Cut"),
      visible: isText,
      enabled: props.isEditable,
      accelerator: "CommandOrControl+X",
      click(_item) {
        webContents.cut();
      },
    },
    {
      label: t.__("Copy"),
      accelerator: "CommandOrControl+C",
      enabled: props.editFlags.canCopy,
      click(_item) {
        webContents.copy();
      },
    },
    {
      label: t.__("Paste"), // Bug: Paste replaces text
      accelerator: "CommandOrControl+V",
      enabled: props.isEditable,
      click() {
        webContents.paste();
      },
    },
    {
      type: "separator",
    },
    {
      label:
        linkURL?.protocol === "mailto:"
          ? t.__("Copy Email Address")
          : t.__("Copy Link"),
      visible: isLink,
      click(_item) {
        clipboard.write({
          bookmark: props.linkText,
          text:
            linkURL?.protocol === "mailto:" ? linkURL.pathname : props.linkURL,
        });
      },
    },
    {
      label: t.__("Copy Image"),
      visible: props.mediaType === "image",
      click(_item) {
        webContents.copyImageAt(props.x, props.y);
      },
    },
    {
      label: t.__("Copy Image URL"),
      visible: props.mediaType === "image",
      click(_item) {
        clipboard.write({
          bookmark: props.srcURL,
          text: props.srcURL,
        });
      },
    },
    {
      type: "separator",
      visible: isLink || props.mediaType === "image",
    },
    {
      label: t.__("Services"),
      visible: process.platform === "darwin",
      role: "services",
    },
  ];

  if (props.misspelledWord) {
    if (props.dictionarySuggestions.length > 0) {
      const suggestions: Electron.MenuItemConstructorOptions[] = props.dictionarySuggestions.map(
        (suggestion: string) => makeSuggestion(suggestion),
      );
      menuTemplate = [...suggestions, ...menuTemplate];
    } else {
      menuTemplate.unshift({
        label: t.__("No Suggestion Found"),
        enabled: false,
      });
    }
  }
  // Hide the invisible separators on Linux and Windows
  // Electron has a bug which ignores visible: false parameter for separator menuitems. So we remove them here.
  // https://github.com/electron/electron/issues/5869
  // https://github.com/electron/electron/issues/6906

  const filteredMenuTemplate = menuTemplate.filter(
    (menuItem) => menuItem.visible ?? true,
  );
  const menu = Menu.buildFromTemplate(filteredMenuTemplate);
  menu.popup();
};
