import type jsPDF from 'jspdf';
import type { PdfSettings } from '../services/config';

/**
 * Render text with basic markdown (**bold**) and line breaks into a jsPDF doc.
 * Returns the final Y position after rendering.
 */
export function renderMarkdownText(
  doc: jsPDF,
  text: string,
  x: number,
  y: number,
  options?: { fontSize?: number; lineHeight?: number },
): number {
  const fontSize = options?.fontSize ?? 9;
  const lineHeight = options?.lineHeight ?? fontSize * 0.5;
  doc.setFontSize(fontSize);
  doc.setTextColor(0, 0, 0);

  const lines = text.split('\n');
  let curY = y;

  for (const line of lines) {
    const segments = line.split('**');
    let curX = x;
    for (let i = 0; i < segments.length; i++) {
      const seg = segments[i];
      if (!seg) continue;
      const isBold = i % 2 === 1;
      doc.setFont('helvetica', isBold ? 'bold' : 'normal');
      doc.text(seg, curX, curY);
      curX += doc.getTextWidth(seg);
    }
    curY += lineHeight;
  }

  doc.setFont('helvetica', 'normal');
  return curY;
}

/** Load an image from a data URL and return its natural pixel dimensions. */
function getImageDimensions(src: string): Promise<{ w: number; h: number }> {
  return new Promise((resolve) => {
    const img = new Image();
    img.onload = () => resolve({ w: img.naturalWidth, h: img.naturalHeight });
    img.onerror = () => resolve({ w: 1, h: 1 });
    img.src = src;
  });
}

/**
 * Add a white-background PDF header matching the official template:
 * - Left:  pdf_header text (bold italic, multi-line org hierarchy)
 * - Right: org name (bold) + logo (aspect-ratio correct)
 * - Thin dark separator line below
 *
 * Does NOT render the document title — callers do that below the returned Y.
 * Returns Y position where document content should start.
 */
export async function addPdfHeader(
  doc: jsPDF,
  settings: PdfSettings,
  pageWidth: number,
): Promise<number> {
  const margin = 6;
  const rightEdge = pageWidth - margin;
  const logoMaxH = 16;

  // ── Right: logo (aspect-ratio-correct) ──
  const logoSrc = settings.app_logo || settings.pdf_logo;
  let logoLeftEdge = rightEdge;

  if (logoSrc) {
    try {
      const { w, h } = await getImageDimensions(logoSrc);
      const ratio = w / h;
      const logoH = logoMaxH;
      const logoW = logoH * ratio;
      const fmt = logoSrc.startsWith('data:image/png') ? 'PNG' : 'JPEG';
      const logoX = rightEdge - logoW;
      doc.addImage(logoSrc, fmt, logoX, 2, logoW, logoH);
      logoLeftEdge = logoX - 3;
    } catch { /* ignore invalid image */ }
  }

  // ── Right: org name (to the left of logo, vertically centred) ──
  if (settings.pdf_org_name) {
    doc.setFontSize(10);
    doc.setFont('helvetica', 'bold');
    doc.setTextColor(0, 0, 0);
    const nameW = doc.getTextWidth(settings.pdf_org_name);
    doc.text(settings.pdf_org_name, logoLeftEdge - nameW, 11);
  }

  // ── Left: pdf_header text (bold italic, multi-line) ──
  let headerEndY = 10;
  if (settings.pdf_header) {
    doc.setFontSize(8);
    doc.setTextColor(60, 60, 60);
    const headerLines = settings.pdf_header.split('\n');
    let hy = 8;
    for (const line of headerLines) {
      const segments = line.split('**');
      let hx = margin;
      for (let i = 0; i < segments.length; i++) {
        const seg = segments[i];
        if (!seg) continue;
        doc.setFont('helvetica', i % 2 === 1 ? 'bolditalic' : 'italic');
        doc.text(seg, hx, hy);
        hx += doc.getTextWidth(seg);
      }
      hy += 4;
    }
    headerEndY = hy;
  }

  // ── Separator line ──
  const lineY = Math.max(headerEndY, logoMaxH + 4) + 2;
  doc.setDrawColor(60, 60, 60);
  doc.setLineWidth(0.5);
  doc.line(margin, lineY, pageWidth - margin, lineY);

  // Reset styles
  doc.setFont('helvetica', 'normal');
  doc.setTextColor(0, 0, 0);
  doc.setFontSize(10);

  return lineY + 9;
}

/**
 * Returns a `didDrawPage` callback that renders pdf_footer (left) and
 * "Seite X/Y" page numbers (bottom right) on every page.
 */
export function addPdfFooter(
  doc: jsPDF,
  settings: PdfSettings,
): (data: any) => void {
  return (data: any) => {
    const pageHeight = doc.internal.pageSize.height;
    const pageWidth = doc.internal.pageSize.width;

    doc.setFontSize(8);
    doc.setFont('helvetica', 'normal');
    doc.setTextColor(100, 100, 100);

    if (settings.pdf_footer) {
      renderMarkdownText(doc, settings.pdf_footer, 10, pageHeight - 8, { fontSize: 8 });
    }

    const pageNum = data?.pageNumber ?? 1;
    const pageCount = data?.pageCount ?? 1;
    const pageText = `Seite ${pageNum}/${pageCount}`;
    const textWidth = doc.getTextWidth(pageText);
    doc.text(pageText, pageWidth - 10 - textWidth, pageHeight - 8);

    doc.setTextColor(0, 0, 0);
  };
}
