import EventEmitter from "events";
import { withLoader } from "../utils/loader";
import { getEvents } from "../api/atproto";
import { database } from "../services/db";
import { ToolsOzoneModerationDefs } from "@atproto/api";
import { chunkArray } from "@atproto/common";
import { transformModEventToRow } from "../services/event/transformers";

export const fetchEvents = async (options: {
  createdAfter?: string;
  createdBefore?: string;
  types?: string[];
  cursor?: string;
}) => {
  const emitter = new EventEmitter();
  const allEvents = await withLoader(
    `Fetching events...`,
    async (updateMessage) => {
      emitter.on("update", ({ nextCursor, eventCount, maxCount }) => {
        updateMessage(
          `Fetched page with cursor: ${nextCursor}, total events: ${eventCount} out of ${maxCount}`
        );
      });

      const { cursor, events } = await getEvents(options, emitter);
      updateMessage(`Fetched ${events.length} queue items. Cursor: ${cursor}`);
      return events;
    }
  );

  return allEvents;
};

export const saveEvents = async (
  events: ToolsOzoneModerationDefs.ModEventView[]
) => {
  await withLoader(
    `Storing ${events.length} events...`,
    async (updateMessage) => {
      if (events.length === 0) {
        updateMessage("No events to store");
        throw new Error("No events to store");
      }
      for (const chunk of chunkArray(events, 500)) {
        await database.insertEvents(chunk.map(transformModEventToRow));
        updateMessage(
          `Stored ${chunk.length} out of ${events.length} events in local database`
        );
      }
      updateMessage(`Stored ${events.length} events in local database`);
    }
  );
};