import { PdfData } from "pdfdataextract";
import { config } from "./config";
import { IGetMetaResponse } from "./types";
import { verifyPDF } from "./lib";
import { formatPdfTime } from "./lib/timeUtils";
import { AppError, GeneralError } from "./lib/errors";
import { isPDF } from "./lib/generalUtils";
import { TimestampAndEnableLTV } from "./utils";

type SealCoords = {
  [key: string]: { x: string; y: string };
};

declare global {
  interface Window {
    PDFNet: any;
    CoreControls: any;
  }
}

class PDFparser {
  readonly document;

  constructor(document: Buffer) {
    this.document = document;
  }

  getPDFMeta = async (): Promise<IGetMetaResponse> => {
    if (!(this.document instanceof Buffer)) {
      throw new AppError("Document is not Buffer");
    }

    if (!isPDF(this.document)) {
      throw new AppError("Only pdf file type is supported");
    }

    try {
      const signaturesMeta = await verifyPDF(this.document);
      const pdfMeta = await PdfData.extract(this.document, config);

      const result = {
        pages: pdfMeta.pages,
        title: pdfMeta.info.Title || "Unknown",
        author: pdfMeta.info.Author || "Unknown",
        creation_date: formatPdfTime(pdfMeta.info.CreationDate),
        mod_date: formatPdfTime(pdfMeta.info.ModDate),
      };

      if (signaturesMeta) {
        result["signatures"] = signaturesMeta.signatures;
        result["expired"] = signaturesMeta.expired;
      }

      return result;
    } catch (error) {
      throw new GeneralError(error);
    }
  };

  insertQrCode = async (
    imgBytes: ArrayBuffer,
    url: string,
    coords: SealCoords,
    scaleFactor: number,
    licenseKey: string,
    certPath: string | ArrayBuffer,
    certTSAUrl: string
  ): Promise<ArrayBuffer> => {
    let lib, buf;
    if (typeof window !== `undefined`) {
      lib = window.PDFNet;
      const CoreControls = window.CoreControls;
      CoreControls.setWorkerPath("webviewer/core");
    } else {
      const pdflib = await import("@pdftron/pdfnet-node");
      lib = pdflib.PDFNet;
    }

    //will this work ??
    console.log(lib);
    try {
      await lib.initialize(licenseKey);
    } catch (e) {
      console.log(e);
    }

    try {
      buf = await TimestampAndEnableLTV(
        this.document,
        certPath,
        certTSAUrl,
        imgBytes,
        coords,
        lib
      );
    } catch (error) {
      console.log(error);
      throw new GeneralError("Could Not sign pdf");
    }

    await lib.shutdown();
    return buf;
  };
}

export default PDFparser;