import { getDocument, GlobalWorkerOptions, PDFDocumentProxy } from 'pdfjs-dist';
import { TextItem } from 'pdfjs-dist/types/src/display/api';

export function webOpenOpenFileDialog(filterPattern: string, fnStartLoading: Function | undefined): Promise<{
  blob: Blob,
  content?: string
}> {
  return new Promise((resolve, reject) => {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = filterPattern
    .replaceAll('*.txt', 'text/plain')
    .replace('*.midi', 'audio/midi')
    .replace('*.mid', 'audio/midi')
    .replaceAll('*.', 'application/')
    .replaceAll(';', ',');

    input.onchange = async e => {
      // @ts-ignore
      const file: Blob = e.target?.files[0];
      if (fnStartLoading && typeof fnStartLoading === 'function')
        fnStartLoading();
      if (!GlobalWorkerOptions.workerSrc && file.type === 'application/pdf')
        // @ts-ignore
        GlobalWorkerOptions.workerSrc = await import('pdfjs-dist/build/pdf.worker.min.mjs');
      if (file.type === 'text/plain') {
        const reader = new FileReader();
        reader.readAsText(file, 'UTF-8');

        reader.onload = event => {
          const content = event.target?.result as string;
          resolve({
            blob: file,
            content: content
          });
        };
        reader.onerror = reject;
      } else if (file.type === 'application/pdf') {
        const readPDFPage = async (doc: PDFDocumentProxy, pageNo: number) => {
          const page = await doc.getPage(pageNo);
          const tokenizedText = await page.getTextContent();
          return tokenizedText.items.map(token => (token as TextItem).str).join('');
        };
        let reader = new FileReader();
        reader.readAsArrayBuffer(file);

        reader.onload = async (event) => {
          try {
            const doc = await getDocument(event.target?.result!).promise;
            const pageTextPromises = [];
            for (let pageNo = 1; pageNo <= doc.numPages; pageNo++) {
              pageTextPromises.push(readPDFPage(doc, pageNo));
            }
            const pageTexts = await Promise.all(pageTextPromises);
            let content;
            if (pageTexts.length === 1)
              content = pageTexts[0];
            else
              content = pageTexts.map((p, i) => `Page ${i + 1}:\n${p}`).join('\n\n');
            resolve({
              blob: file,
              content: content
            });
          } catch (err) {
            reject(err);
          }
        };
        reader.onerror = reject;
      } else {
        resolve({
          blob: file
        });
      }
    };
    input.click();
  });
}