/* eslint-disable no-restricted-syntax */
import Promise from 'bluebird';
import {
  PDFDocument, StandardFonts, rgb, degrees,
} from 'pdf-lib';
import download from 'downloadjs';
import { loggerPlugin } from '@/plugins/logger';

/**
 *
 * @param {string} text
 * @returns {Promise<Buffer>}
 */
export const createPdf = async (text) => {
  const pdfDoc = await PDFDocument.create();

  const fontStyle = await pdfDoc.embedFont(StandardFonts.TimesRoman);
  const fontSize = 10;

  const pdfPage = pdfDoc.addPage();
  const { height } = pdfPage.getSize();

  pdfPage.drawText(text, {
    x: 50,
    y: height - 4 * fontSize,
    size: fontSize,
    font: fontStyle,
  });

  const pdfExport = await pdfDoc.save();

  return pdfExport;
};

/**
 *
 * @param {Buffer} fileBuffer
 * @param {string} fileName
 * @returns
 */
export const saveAsPdf = async (fileBuffer, fileName) => {
  return download(fileBuffer, fileName, 'application/pdf');
};

/**
 *
 * @param {string} fileUrl
 * @returns
 */
export const getPdfBuffer = async (fileUrl) => {
  const response = await fetch(fileUrl);

  return response.blob();
};

/**
 *
 * @param {Buffer} pdfBytes
 * @returns {string}
 */
export const getUrlBlobPdf = (pdfBytes) => {
  const blob = new Blob([pdfBytes], { type: 'application/pdf' });
  const url = URL.createObjectURL(blob);
  return url;
};

/**
 *
 * @param {Buffer} pdfBuffer
 * @param {string} text
 * @returns {Promise<Buffer>}
 */
export const addTextPdf = async (pdfBuffer, text) => {
  const pdfDoc = await PDFDocument.load(pdfBuffer);

  const fontStyle = await pdfDoc.embedFont(StandardFonts.Helvetica);
  const fontSize = 20;

  const listPage = pdfDoc.getPages();

  listPage.forEach((page) => {
    page.drawText(text, {
      x: 10,
      y: 20,
      size: fontSize,
      font: fontStyle,
      color: rgb(0, 0, 0),
    });
  });

  return pdfDoc.save();
};

/**
 *
 * @param {Buffer[]} listPdfBuffer
 * @returns {Promise<Buffer>}
 */
export const mergeListPdf = async (listPdfBuffer) => {
  const mergedPdf = await PDFDocument.create();

  await Promise.mapSeries(listPdfBuffer, async (pdfBuffer) => {
    try {
      const pdfFile = await PDFDocument.load(pdfBuffer);

      const listPage = await mergedPdf.copyPages(pdfFile, pdfFile.getPageIndices());
      listPage.forEach((page) => mergedPdf.addPage(page));
    } catch (error) {
      loggerPlugin.error({
        msg: 'ERROR_MERGING_FILE_PDF',
        error,
      });
      return '';
    }
  });

  return mergedPdf.save();
};

export const wartermarkPdf = async (
  pdfBuffer,
  imageBuffer,
  options = {},
) => {
  const pdfDoc = await PDFDocument.load(pdfBuffer);

  const wartermarkImg = await pdfDoc.embedPng(imageBuffer);

  const listPage = pdfDoc.getPages();

  listPage.forEach((page) => {
    page.drawImage(wartermarkImg, {
      opacity: 1,
      width: 200,
      height: 200,
      y: 100,
      x: 20,
      ...options,
    });
  });

  return pdfDoc.save();
};

export const getMetaPdf = async (pdfBuffer) => {
  const result = {
    pageCount: 0,
  };

  const pdfDoc = await PDFDocument.load(pdfBuffer);

  result.pageCount = await pdfDoc.getPageCount();

  return result;
};

export const reRenderPdf = async (
  pdfBuffer,
  options = {
    text: '',
    size: 0,
    marginX: 0,
    marginY: 0,
    rotation: 0,
  },
) => {
  const pdfDoc = await PDFDocument.load(pdfBuffer);

  const font = await pdfDoc.embedFont(StandardFonts.HelveticaBold);

  const totalPage = await pdfDoc.getPageCount();
  const listPage = pdfDoc.getPages();

  listPage.forEach((pageData, pageIndex) => {
    const drawText = [options.text || '', `(${pageIndex + 1}/${totalPage})`].filter((val) => val).join(' - ');

    const { height } = pageData.getSize();

    pageData.drawText(drawText, {
      x: options.marginX || 10,
      y: height - (height - (options.marginY || 20)),
      size: options.size || 20,
      font,
      rotate: degrees(-(options.rotation || 0)),
    });
  });

  return pdfDoc.save();
};
