import readline from "node:readline";
import os from "os";
import { pdf } from "pdf-to-img";
import sharp from "sharp";

let isPrompting = false; // prevent multiple prompts at the same time

export async function askOtp() {
  console.log("ASKING OTP");
  if (isPrompting) return null; // prevent multiple prompts
  isPrompting = true;
  console.log("is not prompting");

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });

  const question = (query) =>
    new Promise((resolve) => rl.question(query, resolve));

  try {
    console.log("-----------");
    const enteredOtp = await question("Enter OTP: ");
    console.log("-----------");
    isPrompting = false;
    rl.close();
    return enteredOtp.trim();
  } catch (error) {
    console.log("Error");
  }
}

export function notPrompting() {
  isPrompting = false;
}

export function getDeviceInfo() {
  return {
    os: {
      platform: os.platform(),
      type: os.type(),
      release: os.release(),
      arch: os.arch(),
      hostname: os.hostname(),
    },
    cpu: {
      cores: os.cpus().length,
      model: os.cpus()[0].model,
      speedMHz: os.cpus()[0].speed,
    },
    user: os.userInfo(),
    process: {
      nodeVersion: process.version,
      execPath: process.execPath,
    },
  };
}

/**
 * Converts a PDF buffer or file path to an array of image buffers
 * @param {Buffer|string} pdfInput - PDF buffer or file path
 * @param {Object} options - Conversion options (optional)
 * @param {number} options.scale - Scale factor for image resolution (default: 2)
 * @param {number} options.width - Target width in pixels (will calculate scale if provided)
 * @param {number} options.height - Target height in pixels (optional)
 * @param {number[]} options.page_numbers - Array of page numbers to convert (optional, converts all pages by default)
 * @returns {Promise<Buffer[]>} Array of image buffers, one for each page
 */
export async function convertPDFToImage(pdfInput, options = {}) {
  try {
    // pdf-to-img uses scale instead of width/height directly
    // Default scale of 2 provides good quality for thermal printers
    let scale = options.scale || 2;

    const pdfOptions = {
      scale,
      ...options,
    };

    const document = await pdf(pdfInput, pdfOptions);
    const outputImages = [];

    // If specific page numbers are requested, use getPage() for each
    if (
      options.page_numbers &&
      Array.isArray(options.page_numbers) &&
      options.page_numbers.length > 0
    ) {
      for (const pageNum of options.page_numbers) {
        // page numbers are 1-indexed in the API
        let image = await document.getPage(pageNum);

        // Resize with Sharp if width or height are provided
        if (options.width || options.height) {
          const resizeOptions = {};
          if (options.width) resizeOptions.width = options.width;
          if (options.height) resizeOptions.height = options.height;
          image = await sharp(image).resize(resizeOptions).toBuffer();
        }

        outputImages.push(image);
      }
    } else {
      // Convert all pages: async iterable to array
      for await (const image of document) {
        let processedImage = image;

        // Resize with Sharp if width or height are provided
        if (options.width || options.height) {
          const resizeOptions = {};
          if (options.width) resizeOptions.width = options.width;
          if (options.height) resizeOptions.height = options.height;
          processedImage = await sharp(image).resize(resizeOptions).toBuffer();
        }

        outputImages.push(processedImage);
      }
    }

    return outputImages; // Array of image buffers
  } catch (error) {
    console.error("Error converting PDF to image:", error);
    throw error;
  }
}
