import html2canvas from "html2canvas";
import jsPDF from "jspdf";
import type { CanvasData, CanvasTemplate } from "@/lib/types";

/**
 * PDF Generation utilities using html2canvas + jsPDF
 * Provides one-click PDF download without print dialogs
 */

export interface PDFGenerationOptions {
  format: "A3" | "A4";
  orientation: "landscape" | "portrait";
  includeMetadata?: boolean;
  quality?: "draft" | "print";
}

export const defaultPDFOptions: PDFGenerationOptions = {
  format: "A3",
  orientation: "landscape",
  includeMetadata: true,
  quality: "print",
};

/**
 * Generate filename for canvas PDF
 */
export function generateFilename(canvas: CanvasTemplate, canvasData?: CanvasData): string {
  const team = canvasData?.metadata?.team || "equipe";
  const date = new Date().toISOString().split("T")[0];
  const title = canvas.title
    .toLowerCase()
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "") // Remove accents
    .replace(/[^a-z0-9]/g, "-")
    .replace(/-+/g, "-")
    .replace(/^-|-$/g, "");

  return `${title}_${team}_${date}.pdf`;
}

/**
 * Export a single canvas to PDF with one-click download
 * Uses html2canvas to capture the element and jsPDF to create the PDF
 * 
 * For A3 fixed canvases: temporarily removes CSS transform scaling
 * before capture to get the full-resolution image
 */
export async function exportCanvasToPDF(
  canvasElement: HTMLElement,
  canvas: CanvasTemplate,
  options: Partial<PDFGenerationOptions> = {}
): Promise<void> {
  const mergedOptions = { ...defaultPDFOptions, ...options };

  // A3 dimensions in mm: 420 x 297 (landscape)
  // A4 dimensions in mm: 297 x 210 (landscape)
  const pageWidth = mergedOptions.format === "A3" ? 420 : 297;
  const pageHeight = mergedOptions.format === "A3" ? 297 : 210;

  // Find the actual A3 fixed canvas element (might be a child of passed element)
  const a3Canvas = canvasElement.querySelector('.canvas-a3-fixed') as HTMLElement ||
    canvasElement.closest('.canvas-a3-fixed') as HTMLElement ||
    canvasElement;

  // Store original transform and remove it for capture
  const originalTransform = a3Canvas.style.transform;
  const originalMarginBottom = a3Canvas.style.marginBottom;

  // Remove transform scaling to capture at full resolution
  a3Canvas.style.transform = 'none';
  a3Canvas.style.marginBottom = '0';

  try {
    // Capture the canvas element using html2canvas at native A3 dimensions
    const htmlCanvas = await html2canvas(a3Canvas, {
      scale: 2, // Higher resolution for better quality (3174 x 2246 pixels)
      useCORS: true, // Allow cross-origin images
      allowTaint: true,
      backgroundColor: "#ffffff",
      logging: false,
      // Use the fixed A3 dimensions
      width: 1587,
      height: 1123,
      windowWidth: 1587,
      windowHeight: 1123,
    });

    // Create PDF with correct orientation
    const pdf = new jsPDF({
      orientation: mergedOptions.orientation,
      unit: "mm",
      format: mergedOptions.format.toLowerCase() as "a3" | "a4",
    });

    // Since we capture at A3 proportions (1587x1123 = 1.414 ratio),
    // it should fit perfectly into A3 page (420x297 = 1.414 ratio)
    // Just add the image to fill the page
    const imgData = htmlCanvas.toDataURL("image/png", 1.0);
    pdf.addImage(imgData, "PNG", 0, 0, pageWidth, pageHeight);

    // Generate filename and trigger download
    const filename = generateFilename(canvas);
    pdf.save(filename);
  } finally {
    // Restore original transform
    a3Canvas.style.transform = originalTransform;
    a3Canvas.style.marginBottom = originalMarginBottom;
  }
}

/**
 * Export a multi-page canvas to PDF with one-click download
 * Finds all pages within the container and exports each as a separate PDF page
 */
