import jsPDF from 'jspdf';

export interface InvoiceDataPayload {
  invoiceId: string;
  registrationId: string;
  transactionId?: string;
  date: string;
  subtotal: string;
  tax: string;
  taxLabel?: string;
  total: string;
  totalClassValue?: string;
  pricePerLesson?: string;
  priceSuffix?: string;
  paymentFrequencyLabel?: string;
  lessonCount?: string;
  currency: string;
  paymentStatus: string;
  paymentMethod: string;
  programName: string;
  instructorName: string;
  startDate: string;
  classTime: string;
  location: string;
  parentName: string;
  parentEmail: string;
  parentLeadId: string;
  childName: string;
  childAgeGroup: string;
  childId: string;
  companyName?: string;
  companyAddress?: string;
}

const currencySymbolFor = (currency: string) =>
  currency === "USD" ? "$" : `${currency} `;

// Color Palette
const primaryBlue: [number, number, number] = [0, 151, 220];      
const textDark: [number, number, number] = [51, 51, 51];          
const textGray: [number, number, number] = [119, 119, 119];       
const white: [number, number, number] = [255, 255, 255];          

const loadLogo = async (doc: jsPDF, margin: number, y: number): Promise<void> => {
  const logoUrl = "https://yefranchisees.b-cdn.net/media/super_admin/1765876542596_h5zysjyuz2_1763553376085_6ko0s4sekh8_qualiti_logo.png";
  return new Promise<void>((resolve) => {
    const img = new window.Image();
    img.crossOrigin = "Anonymous"; 
    img.onload = () => {
      const imgWidth = 55;
      const imgHeight = (img.height * imgWidth) / img.width; 
      doc.addImage(img, 'PNG', margin, y, imgWidth, imgHeight);
      resolve();
    };
    img.onerror = () => resolve();
    img.src = logoUrl;
  });
};

