import { jsPDF } from 'jspdf';

/**
 * Returns high-quality settings for jsPDF initialization.
 * @param {string} orientation - 'p', 'portrait', 'l', 'landscape'
 * @param {string} unit - 'pt', 'mm', 'cm', 'in'
 * @param {string} format - 'a4', 'letter', etc.
 * @returns {object} Configuration object for jsPDF
 */
export const getHighQualityPdfSettings = (orientation = 'portrait', unit = 'pt', format = 'letter') => {
  return {
    orientation,
    unit,
    format,
    compress: true, // Use compression to keep file size reasonable
    precision: 16    // Higher precision for vector positioning
  };
};

/**
 * Loads an image from a URL and returns high-quality data URL and dimensions.
 * Includes timeout and error handling.
 * @param {string} url - Image URL
 * @param {number} timeoutMs - Timeout in milliseconds (default 10000)
 * @returns {Promise<object|null>} Object containing dataURL, width, height, ratio
 */
export const loadImageHighQuality = (url, timeoutMs = 10000) => {
  return new Promise((resolve) => {
    if (!url || typeof url !== 'string') {
      resolve(null);
      return;
    }

    let isResolved = false;
    const safeResolve = (val) => {
      if (!isResolved) {
        isResolved = true;
        resolve(val);
      }
    };

    const img = new Image();
    img.crossOrigin = 'Anonymous';
    
    // Timeout handler
    const timer = setTimeout(() => {
      console.warn(`Image load timed out for URL: ${url}`);
      img.src = ""; // Stop loading
      safeResolve(null);
    }, timeoutMs);

    img.onload = () => {
      clearTimeout(timer);
      try {
        const canvas = document.createElement('canvas');
        // Use natural dimensions for full resolution
        canvas.width = img.naturalWidth || 100;
        canvas.height = img.naturalHeight || 100;
        const ctx = canvas.getContext('2d');
        // Enable high quality image smoothing
        ctx.imageSmoothingEnabled = true;
        ctx.imageSmoothingQuality = 'high';
        ctx.drawImage(img, 0, 0);
        
        // Use PNG to preserve transparency
        const dataURL = canvas.toDataURL('image/png');
        safeResolve({
          dataURL,
          width: img.naturalWidth || 100,
          height: img.naturalHeight || 100,
          ratio: (img.naturalWidth || 100) / (img.naturalHeight || 100)
        });
      } catch (e) {
        console.error("Error processing loaded image:", e);
        safeResolve(null);
      }
    };

    img.onerror = (e) => {
      clearTimeout(timer);
      console.warn("High-quality image load failed:", url);
      safeResolve(null);
    };

    try {
        img.src = url;
    } catch (e) {
        clearTimeout(timer);
        safeResolve(null);
    }
  });
};

/**
 * Applies an image to the PDF document with optimal quality settings.
 * @param {jsPDF} doc - The jsPDF document instance
 * @param {string|object} imageSource - URL, data URI, or object
 * @param {number} x - X coordinate
 * @param {number} y - Y coordinate
 * @param {number} width - Width on PDF
 * @param {number} height - Height on PDF
 */
export const applyHighQualityImageToPdf = async (doc, imageSource, x, y, width, height, options = {}) => {
  if (!imageSource || !doc) return;

  try {
    let data = imageSource;
    let imgWidth = 0;
    let imgHeight = 0;

    // If imageSource is a URL string, load it first
    if (typeof imageSource === 'string' && !imageSource.startsWith('data:') && imageSource.length < 2000) {
      const loaded = await loadImageHighQuality(imageSource);
      if (loaded) {
        data = loaded.dataURL;
        imgWidth = loaded.width;
        imgHeight = loaded.height;
      } else {
        return;
      }
    } else if (typeof imageSource === 'object' && imageSource.dataURL) {
      data = imageSource.dataURL;
      imgWidth = imageSource.width || 0;
      imgHeight = imageSource.height || 0;
    }

    if (typeof data !== 'string') return;

    // Smart crop: center-crop the image to fill the target area (like object-fit: cover)
    const shouldCrop = options.crop !== false && imgWidth > 0 && imgHeight > 0;

    if (shouldCrop) {
      const targetRatio = width / height;
      const srcRatio = imgWidth / imgHeight;

      let sx = 0, sy = 0, sw = imgWidth, sh = imgHeight;
      if (srcRatio > targetRatio) {
        // Source is wider — crop sides
        sw = Math.round(imgHeight * targetRatio);
        sx = Math.round((imgWidth - sw) / 2);
      } else {
        // Source is taller — crop top/bottom
        sh = Math.round(imgWidth / targetRatio);
        sy = Math.round((imgHeight - sh) / 2);
      }

      // Re-render cropped region to a canvas
      const canvas = document.createElement('canvas');
      const outW = Math.min(sw, 1200); // cap resolution for PDF size
      const outH = Math.round(outW * (sh / sw));
      canvas.width = outW;
      canvas.height = outH;
      const ctx = canvas.getContext('2d');
      ctx.imageSmoothingEnabled = true;
      ctx.imageSmoothingQuality = 'high';

      const img = new Image();
      img.src = data;
      await new Promise((res) => { img.onload = res; img.onerror = res; });
      ctx.drawImage(img, sx, sy, sw, sh, 0, 0, outW, outH);
      const croppedData = canvas.toDataURL('image/jpeg', 0.85);
      doc.addImage(croppedData, 'JPEG', x, y, width, height, undefined, 'FAST');
    } else {
      doc.addImage(data, 'PNG', x, y, width, height, undefined, 'FAST');
    }
  } catch (e) {
    console.error("Error applying high-quality image to PDF:", e);
  }
};