import html2canvas from 'html2canvas';
import { jsPDF } from 'jspdf';

export interface Options {
  filename?: string;
  compress?: boolean;
  scale?: number;
  callback?: () => void;
}

const noop = () => {};

export async function exportPdf(
  element: HTMLElement | null,
  options: Options = {},
): Promise<void> {
  const {
    filename = '未命名',
    compress = true,
    scale = 2,
    callback = noop,
  } = options;

  if (!element) {
    callback();
    return;
  }

  const originWidth = element.offsetWidth || 700;
  const container = document.createElement('div');
  container.style.cssText = `position:fixed;left:${-2 * originWidth}px;top:0;padding:0px;width:${originWidth}px;box-sizing:content-box;`;
  document.body.appendChild(container);
  container.appendChild(element.cloneNode(true));

  const render = async () => {
    try {
      const canvas = await html2canvas(container, { scale });
      const contentWidth = canvas.width;
      const contentHeight = canvas.height;

      // 一页全部展示
      // eslint-disable-next-line new-cap
      const doc = new jsPDF({
        orientation: contentWidth > contentHeight ? 'l' : 'p',
        unit: 'px',
        format: [contentWidth, contentHeight],
        compress,
      });
      doc.addImage({
        imageData: canvas,
        format: 'PNG',
        x: 0,
        y: 0,
        width: contentWidth,
        height: contentHeight,
        compression: 'FAST',
      });
      doc.save(`${filename}.pdf`);
    } catch (error) {
      console.error(`Error rendering PDF:`, error);
    } finally {
      container.remove();
      callback();
    }
  };

  const eleImgs = Array.from(container.querySelectorAll('img'));
  const { length } = eleImgs;
  let start = 0;
  if (length === 0) {
    await render();
    return;
  }

  eleImgs.forEach((ele) => {
    const { src } = ele;
    if (!src) return;
    ele.onload = () => {
      if (!/^http/.test(ele.src)) {
        start++;
        if (start === length) {
          render();
        }
      }
    };

    fetch(src)
      .then((res) => res.blob())
      .then((blob) => {
        const reader = new FileReader();
        reader.onload = () => {
          ele.src = reader.result as string;
        };
        reader.readAsDataURL(blob);
        return true;
      })
      .catch((error) => {
        start++;
        console.error(`Error fetching image:`, error);
        if (start === length) {
          render();
        }
      });
  });
}