export async function exportMultiPageCanvasToPDF(
  containerElement: HTMLElement,
  canvas: CanvasTemplate,
  options: Partial<PDFGenerationOptions> = {}
): Promise<void> {
  const mergedOptions = { ...defaultPDFOptions, ...options };

  // A3 dimensions in mm: 420 x 297 (landscape)
  const pageWidth = mergedOptions.format === "A3" ? 420 : 297;
  const pageHeight = mergedOptions.format === "A3" ? 297 : 210;

  // Find all A3 canvas pages within the container
  const pageElements = containerElement.querySelectorAll('.canvas-a3-fixed[data-page-index]') as NodeListOf<HTMLElement>;

  // If no multi-page elements found, fall back to single page export
  if (pageElements.length === 0) {
    return exportCanvasToPDF(containerElement, canvas, options);
  }

  // Create PDF with correct orientation
  const pdf = new jsPDF({
    orientation: mergedOptions.orientation,
    unit: "mm",
    format: mergedOptions.format.toLowerCase() as "a3" | "a4",
  });

  for (let i = 0; i < pageElements.length; i++) {
    const pageElement = pageElements[i];

    // Add new page for subsequent canvases
    if (i > 0) {
      pdf.addPage();
    }

    // Store original transform and remove it for capture
    const originalTransform = pageElement.style.transform;
    const originalMarginBottom = pageElement.style.marginBottom;

    // Remove transform scaling to capture at full resolution
    pageElement.style.transform = 'none';
    pageElement.style.marginBottom = '0';

    try {
      // Capture the page element using html2canvas at native A3 dimensions
      const htmlCanvas = await html2canvas(pageElement, {
        scale: 2, // Higher resolution for better quality
        useCORS: true,
        allowTaint: true,
        backgroundColor: "#ffffff",
        logging: false,
        width: 1587,
        height: 1123,
        windowWidth: 1587,
        windowHeight: 1123,
      });

      // Add the image to fill the page
      const imgData = htmlCanvas.toDataURL("image/png", 1.0);
      pdf.addImage(imgData, "PNG", 0, 0, pageWidth, pageHeight);
    } finally {
      // Restore original transform
      pageElement.style.transform = originalTransform;
      pageElement.style.marginBottom = originalMarginBottom;
    }
  }

  // Generate filename and trigger download
  const filename = generateFilename(canvas);
  pdf.save(filename);
}

/**
 * Export multiple canvases to a single PDF
 */
export async function exportAllCanvasesToPDF(
  canvases: { element: HTMLElement; canvas: CanvasTemplate }[],
  options: Partial<PDFGenerationOptions> = {}
): Promise<void> {
  const mergedOptions = { ...defaultPDFOptions, ...options };

  const pageWidth = mergedOptions.format === "A3" ? 420 : 297;
  const pageHeight = mergedOptions.format === "A3" ? 297 : 210;

  // Create PDF
  const pdf = new jsPDF({
    orientation: mergedOptions.orientation,
    unit: "mm",
    format: mergedOptions.format.toLowerCase() as "a3" | "a4",
  });

  for (let i = 0; i < canvases.length; i++) {
    const { element } = canvases[i];

    // Add new page for subsequent canvases
    if (i > 0) {
      pdf.addPage();
    }

    // Capture the canvas element
    const htmlCanvas = await html2canvas(element, {
      scale: 2,
      useCORS: true,
      allowTaint: true,
      backgroundColor: "#ffffff",
      logging: false,
      width: element.scrollWidth,
      height: element.scrollHeight,
      windowWidth: element.scrollWidth,
      windowHeight: element.scrollHeight,
    });

    // Calculate scaling
    const imgWidth = htmlCanvas.width;
    const imgHeight = htmlCanvas.height;
    const imgAspectRatio = imgWidth / imgHeight;
    const pageAspectRatio = pageWidth / pageHeight;

    let finalWidth: number;
    let finalHeight: number;
    let offsetX = 0;
    let offsetY = 0;

    if (imgAspectRatio > pageAspectRatio) {
      finalWidth = pageWidth;
      finalHeight = pageWidth / imgAspectRatio;
      offsetY = (pageHeight - finalHeight) / 2;
    } else {
      finalHeight = pageHeight;
      finalWidth = pageHeight * imgAspectRatio;
      offsetX = (pageWidth - finalWidth) / 2;
    }

    // Add the image to the PDF
    const imgData = htmlCanvas.toDataURL("image/png", 1.0);
    pdf.addImage(imgData, "PNG", offsetX, offsetY, finalWidth, finalHeight);
  }

  // Save the combined PDF
  const date = new Date().toISOString().split("T")[0];
  pdf.save(`tous-les-canevas_${date}.pdf`);
}

// Legacy function - kept for backwards compatibility
export async function generatePDFServer(
  canvasId: string,
  options: Partial<PDFGenerationOptions> = {}
): Promise<string> {
  // This function is deprecated - use exportCanvasToPDF instead
  throw new Error(
    "generatePDFServer est obsolète. Utilisez exportCanvasToPDF à la place."
  );
}

export function downloadPDF(url: string, filename: string): void {
  const link = document.createElement("a");
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  setTimeout(() => URL.revokeObjectURL(url), 1000);
}
