// Parser Manager - Routes files to appropriate parsers
// Procedural style: Functions, not classes

// ============================================================
// Parser Registry
// ============================================================

const PARSER_REGISTRY: ParserEntry[] = [
  {
    format: "epub",
    mimeType: "application/epub+zip",
    extensions: [".epub"],
    side: "client",
  },
  {
    format: "fb2",
    mimeType: "application/fb2",
    extensions: [".fb2", ".fb2.zip"],
    side: "client",
  },
  {
    format: "txt",
    mimeType: "text/plain",
    extensions: [".txt"],
    side: "client",
  },
  {
    format: "html",
    mimeType: "text/html",
    extensions: [".html", ".htm"],
    side: "client",
  },
  {
    format: "mobi",
    mimeType: "application/x-mobipocket-ebook",
    extensions: [".mobi", ".azw"],
    side: "server",
  },
  {
    format: "azw3",
    mimeType: "application/vnd.amazon.mobi8-ebook",
    extensions: [".azw3"],
    side: "server",
  },
  {
    format: "docx",
    mimeType:
      "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    extensions: [".docx"],
    side: "server",
  },
  {
    format: "rtf",
    mimeType: "application/rtf",
    extensions: [".rtf"],
    side: "server",
  },
];

interface ParserEntry {
  format: string;
  mimeType: string;
  extensions: string[];
  side: "client" | "server";
}

// ============================================================
// Parser Detection
// ============================================================

export function detectParserFormat(
  mimeType: string,
  extension: string,
): ParserEntry | null {
  return (
    PARSER_REGISTRY.find(
      (entry) =>
        entry.mimeType === mimeType ||
        entry.extensions.includes(extension.toLowerCase()),
    ) || null
  );
}

export function requiresServerParsing(
  mimeType: string,
  extension: string,
): boolean {
  const entry = detectParserFormat(mimeType, extension);
  return entry?.side === "server" || false;
}

// ============================================================
// Main Parse Function (Router)
// ============================================================

export async function parseEbook(
  file: Blob,
  mimeType: string,
  extension: string,
): Promise<EbookCIF> {
  const entry = detectParserFormat(mimeType, extension);

  if (!entry) {
    throw new Error(`Unsupported ebook format: ${mimeType}, ${extension}`);
  }

  if (entry.side === "server") {
    return parseEbookOnServer(file, entry.format);
  } else {
    return parseEbookOnClient(file, entry.format);
  }
}

// ============================================================
// Client-Side Parsing
// ============================================================

async function parseEbookOnClient(
  file: Blob,
  format: string,
): Promise<EbookCIF> {
  switch (format) {
    case "epub": {
      const { parseEPUB } = await import("../parsers/epub-parsers");
      return parseEPUB(file);
    }
    case "fb2": {
      const { parseFB2 } = await import("../parsers/fb2-parser");
      return parseFB2(file);
    }
    case "txt": {
      const { parseTXT } = await import("../parsers/txt-parser");
      return parseTXT(file);
    }
    case "html": {
      const { parseHTML } = await import("../parsers/html-parser");
      return parseHTML(file);
    }
    default:
      throw new Error(`Client-side parser not implemented for: ${format}`);
  }
}

// ============================================================
// Server-Side Parsing (API Call)
// ============================================================

async function parseEbookOnServer(
  file: Blob,
  format: string,
): Promise<EbookCIF> {
  const formData = new FormData();
  formData.append("file", file);
  formData.append("format", format);

  const response = await fetch("/readers/parse", {
    method: "POST",
    body: formData,
  });

  if (!response.ok) {
    throw new Error(`Server parsing failed: ${response.statusText}`);
  }

  return await response.json();
}
