/// <reference no-default-lib="true" />
/// <reference lib="esnext" />
/// <reference lib="dom" />
import { caret, insertText } from "../scrapbox-userscript-std/dom.ts";
import type { Scrapbox } from "https://raw.githubusercontent.com/scrapbox-jp/types/0.0.8/mod.ts";
declare const scrapbox: Scrapbox;

const userscriptId = "mobile-decorate-page-menu";
const dummyImage = "/assets/img/favicon/apple-touch-icon.png";

export interface Init {
  id?: string;
  decorates?: Decorate[];
}
export interface Decorate {
  title: string;
  titleStyle?: string;
  icon?: string;
  onClick: (
    text: string,
  ) => (Promise<string | undefined> | string | undefined);
}

export function mount(init?: Init) {
  const id = (init?.id ?? userscriptId).replaceAll(" ", "_");
  const decorates = init?.decorates ?? defaultDecorates;

  const selector = `head style[data-userscript-name="${id}"]`;
  document.querySelector(selector)?.remove?.();
  const style = document.createElement("style");
  style.dataset.userscriptName = id;
  style.textContent = `a#${id}.tool-btn:hover {
  text-decoration: none;
}
a#${id}.tool-btn::before {
  position: absolute;
  content: "\\f591";
  font: 900 20px/46px "Font Awesome 5 Free";
}
a#${id}.tool-btn img {
  opacity: 0;
}

a#${id}.tool-btn ~ ul a::before {
  position: absolute;
  font-family: "Font Awesome 5 Free";
  font-weight: 900;
}
a#${id}.tool-btn ~ ul img {
  opacity: 0;
  margin-right: 0;
}`;
  document.head.append(style);

  if (!document.getElementById(id)) {
    scrapbox.PageMenu.addMenu({
      title: id,
      image: dummyImage,
    });
  }

  scrapbox.PageMenu(id).removeAllItems();
  let counter = 0;
  for (const { title, titleStyle, icon, onClick } of decorates) {
    counter++;
    scrapbox.PageMenu(id).addItem({
      title,
      ...(icon ? { image: dummyImage } : {}),
      onClick: async () => {
        const { selectedText } = caret();
        if (selectedText === "") return;
        const result = onClick(selectedText);
        const text = result instanceof Promise ? await result : result;
        if (text === undefined) return;
        if (text === selectedText) return;
        await insertText(text);
      },
    });
    if (titleStyle) {
      style.textContent +=
        `a#${id}.tool-btn ~ ul li:nth-of-type(${counter}) a { ${titleStyle} }\n`;
    }
    if (!icon) continue;
    style.textContent +=
      `a#${id}.tool-btn ~ ul li:nth-of-type(${counter}) a::before { content:"${icon}"; }\n`;
  }
}

export const defaultDecorates: Decorate[] = [
  {
    title: "Strong",
    titleStyle: "font-weight: bold;",
    icon: "\\f032",
    onClick: (text) => `[* ${text}]`,
  },
  {
    title: "Italic",
    titleStyle: "font-style: italic;",
    icon: "\\f033",
    onClick: (text) => `[/ ${text}]`,
  },
  {
    title: "Strike",
    titleStyle: "text-decoration-line: line-through;",
    icon: "\\f0cc",
    onClick: (text) => `[- ${text}]`,
  },
  {
    title: "Underline",
    titleStyle: "text-decoration-line: underline;",
    icon: "\\f0cd",
    onClick: (text) => `[_ ${text}]`,
  },
  {
    title: "Marker",
    titleStyle: "font-weight: bold;",
    icon: "\\f5a1",
    onClick: (text) => `[[${text}]]`,
  },
];