// Handle internal PDF links (cross-references, citations, TOC links)
// External links open in new tab
// Procedural implementation (no OOP)

interface PDFLink {
  url: string;
  pageNumber?: number;
  bounds: { x: number; y: number; width: number; height: number };
}

interface PDFLinkHandlerState {
  doc: PDFDocumentProxy | null;
  container: HTMLElement;
  onPageNavigate: (pageNumber: number) => void;
}

async function initializePDFLinkHandler(
  container: HTMLElement,
  onPageNavigate: (pageNumber: number) => void,
  doc: PDFDocumentProxy,
): Promise<PDFLinkHandlerState> {
  const state: PDFLinkHandlerState = {
    doc,
    container,
    onPageNavigate,
  };

  await setupPDFLinks(state);

  return state;
}

async function setupPDFLinks(state: PDFLinkHandlerState): Promise<void> {
  if (!state.doc) return;

  for (let pageNum = 1; pageNum <= state.doc.numPages; pageNum++) {
    const page = await state.doc.getPage(pageNum);
    const annotations = await page.getAnnotations();

    for (const annotation of annotations) {
      if (annotation.subtype === "Link") {
        createPDFLinkElement(state, annotation, pageNum);
      }
    }
  }
}

function createPDFLinkElement(
  state: PDFLinkHandlerState,
  annotation: any,
  pageNumber: number,
): void {
  const pageElement = state.container.querySelector(
    `[data-page-number="${pageNumber}"]`,
  );
  if (!pageElement) return;

  const link = document.createElement("a");
  link.className = "pdf-internal-link";
  link.href = "javascript:void(0)";

  if (annotation.rect) {
    const rect = annotation.rect;
    link.style.position = "absolute";
    link.style.left = `${rect[0]}px`;
    link.style.top = `${rect[1]}px`;
    link.style.width = `${rect[2] - rect[0]}px`;
    link.style.height = `${rect[3] - rect[1]}px`;
    link.style.cursor = "pointer";
  }

  link.addEventListener("click", (e) => {
    e.preventDefault();
    handlePDFLinkClick(state, annotation);
  });

  pageElement.appendChild(link);
}

async function handlePDFLinkClick(
  state: PDFLinkHandlerState,
  annotation: any,
): Promise<void> {
  if (!state.doc) return;

  if (annotation.url) {
    if (
      annotation.url.startsWith("http://") ||
      annotation.url.startsWith("https://")
    ) {
      window.open(annotation.url, "_blank", "noopener,noreferrer");
    } else {
      console.warn("Unhandled URL:", annotation.url);
    }
  } else if (annotation.dest) {
    const pageNumber = await resolvePDFLinkDestination(state, annotation.dest);
    state.onPageNavigate(pageNumber);
  }
}

async function resolvePDFLinkDestination(
  state: PDFLinkHandlerState,
  dest: string | any[],
): Promise<number> {
  if (!state.doc) return 1;

  try {
    let explicitDest: any[];

    if (typeof dest === "string") {
      const destObj = await state.doc.getDestination(dest);
      if (!destObj) return 1;
      explicitDest = destObj;
    } else {
      explicitDest = dest;
    }

    const ref = explicitDest[0];

    if (typeof ref === "object" && ref !== null) {
      const pageIndex = await state.doc.getPageIndex(ref);
      return pageIndex + 1;
    } else if (typeof ref === "number") {
      return ref + 1;
    }

    return 1;
  } catch (error) {
    console.error("Failed to resolve link destination:", error);
    return 1;
  }
}
