// Dual page spread view for PDFs
// Procedural implementation (no OOP)

type DualPageMode = "single" | "dual";

interface PDFDualPageViewState {
  currentMode: DualPageMode;
  minViewportWidth: number;
}

function createPDFDualPageView(
  container: HTMLElement,
  onModeChange: (mode: DualPageMode) => void,
): PDFDualPageViewState {
  const state: PDFDualPageViewState = {
    currentMode: "single",
    minViewportWidth: 1200,
  };

  setupResponsiveDualPageToggle(container, state, onModeChange);

  return state;
}

function setupResponsiveDualPageToggle(
  container: HTMLElement,
  state: PDFDualPageViewState,
  onModeChange: (mode: DualPageMode) => void,
): void {
  const resizeObserver = new ResizeObserver(() => {
    handleDualPageResize(container, state, onModeChange);
  });

  resizeObserver.observe(container);
}

function handleDualPageResize(
  container: HTMLElement,
  state: PDFDualPageViewState,
  onModeChange: (mode: DualPageMode) => void,
): PDFDualPageViewState {
  const viewportWidth = window.innerWidth;

  if (
    viewportWidth >= state.minViewportWidth &&
    state.currentMode === "single"
  ) {
    if (!hasManualDualPageOverride()) {
      return setDualPageMode(container, state, "dual", false, onModeChange);
    }
  } else if (
    viewportWidth < state.minViewportWidth &&
    state.currentMode === "dual"
  ) {
    return setDualPageMode(container, state, "single", false, onModeChange);
  }

  return state;
}

function setDualPageMode(
  container: HTMLElement,
  state: PDFDualPageViewState,
  mode: DualPageMode,
  manual: boolean,
  onModeChange: (mode: DualPageMode) => void,
): PDFDualPageViewState {
  if (state.currentMode === mode) return state;

  container.classList.remove("pdf-single-page", "pdf-dual-page");
  container.classList.add(
    mode === "dual" ? "pdf-dual-page" : "pdf-single-page",
  );

  if (manual) {
    setManualDualPageOverride(mode);
  }

  onModeChange(mode);

  return { ...state, currentMode: mode };
}

function toggleDualPageMode(
  container: HTMLElement,
  state: PDFDualPageViewState,
  onModeChange: (mode: DualPageMode) => void,
): PDFDualPageViewState {
  const newMode = state.currentMode === "single" ? "dual" : "single";
  return setDualPageMode(container, state, newMode, true, onModeChange);
}

function getDualPagePagePair(
  state: PDFDualPageViewState,
  currentPage: number,
  totalPages: number,
): { left?: number; right: number } {
  if (state.currentMode === "single") {
    return { right: currentPage };
  }

  if (currentPage % 2 === 1) {
    return {
      left: currentPage > 1 ? currentPage - 1 : undefined,
      right: currentPage,
    };
  } else {
    return {
      left: currentPage,
      right: currentPage < totalPages ? currentPage + 1 : currentPage,
    };
  }
}

function hasManualDualPageOverride(): boolean {
  return localStorage.getItem("pdf-dual-page-manual") === "true";
}

function setManualDualPageOverride(mode: DualPageMode): void {
  localStorage.setItem("pdf-dual-page-manual", "true");
  localStorage.setItem("pdf-dual-page-mode", mode);
}

function getDualPageStyles(): string {
  return `
    .pdf-dual-page .pdf-page-container {
      display: inline-block;
      vertical-align: top;
      width: 50%;
    }

    .pdf-dual-page .pdf-scroll-container {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
    }

    .pdf-single-page .pdf-page-container {
      display: block;
      width: 100%;
    }
  `;
}