// ─────────────────────────────────────────────────────────────────────────────
// GENERATOR 1: THE PROPER INVOICE (With Tax, Subtotal, Total Table)
// ─────────────────────────────────────────────────────────────────────────────
// ─────────────────────────────────────────────────────────────────────────────
// GENERATOR 1: THE UPDATED INVOICE (Tax moved to Totals Section)
// ─────────────────────────────────────────────────────────────────────────────
export const generateStandardInvoicePDF = async (data: InvoiceDataPayload) => {
  const doc = new jsPDF();
  const pageWidth = doc.internal.pageSize.getWidth();
  const pageHeight = doc.internal.pageSize.getHeight();
  const margin = 20;
  
  // ---------------------------------------------------------------------------
  // TOP RIBBON & INVOICE TITLE
  // ---------------------------------------------------------------------------
  doc.setFillColor(...primaryBlue);
  doc.rect(0, 0, pageWidth, 18, 'F'); 
  
  doc.setTextColor(...white);
  doc.setFontSize(20);
  doc.setFont('helvetica', 'bold');
  doc.text('INVOICE', pageWidth / 2, 13, { align: 'center' });

  // Load Logo
  let y = 25; 
  await loadLogo(doc, margin, y);

  // ---------------------------------------------------------------------------
  // LEFT HEADER: Company Info (Below Logo)
  // ---------------------------------------------------------------------------
  y = 50; 
  doc.setFontSize(10);
  doc.setFont('helvetica', 'bold');
  doc.setTextColor(30, 60, 90); 
  doc.text(data.companyName || '', margin, y);
  
  doc.setFont('helvetica', 'normal');
  doc.setFontSize(9);
  doc.setTextColor(...textDark);
  
  if (data.companyAddress) {
    const addressLines = doc.splitTextToSize(data.companyAddress, 80);
    doc.text(addressLines, margin, y + 5);
  }

  // ---------------------------------------------------------------------------
  // RIGHT HEADER: Invoice Number & Balance Due
  // ---------------------------------------------------------------------------
  doc.setFontSize(10);
  doc.setFont('helvetica', 'bold');
  doc.setTextColor(...textDark);
  doc.text(`# ${data.invoiceId}`, pageWidth - margin, 35, { align: 'right' });
  
  doc.setFontSize(9);
  doc.setFont('helvetica', 'bold');
  doc.setTextColor(...textGray);
  doc.text('Balance Due', pageWidth - margin, 48, { align: 'right' });
  
  doc.setFontSize(12);
  doc.setTextColor(...textDark);
  const currencySymbol = currencySymbolFor(data.currency);
  const balanceDue =
    data.paymentStatus === "PAID" ? 0 : Math.max(0, parseFloat(data.total) || 0);
  doc.text(`${currencySymbol}${balanceDue.toFixed(2)}`, pageWidth - margin, 54, { align: 'right' }); 

  // ---------------------------------------------------------------------------
  // MIDDLE SECTION: Bill To & Invoice Meta Data
  // ---------------------------------------------------------------------------
  y = 80; 
  
  // Left Side: Bill To
  doc.setFontSize(9);
  doc.setTextColor(...textGray);
  doc.setFont('helvetica', 'normal');
  doc.text('Bill To', margin, y);
  
  doc.setFontSize(10);
  doc.setTextColor(...textDark);
  doc.setFont('helvetica', 'bold');
  doc.text(data.parentName, margin, y + 6);
  
  doc.setFontSize(9);
  doc.setFont('helvetica', 'normal');
  doc.setTextColor(...textGray);
  let billToY = y + 11;
  if (data.parentEmail) {
    doc.text(data.parentEmail, margin, billToY);
    billToY += 5;
  }
  if (data.childName) {
    doc.text(`Child: ${data.childName}`, margin, billToY);
    billToY += 5;
  }

  // Right Side: Dates and Terms
  const labelX = pageWidth - margin - 35;
  const valueX = pageWidth - margin;
  
  doc.setTextColor(...textGray);
  doc.text('Invoice Date :', labelX, y, { align: 'right' });
  doc.setTextColor(...textDark);
  doc.text(data.date, valueX, y, { align: 'right' });
  
  doc.setTextColor(...textGray);
  doc.text('Terms :', labelX, y + 8, { align: 'right' });
  doc.setTextColor(...textDark);
  doc.text('Due on Receipt', valueX, y + 8, { align: 'right' });
  
  doc.setTextColor(...textGray);
  doc.text('Due Date :', labelX, y + 16, { align: 'right' });
  doc.setTextColor(...textDark);
  doc.text(data.date, valueX, y + 16, { align: 'right' });

  // ---------------------------------------------------------------------------
  // TABLE HEADER
  // ---------------------------------------------------------------------------
  y = 115;
  doc.setFillColor(51, 51, 51); 
  doc.rect(margin, y, pageWidth - (margin * 2), 12, 'F');
  
  doc.setTextColor(...white);
  doc.setFontSize(9);
  doc.setFont('helvetica', 'normal');
  
  const col1 = margin + 5;           // #
  const col2 = margin + 20;          // Item & Description
  const col3 = pageWidth - 100;      // Qty
  const col4 = pageWidth - 60;       // Rate
  const col5 = pageWidth - margin - 5; // Amount
  
  doc.text('#', col1, y + 8);
  doc.text('Item & Description', col2, y + 8);
  doc.text('Qty', col3, y + 8, { align: 'right' });
  doc.text('Rate', col4, y + 8, { align: 'right' });
  doc.text('Amount', col5, y + 8, { align: 'right' });

  // ---------------------------------------------------------------------------
  // TABLE BODY
  // ---------------------------------------------------------------------------
  y += 12;
  doc.setTextColor(...textDark);
  
  // Row 1 (Main Product)
  let rowY = y + 10; 
  doc.setFont('helvetica', 'normal');
  doc.text('1', col1, rowY);
  
  doc.setFont('helvetica', 'normal');
  doc.text(data.programName, col2, rowY);
  
  doc.setFontSize(8);
  doc.setTextColor(100, 100, 100);
  const metaLines: string[] = [];
  if (data.childName) metaLines.push(`Child: ${data.childName}`);
  if (data.lessonCount) metaLines.push(`Lessons: ${data.lessonCount}`);
  if (data.pricePerLesson) {
    metaLines.push(`Unit price: ${currencySymbol}${data.pricePerLesson} ${data.priceSuffix || "per lesson"}`);
  }
  if (metaLines.length > 0) {
    doc.setFontSize(8);
    doc.setTextColor(100, 100, 100);
    doc.text(metaLines.join(' | '), col2, rowY + 5);
  }
  
  doc.setFontSize(9);
  doc.setTextColor(...textDark);
  const amountVal = parseFloat(data.total).toFixed(2);
  doc.text('1.00', col3, rowY, { align: 'right' });
  doc.text(amountVal, col4, rowY, { align: 'right' });
  doc.text(amountVal, col5, rowY, { align: 'right' });

  // Separator Line for Row 1
  rowY += 12; 
  doc.setDrawColor(210, 210, 210);
  doc.setLineWidth(0.5);
  doc.line(margin, rowY, pageWidth - margin, rowY);

  // ---------------------------------------------------------------------------
  // TOTALS & BALANCE DUE SECTION
  // ---------------------------------------------------------------------------
  y = rowY + 8; 
  const totalsLabelX = pageWidth - margin - 40;
  const totalsValueX = pageWidth - margin - 5;
  
  doc.setFontSize(9);
  doc.setTextColor(...textGray); 
  doc.setFont('helvetica', 'normal');
  
  // Subtotal 
  doc.text('Subtotal:', totalsLabelX, y, { align: 'right' });
  doc.setTextColor(...textDark);
  doc.text(`${currencySymbol}${parseFloat(data.subtotal).toFixed(2)}`, totalsValueX, y, { align: 'right' });
  
  // Tax (Dynamically calculates percentage)
  y += 8; 
  doc.setTextColor(...textGray);
  const taxValNum = parseFloat(data.tax) || 0;
  const subtotalNum = parseFloat(data.subtotal) || 0;
  const taxPercentage = subtotalNum > 0 ? ((taxValNum / subtotalNum) * 100).toFixed(0) : 0;
  const taxName = data.taxLabel || 'Tax';
  doc.text(`${taxName} (${taxPercentage}%):`, totalsLabelX, y, { align: 'right' });
  doc.setTextColor(...textDark);
  doc.text(`${currencySymbol}${taxValNum.toFixed(2)}`, totalsValueX, y, { align: 'right' });
  
  // Total 
  y += 8; 
  doc.setTextColor(...textGray);
  doc.text('Total:', totalsLabelX, y, { align: 'right' });
  doc.setTextColor(...textDark);
  doc.text(`${currencySymbol}${parseFloat(data.total).toFixed(2)}`, totalsValueX, y, { align: 'right' });
  
  // Payment Made (Red)
  y += 8; 
  doc.setTextColor(...textGray);
  doc.text('Payment Made:', totalsLabelX, y, { align: 'right' });
  doc.setTextColor(255, 50, 50); 
  doc.text(`(-) ${currencySymbol}${parseFloat(data.total).toFixed(2)}`, totalsValueX, y, { align: 'right' });
  
  // Balance Due Box (Light Grey)
  y += 6; 
  doc.setFillColor(245, 245, 245);
  doc.rect(pageWidth - 140, y, 140 - margin, 12, 'F');
  
  doc.setTextColor(...textDark);
  doc.setFont('helvetica', 'bold');
  doc.text('Balance Due:', totalsLabelX, y + 8, { align: 'right' }); 
  doc.text(`${currencySymbol}0.00`, totalsValueX, y + 8, { align: 'right' });

  // ---------------------------------------------------------------------------
  // FOOTER
  // ---------------------------------------------------------------------------
  doc.setFontSize(8);
  doc.setFont('helvetica', 'normal');
  doc.setTextColor(...textGray);
  doc.text('Thank you for choosing our programs.', pageWidth / 2, pageHeight - 20, { align: 'center' });

  doc.save(`Invoice_${data.invoiceId}.pdf`);
};

