import { GlobalWorkerOptions, getDocument } from 'pdfjs-dist/build/pdf.mjs';
import pdfWorker from 'pdfjs-dist/build/pdf.worker.mjs?url';

GlobalWorkerOptions.workerSrc = pdfWorker;

const cleanText = (value = '') =>
  value
    .replace(/\r/g, '')
    .replace(/\t/g, ' ')
    .replace(/\s+\n/g, '\n')
    .replace(/\n{3,}/g, '\n\n')
    .replace(/[ \u00A0]{2,}/g, ' ')
    .trim();

const extractPageText = async (page) => {
  const content = await page.getTextContent();
  const strings = content.items
    .map((item) => ('str' in item ? item.str : item?.unicode))
    .filter(Boolean)
    .map((text) => text.replace(/\s+/g, ' ').trim());
  return cleanText(strings.join(' '));
};

export const extractTextFromPdf = async (file) => {
  const arrayBuffer = await file.arrayBuffer();
  const pdf = await getDocument({ data: arrayBuffer }).promise;
  const texts = [];
  for (let pageNumber = 1; pageNumber <= pdf.numPages; pageNumber += 1) {
    // eslint-disable-next-line no-await-in-loop
    const page = await pdf.getPage(pageNumber);
    // eslint-disable-next-line no-await-in-loop
    const text = await extractPageText(page);
    if (text) {
      texts.push(text);
    }
  }
  let info = {};
  try {
    // pdf.getMetadata() resolves with info + metadata.
    // eslint-disable-next-line no-await-in-loop
    const metadata = await pdf.getMetadata();
    info = metadata?.info || {};
  } catch {
    info = {};
  }
  return {
    text: texts.join('\n\n').trim(),
    metadata: {
      title: info.Title || '',
      authors: info.Author ? [info.Author] : [],
      publisher: info.Producer || '',
      language: info.Language || '',
      publishedDate: info.CreationDate || '',
      description: '',
      identifiers: info.Identifier ? [{ identifier: info.Identifier }] : [],
      filename: file.name,
      fileSize: file.size,
      pageCount: pdf.numPages,
    },
  };
};
