// Dictionary lookup popup for ebooks
// Feature Registration Pattern implementation

import type { ReaderContext } from "../core/reader-context";

export function init(context: ReaderContext): void {
  context.events.on("dictionary:lookup", (detail: { word: string; position: { x: number; y: number } }) => {
    showDictionaryPopup(detail.word, detail.position);
  });

  context.events.on("reader:loaded", () => {
    handleTextSelection();
  });

  context.events.on("reader:unload", () => {
    const popup = document.getElementById("dictionary-popup");
    popup?.remove();
  });
}

function showDictionaryPopup(
  word: string,
  position: { x: number; y: number },
): void {
  const existing = document.getElementById("dictionary-popup");
  existing?.remove();

  const popup = document.createElement("div");
  popup.id = "dictionary-popup";
  popup.className =
    "absolute bg-white text-black p-4 rounded-lg shadow-xl max-w-md z-50";
  popup.style.left = `${position.x}px`;
  popup.style.top = `${position.y}px`;

  popup.innerHTML = '<p class="text-sm">Loading...</p>';
  document.body.appendChild(popup);

  lookupWord(word)
    .then((entry) => {
      popup.innerHTML = `
      <h3 class="font-bold text-lg">${entry.word}</h3>
      <p class="text-sm italic">${entry.part_of_speech || ""}</p>
      <p class="mt-2">${entry.definition}</p>
      ${entry.example ? `<p class="mt-2 text-sm italic">"${entry.example}"</p>` : ""}
    `;
    })
    .catch(() => {
      popup.innerHTML = `<p class="text-red-500">Definition not found for "${word}"</p>`;
    });

  setTimeout(() => {
    document.addEventListener("click", function closePopup(e: MouseEvent) {
      if (!popup.contains(e.target as Node)) {
        popup.remove();
        document.removeEventListener("click", closePopup);
      }
    });
  }, 100);
}

function handleTextSelection(): void {
  document.addEventListener("mouseup", () => {
    const selection = window.getSelection();
    const selectedText = selection?.toString().trim();

    if (selectedText && selectedText.split(" ").length === 1) {
      const range = selection?.getRangeAt(0);
      const rect = range?.getBoundingClientRect();

      if (rect) {
        showDictionaryPopup(selectedText, { x: rect.left, y: rect.bottom });
      }
    }
  });
}

async function lookupWord(word: string): Promise<any> {
  const response = await fetch(`/api/dictionary/${word}`);
  if (!response.ok) {
    throw new Error(`Failed to lookup word: ${word}`);
  }
  return await response.json();
}