// ─────────────────────────────────────────────────────────────────────────────
// GENERATOR 2: THE ORIGINAL RECEIPT 
// ─────────────────────────────────────────────────────────────────────────────
export const generateReceiptPDF = async (data: InvoiceDataPayload) => {
  const doc = new jsPDF();
  const pageWidth = doc.internal.pageSize.getWidth();
  const pageHeight = doc.internal.pageSize.getHeight();
  const margin = 20;
  let y = 0;

  doc.setFillColor(...primaryBlue);
  doc.rect(0, 0, pageWidth, 18, 'F'); 
  doc.setTextColor(...white);
  doc.setFontSize(16);
  doc.setFont('helvetica', 'bold');
  doc.text('PAYMENT RECEIPT', pageWidth / 2, 12, { align: 'center' }); 

  y = 28; 
  await loadLogo(doc, margin, y);

  doc.setTextColor(...textGray);
  doc.setFontSize(9);
  doc.setFont('helvetica', 'normal');
  doc.text(`Date: ${data.date}`, pageWidth - margin, y + 6, { align: 'right' });
  doc.text(`Receipt ID: ${data.registrationId}`, pageWidth - margin, y + 11, { align: 'right' });

  y += 28; 

  const drawSectionHeader = (title: string, yPos: number) => {
    doc.setTextColor(...primaryBlue);
    doc.setFontSize(11); 
    doc.setFont('helvetica', 'bold');
    doc.text(title.toUpperCase(), margin, yPos);
    doc.setDrawColor(...primaryBlue);
    doc.setLineWidth(0.4);
    doc.line(margin, yPos + 2, pageWidth - margin, yPos + 2);
    return yPos + 10; 
  };

  const drawRow = (label: string, value: string, yPos: number, isLast: boolean = false) => {
    doc.setTextColor(...textGray);
    doc.setFontSize(9); 
    doc.setFont('helvetica', 'bold');
    doc.text(label, margin, yPos);
    doc.setTextColor(...textDark);
    doc.setFont('helvetica', 'normal');
    doc.text(value || 'N/A', pageWidth - margin, yPos, { align: 'right' });
    if (!isLast) {
      doc.setDrawColor(240, 240, 240); 
      doc.setLineWidth(0.1);
      doc.line(margin, yPos + 3, pageWidth - margin, yPos + 3); 
    }
    return yPos + 8; 
  };

  const sym = currencySymbolFor(data.currency);

  y = drawSectionHeader('Recipient', y);
  y = drawRow('Parent / Guardian', data.parentName, y);
  if (data.parentEmail) y = drawRow('Email', data.parentEmail, y);
  y = drawRow('Child', data.childName, y, true);
  y += 8;

  y = drawSectionHeader('Payment', y);
  if (data.transactionId) y = drawRow('Transaction ID', data.transactionId, y);
  y = drawRow('Amount Paid', `${sym}${parseFloat(data.total).toFixed(2)}`, y);
  const taxValNum = parseFloat(data.tax) || 0;
  if (taxValNum > 0) {
    const taxLabelText = data.taxLabel ? `Tax (${data.taxLabel})` : 'Tax';
    y = drawRow(taxLabelText, `${sym}${taxValNum.toFixed(2)}`, y);
  }
  y = drawRow('Date Paid', data.date, y);
  y = drawRow('Payment Method', data.paymentMethod || 'Card', y, true);
  y += 8;

  y = drawSectionHeader('Program', y);
  y = drawRow('Program', data.programName, y);
  y = drawRow('Start Date', data.startDate, y);
  y = drawRow('Schedule', data.classTime, y);
  if (data.lessonCount) y = drawRow('Number of Lessons', data.lessonCount, y);
  if (data.totalClassValue) {
    y = drawRow('Total Class Value', `${sym}${parseFloat(data.totalClassValue).toFixed(2)}`, y);
  }
  if (data.pricePerLesson) {
    y = drawRow('Unit Price', `${sym}${data.pricePerLesson} ${data.priceSuffix || 'per lesson'}`, y);
  }
  if (data.paymentFrequencyLabel) {
    y = drawRow('Payment Frequency', data.paymentFrequencyLabel, y, true);
  } else {
    y = drawRow('Location', data.location, y, true);
  }

  doc.setTextColor(...textGray);
  doc.setFontSize(8);
  doc.setFont('helvetica', 'normal');
  doc.text('Thank you for choosing our programs. Please keep this receipt for your records.', pageWidth / 2, pageHeight - 22, { align: 'center' });

  doc.save(`Receipt_${data.registrationId}.pdf`);
};