import type { ReaderContext } from "../core/reader-context";
interface ProgressDisplay {
  mode: "pages" | "chapter" | "percentage" | "time-left";
  text: string;
}

let context: ReaderContext;

export async function init(readerContext: ReaderContext): Promise<void> {
  context = readerContext;
  context.events.on("pageChanged", () => {
    updateProgressDisplay(context);
  });
  context.events.on("progressUpdated", () => {
    updateProgressDisplay(context);
  });
  setupProgressModeCycling(context);
}
export { calculateProgress, cycleProgressMode };
export type { ProgressDisplay };
function calculateProgress(
  currentPage: number,
  totalPages: number,
  currentChapterPage: number,
  chapterPages: number,
  readingSpeed?: ReadingSpeed,
): ProgressDisplay {
  const mode = getCurrentProgressMode();
  switch (mode) {
    case "pages":
      return {
        mode: "pages",
        text: `${currentPage}/${totalPages}`,
      };
    case "chapter":
      return {
        mode: "chapter",
        text: `${currentChapterPage}/${chapterPages}`,
      };
    case "percentage":
      const percentage = Math.round((currentPage / totalPages) * 100);
      return {
        mode: "percentage",
        text: `${percentage}%`,
      };
    case "time-left":
      if (!readingSpeed || readingSpeed.pages_per_minute === 0) {
        return { mode: "time-left", text: "--:--" };
      }
      const pagesLeft = totalPages - currentPage;
      const minutesLeft = pagesLeft / readingSpeed.pages_per_minute;
      const hours = Math.floor(minutesLeft / 60);
      const mins = Math.round(minutesLeft % 60);
      return {
        mode: "time-left",
        text: `${hours}h ${mins}m`,
      };
    default:
      return { mode: "pages", text: `${currentPage}/${totalPages}` };
  }
}
function cycleProgressMode(): void {
  const modes: Array<"pages" | "chapter" | "percentage" | "time-left"> = [
    "pages",
    "chapter",
    "percentage",
    "time-left",
  ];
  const currentMode = getCurrentProgressMode();
  const currentIndex = modes.indexOf(currentMode);
  const nextMode = modes[(currentIndex + 1) % modes.length];
  setProgressMode(nextMode);
}
function getCurrentProgressMode(): ReaderSettings["progress_mode"] {
  const settingsStr = localStorage.getItem("reader_settings_progress_mode");
  if (settingsStr) {
    try {
      return JSON.parse(settingsStr);
    } catch {
      return "pages";
    }
  }
  return "pages";
}
function setProgressMode(mode: ReaderSettings["progress_mode"]): void {
  localStorage.setItem("reader_settings_progress_mode", JSON.stringify(mode));

  const display = document.getElementById("progress-display");
  if (display) {
    display.dataset.mode = mode;
  }
}
async function getReadingSpeed(): Promise<ReadingSpeed | null> {
  const speedStr = localStorage.getItem("reader_speed_data");
  if (speedStr) {
    try {
      return JSON.parse(speedStr);
    } catch {
      return null;
    }
  }
  return null;
}
function updateProgressDisplay(context: ReaderContext): void {
  const state = context.getState();
  const display = context.elements.progressDisplay;
  if (!display || !state.currentReader) return;
  let currentPage = 0;
  let totalPages = 0;
  if (state.currentReader.type === "ebook") {
    currentPage = state.currentReader.currentSpineIndex + 1;
    totalPages = state.currentReader.cif.spine.length;
  } else if (state.currentReader.type === "pdf") {
    currentPage = state.currentReader.currentPage;
    totalPages = state.readerMetadata?.total_pages || 0;
  } else {
    currentPage = state.currentReader.currentPage;
    totalPages = state.currentReader.images.length;
  }
  getReadingSpeed().then((speed) => {
    const result = calculateProgress(
      currentPage,
      totalPages,
      0,
      0,
      speed || undefined,
    );
    display.textContent = result.text;
    display.dataset.mode = result.mode;
  });
}
function setupProgressModeCycling(context: ReaderContext): void {
  const display = context.elements.progressDisplay;
  if (!display) return;
  display.style.cursor = "pointer";
  display.addEventListener("click", () => {
    cycleProgressMode();
    updateProgressDisplay(context);
  });
}
