// Track reading speed and update database
// Feature Registration Pattern implementation

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

let context: ReaderContext;

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

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

  context.events.on("reading-session:start", () => {
    if (state) {
      startReadingSession(state);
    }
  });

  context.events.on("page-changed", () => {
    if (state) {
      recordPageTurn(state);
    }
  });

  context.events.on("words-read", (detail: { wordCount: number }) => {
    if (state) {
      recordWordsRead(state, detail.wordCount);
    }
  });

  context.events.on("reading-session:end", async () => {
    if (state) {
      await syncReadingSpeed(state);
    }
  });

  context.events.on("reader:unload", async () => {
    if (state) {
      await syncReadingSpeed(state);
      state = null;
    }
  });
}

interface ReadingSpeedTrackerState {
  startTime: number | null;
  pagesRead: number;
  wordsRead: number;
  lastSync: number;
  mediaItemId: string;
}

function createReadingSpeedTracker(
  mediaItemId: string,
): ReadingSpeedTrackerState {
  return {
    startTime: null,
    pagesRead: 0,
    wordsRead: 0,
    lastSync: Date.now(),
    mediaItemId,
  };
}

function startReadingSession(
  state: ReadingSpeedTrackerState,
): ReadingSpeedTrackerState {
  state.startTime = Date.now();
  state.pagesRead = 0;
  state.wordsRead = 0;
  return state;
}

function recordPageTurn(
  state: ReadingSpeedTrackerState,
): ReadingSpeedTrackerState {
  if (!state.startTime) return state;

  state.pagesRead += 1;
  const now = Date.now();

  if (state.pagesRead % 5 === 0 || now - state.lastSync > 5 * 60 * 1000) {
    syncReadingSpeed(state);
    state.lastSync = now;
  }

  return state;
}

function recordWordsRead(
  state: ReadingSpeedTrackerState,
  wordCount: number,
): ReadingSpeedTrackerState {
  state.wordsRead += wordCount;
  return state;
}

async function syncReadingSpeed(
  state: ReadingSpeedTrackerState,
): Promise<void> {
  if (!state.startTime) return;

  const minutesElapsed = (Date.now() - state.startTime) / (1000 * 60);
  const pagesPerMinute = state.pagesRead / minutesElapsed;
  const wordsPerMinute = state.wordsRead / minutesElapsed;

  try {
    const token = localStorage.getItem("token");
    await fetch(`/readers/${state.mediaItemId}/reading-speed`, {
      method: "PUT",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${token}`,
      },
      body: JSON.stringify({
        pages_per_minute: pagesPerMinute,
        words_per_minute: wordsPerMinute,
        pages_read: state.pagesRead,
        total_reading_minutes: minutesElapsed,
      }),
    });
  } catch (error) {
    console.error("Failed to sync reading speed:", error);
  }
}
