// Comments in English
import { EditorView } from "@codemirror/view";
import { syntaxTree } from "@codemirror/language";
import { Decoration } from "@codemirror/view";
import { selectionIntersects } from "../utils/selection";

export const liveLinkTheme = EditorView.theme({
  ".cm-live-link": {
    color: "#3b82f6",
    textDecoration: "underline",
    cursor: "pointer",
    userSelect: "text",
  },
});

export function openExternal(url: string) {
  try { const u = new URL(url, window.location.href); window.open(u.href, "_blank", "noopener"); } catch {}
}

export function liveLinkHandlers() {
  return EditorView.domEventHandlers({
    mousedown(event, view) {
      const target = event.target as HTMLElement | null;
      const linkEl = target?.closest?.(".cm-live-link") as HTMLElement | null;
      if (!linkEl) return false;
      const pos = (view as EditorView).posAtDOM(linkEl, 0);
      const info = linkAt(view as EditorView, pos);
      if (!info) return false;
      if (selectionIntersects((view as EditorView).state.selection, info.from, info.to)) return false;
      const url = linkEl.getAttribute("data-url");
      if (!url) return false;
      if (event.button === 0) { event.preventDefault(); event.stopPropagation(); openExternal(url); return true; }
      return false;
    }
  });
}

export const liveLinkKeybind = {
  key: "Mod-Enter",
  run(view: EditorView) {
    const pos = view.state.selection.main.head;
    const info = linkAt(view, pos);
    if (info && info.url) { openExternal(info.url); return true; }
    return false;
  },
};

export function linkAt(view: EditorView, pos: number): { from: number; to: number; url: string } | null {
  const state = view.state; const tree = syntaxTree(state);
  let found: { from: number; to: number } | null = null;
  tree.iterate({ from: pos, to: pos, enter(n) { if (n.name === "Link" && n.from <= pos && n.to >= pos) found = { from: n.from, to: n.to }; }});
  if (!found) return null;
  const raw = state.doc.sliceString(found.from, found.to);
  const ob = raw.indexOf("["); const cb = raw.indexOf("]", ob + 1); const op = raw.indexOf("(", cb + 1); const cp = raw.indexOf(")", op + 1);
  if (ob === -1 || cb === -1 || op === -1 || cp === -1) return null;
  const urlFrom = found.from + op + 1; const urlTo = found.from + cp;
  const url = state.doc.sliceString(urlFrom, urlTo);
  return { from: found.from, to: found.to, url };
}
