import jsPDF from 'jspdf';
import type { PdfFormField, PdfFormTemplate } from './types';

const PT = 72 / 96; // CSS px to PDF pt

function loadImage(url: string): Promise<HTMLImageElement> {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.crossOrigin = 'anonymous';
    img.onload = () => resolve(img);
    img.onerror = reject;
    img.src = url;
  });
}

export async function generatePdfForm(
  template: PdfFormTemplate,
  mode: 'print' | 'fillable' = 'print',
  logoUrl?: string | null
): Promise<jsPDF> {
  const isLandscape = template.page_settings.orientation === 'landscape';
  const doc = new jsPDF({ orientation: isLandscape ? 'l' : 'p', unit: 'pt', format: 'letter' });
  const pageW = doc.internal.pageSize.getWidth();
  const pageH = doc.internal.pageSize.getHeight();
  const m = template.page_settings.margins;
  const contentW = pageW - m.left - m.right;
  let y = m.top;

  // --- Header: Title on left, Logo on right ---
  const headerH = 50;
  // Title
  doc.setFontSize(16);
  doc.setFont('Helvetica', 'bold');
  doc.text(template.name, m.left, y + 20);

  // Logo
  if (logoUrl) {
    try {
      const img = await loadImage(logoUrl);
      const maxLogoH = 40;
      const maxLogoW = 120;
      const ratio = Math.min(maxLogoW / img.width, maxLogoH / img.height, 1);
      const w = img.width * ratio;
      const h = img.height * ratio;
      doc.addImage(img, 'PNG', m.left + contentW - w, y, w, h);
    } catch {
      // Skip logo if it can't load
    }
  }

  y += headerH;
  // Divider line under header
  doc.setDrawColor(180);
  doc.setLineWidth(0.5);
  doc.line(m.left, y, m.left + contentW, y);
  y += 12;

  const checkPageBreak = (needed: number) => {
    if (y + needed > pageH - m.bottom) {
      doc.addPage();
      y = m.top;
    }
  };

  for (const field of template.fields) {
    switch (field.type) {
      case 'text-line': {
        const lineCount = field.lineCount || 1;
        const lineH = (field.lineSpacing || 28) * PT;
        const labelH = 12;
        checkPageBreak(labelH + lineCount * lineH + 8);
        doc.setFontSize(9);
        doc.setFont('Helvetica', 'normal');
        doc.text(field.label, m.left, y + 9);
        y += labelH;
        for (let i = 0; i < lineCount; i++) {
          y += lineH;
          doc.setDrawColor(150);
          doc.setLineWidth(0.5);
          doc.line(m.left, y, m.left + contentW, y);
        }
        y += 8;
        break;
      }

      case 'signature-line': {
        const sigH = field.showPrintedName ? 90 : 55;
        checkPageBreak(sigH);
        y += 20;

        const dateW = field.showDate ? 120 : 0;
        const sigW = contentW - (field.showDate ? dateW + 30 : 0);

        // Signature line
        doc.setDrawColor(80);
        doc.setLineWidth(0.7);
        doc.line(m.left, y + 20, m.left + sigW, y + 20);
        doc.setFontSize(8);
        doc.setFont('Helvetica', 'normal');
        doc.text(field.label, m.left, y + 30);

        // Date line
        if (field.showDate) {
          const dateX = m.left + sigW + 30;
          doc.line(dateX, y + 20, dateX + dateW, y + 20);
          doc.text('Date', dateX, y + 30);
        }

        y += 35;

        // Printed name
        if (field.showPrintedName) {
          doc.setDrawColor(80);
          doc.line(m.left, y + 20, m.left + sigW, y + 20);
          doc.text('Printed Name', m.left, y + 30);
          y += 35;
        }

        y += 8;
        break;
      }

      case 'checkbox': {
        const opts = field.options || [];
        const cols = field.columns || 1;
        const rows = Math.ceil(opts.length / cols);
        const rowH = 18;
        checkPageBreak(14 + rows * rowH + 8);

        doc.setFontSize(9);
        doc.setFont('Helvetica', 'bold');
        doc.text(field.label, m.left, y + 9);
        y += 14;

        const colW = contentW / cols;
        doc.setFont('Helvetica', 'normal');
        doc.setFontSize(9);

        opts.forEach((opt, i) => {
          const col = i % cols;
          const row = Math.floor(i / cols);
          const x = m.left + col * colW;
          const yy = y + row * rowH;
          const boxSize = 10;

          if (mode === 'fillable') {
            // AcroForm checkbox
            (doc as any).checkBox?.(`cb_${field.id}_${i}`, x, yy, boxSize, boxSize);
          }
          // Always draw visual box
          doc.setDrawColor(80);
          doc.setLineWidth(0.5);
          doc.rect(x, yy, boxSize, boxSize);
          doc.text(opt, x + boxSize + 5, yy + 8);
        });

        y += rows * rowH + 8;
        break;
      }

      case 'text-block': {
        const fontSize = field.fontSize || 10;
        const fontStyle = field.bold && field.italic ? 'bolditalic' : field.bold ? 'bold' : field.italic ? 'italic' : 'normal';
        doc.setFontSize(fontSize);
        doc.setFont('Helvetica', fontStyle);

        const lines = doc.splitTextToSize(field.content || '', contentW);
        const lineH = fontSize * 1.4;
        const blockH = lines.length * lineH;
        checkPageBreak(blockH + 8);

        const align = field.alignment || 'left';
        let textX = m.left;
        if (align === 'center') textX = m.left + contentW / 2;
        if (align === 'right') textX = m.left + contentW;

        doc.text(lines, textX, y + fontSize, { align: align as any });
        y += blockH + 8;
        break;
      }

      case 'spacer': {
        const h = (field.height || 20) * PT;
        checkPageBreak(h);
        y += h;
        break;
      }
    }
  }

  return doc;
}
