// Different viewing modes for ebooks
// Feature Registration Pattern implementation

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

export function init(context: ReaderContext): void {
  let state: ViewModeState | null = null;

  context.events.on("reader:loaded", (detail: { container: HTMLElement }) => {
    state = { currentMode: "paginated", currentPage: 1 };
    setViewMode(detail.container, "paginated");
  });

  context.events.on("view-mode:set", (detail: { mode: ViewMode }) => {
    if (state && context.elements.readerContent) {
      state.currentMode = detail.mode;
      setViewMode(context.elements.readerContent, detail.mode);
      context.events.emit("view-mode:changed", { mode: detail.mode });
    }
  });

  context.events.on("view-mode:get", () => {
    if (state) {
      context.events.emit("view-mode:current", state);
    }
  });

  context.events.on("pagination:go-to-page", (detail: { page: number }) => {
    if (state && context.elements.readerContent) {
      state.currentPage = detail.page;
      goToPage(context.elements.readerContent, detail.page);
      context.events.emit("pagination:page-changed", { page: detail.page });
    }
  });
}

type ViewMode = "paginated" | "scrolled" | "single-column" | "double-column";

interface ViewModeState {
  currentMode: ViewMode;
  currentPage: number;
}

function setViewMode(container: HTMLElement, mode: ViewMode): void {
  const content = container.querySelector(".ebook-content");
  if (!content) return;

  const element = content as HTMLElement;

  element.classList.remove(
    "paginated",
    "scrolled",
    "single-column",
    "double-column",
  );

  switch (mode) {
    case "paginated":
      applyPaginatedMode(container, element);
      break;
    case "scrolled":
      applyScrolledMode(container, element);
      break;
    case "single-column":
      applySingleColumn(element);
      break;
    case "double-column":
      applyDoubleColumn(element);
      break;
  }
}

function applyPaginatedMode(
  container: HTMLElement,
  element: HTMLElement,
): void {
  element.classList.add("paginated");

  element.style.height = "100vh";
  element.style.overflow = "hidden";
  element.style.columnCount = "1";
  element.style.columnGap = "0";

  enablePagination(container, element);
}

function applyScrolledMode(container: HTMLElement, element: HTMLElement): void {
  element.classList.add("scrolled");

  element.style.height = "auto";
  element.style.overflowY = "auto";
  element.style.columnCount = "1";

  disablePagination(container);
}

function applySingleColumn(element: HTMLElement): void {
  element.classList.add("single-column");

  element.style.columnCount = "1";
  element.style.columnGap = "0";
  element.style.maxWidth = "800px";
  element.style.margin = "0 auto";
}

function applyDoubleColumn(element: HTMLElement): void {
  element.classList.add("double-column");

  element.style.columnCount = "2";
  element.style.columnGap = "60px";
  element.style.columnRule = "1px solid var(--text-secondary)";
  element.style.maxWidth = "1400px";
  element.style.margin = "0 auto";
}

function enablePagination(container: HTMLElement, element: HTMLElement): void {
  const totalHeight = element.scrollHeight;
  const pageHeight = element.clientHeight;
  const pageCount = Math.ceil(totalHeight / pageHeight);

  addPaginationControls(container, pageCount);
}

function disablePagination(container: HTMLElement): void {
  const controls = container.querySelector(".pagination-controls");
  controls?.remove();
}

function addPaginationControls(
  container: HTMLElement,
  pageCount: number,
): void {
  let currentPage = 1;

  const controls = document.createElement("div");
  controls.className =
    "pagination-controls fixed bottom-0 left-0 right-0 bg-opacity-95 backdrop-blur border-t";
  controls.innerHTML = `
    <button class="prev-page" ${currentPage === 1 ? "disabled" : ""}>← Previous</button>
    <span class="page-info">Page ${currentPage} of ${pageCount}</span>
    <button class="next-page" ${currentPage === pageCount ? "disabled" : ""}>Next →</button>
  `;

  controls.querySelector(".prev-page")?.addEventListener("click", () => {
    if (currentPage > 1) {
      currentPage--;
      goToPage(container, currentPage);
    }
  });

  controls.querySelector(".next-page")?.addEventListener("click", () => {
    if (currentPage < pageCount) {
      currentPage++;
      goToPage(container, currentPage);
    }
  });

  container.appendChild(controls);
}

function goToPage(container: HTMLElement, pageNumber: number): void {
  const content = container.querySelector(".ebook-content") as HTMLElement;
  if (!content) return;

  const pageHeight = content.clientHeight;
  const scrollTop = (pageNumber - 1) * pageHeight;

  content.scrollTo({
    top: scrollTop,
    behavior: "smooth",
  });

  const pageInfo = container.querySelector(".page-info");
  if (pageInfo) {
    pageInfo.textContent = `Page ${pageNumber} of ${getTotalPageCount(container)}`;
  }
}

function getTotalPageCount(container: HTMLElement): number {
  const content = container.querySelector(".ebook-content") as HTMLElement;
  if (!content) return 1;

  const totalHeight = content.scrollHeight;
  const pageHeight = content.clientHeight;

  return Math.ceil(totalHeight / pageHeight);
}

export function getCurrentViewMode(container: HTMLElement): ViewMode {
  const content = container.querySelector(".ebook-content") as HTMLElement;
  if (!content) return "paginated";

  if (content.classList.contains("paginated")) return "paginated";
  if (content.classList.contains("scrolled")) return "scrolled";
  if (content.classList.contains("single-column")) return "single-column";
  if (content.classList.contains("double-column")) return "double-column";

  return "paginated";
}