// PDF text selection - Uses backend API for highlight creation
// Feature Registration Pattern implementation

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

export function init(context: ReaderContext): void {
  let currentMediaItemId: string | null = null;

  context.events.on("reader:loaded", (detail: { mediaItemId: string }) => {
    currentMediaItemId = detail.mediaItemId;
  });

  context.events.on("pdf:selection:get", () => {
    const selection = getPDFTextSelection();
    context.events.emit("pdf:selection-current", selection);
  });

  context.events.on("pdf:highlight:create", async (detail: { selection: PDFTextSelection; color: string }) => {
    if (currentMediaItemId) {
      try {
        const highlight = await createPDFHighlight(currentMediaItemId, detail.selection, detail.color);
        context.events.emit("pdf:highlight-created", highlight);
      } catch (error) {
        console.error("Failed to create highlight:", error);
      }
    }
  });

  context.events.on("pdf:highlights:load", async (detail: { container: HTMLElement }) => {
    if (currentMediaItemId) {
      await loadAndRenderPDFHighlights(currentMediaItemId, detail.container);
    }
  });

  context.events.on("reader:unload", () => {
    currentMediaItemId = null;
  });
}

interface PDFTextSelection {
  pageNumber: number;
  text: string;
  rects: DOMRect[];
}

export function getPDFTextSelection(): PDFTextSelection | null {
  const selection = window.getSelection();
  if (!selection || selection.rangeCount === 0) return null;

  const range = selection.getRangeAt(0);
  const text = range.toString();

  if (!text) return null;

  const pageElement =
    range.commonAncestorContainer.parentElement?.closest?.("[data-page-number]") as HTMLElement;
  const pageNumber = pageElement?.dataset.pageNumber
    ? parseInt(pageElement.dataset.pageNumber)
    : getCurrentPDFPage();

  const rects: DOMRect[] = [];
  for (const rect of Array.from(range.getClientRects())) {
    rects.push(rect);
  }

  return {
    pageNumber,
    text,
    rects,
  };
}

export async function createPDFHighlight(
  mediaItemId: string,
  selection: PDFTextSelection,
  color: string,
): Promise<any> {
  const selectionData = {
    selection_text: selection.text,
    page_number: selection.pageNumber,
    rects: selection.rects.map((rect) => ({
      x: rect.x,
      y: rect.y,
      width: rect.width,
      height: rect.height,
    })),
    color,
  };

  const response = await fetch(`/api/media-items/${mediaItemId}/highlights`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(selectionData),
  });

  if (!response.ok) {
    throw new Error(`Failed to create highlight: ${response.statusText}`);
  }

  return await response.json();
}

export async function loadAndRenderPDFHighlights(
  mediaItemId: string,
  container: HTMLElement,
): Promise<void> {
  const response = await fetch(`/api/media-items/${mediaItemId}/highlights`);
  if (!response.ok) return;

  const highlights: any[] = await response.json();

  for (const highlight of highlights) {
    renderPDFHighlight(container, highlight);
  }
}

function renderPDFHighlight(
  container: HTMLElement,
  highlight: any,
): void {
  const overlay = document.createElement("div");
  overlay.className = "pdf-highlight-annotation";
  overlay.dataset.highlightId = highlight.id;
  overlay.style.backgroundColor = parseColor(highlight.color || "#ffff00");

  for (const rect of highlight.rects || []) {
    const rectDiv = document.createElement("div");
    rectDiv.className = "pdf-highlight-rect";
    rectDiv.style.left = `${rect.x}px`;
    rectDiv.style.top = `${rect.y}px`;
    rectDiv.style.width = `${rect.width}px`;
    rectDiv.style.height = `${rect.height}px`;
    overlay.appendChild(rectDiv);
  }

  container.appendChild(overlay);
}

function parseColor(color: string): string {
  if (color.startsWith("#")) {
    const hex = color.slice(1);
    const r = parseInt(hex.slice(0, 2), 16);
    const g = parseInt(hex.slice(2, 4), 16);
    const b = parseInt(hex.slice(4, 6), 16);
    return `rgba(${r}, ${g}, ${b}, 0.4)`;
  }

  return color;
}

function getCurrentPDFPage(): number {
  const pageElement = document.querySelector("[data-page-number]");
  return pageElement ? parseInt(pageElement.getAttribute("data-page-number") || "1") : 1;
}