import { jsPDF } from 'jspdf';
import 'jspdf-autotable';
import { SchoolData, Student, Contract, Payment, Class } from '../types';
import { getImageDimensions } from './imageService';

/**
 * Helper to calculate proportional dimensions and add image to PDF
 */
const addImageProportional = async (doc: any, src: string, x: number, y: number, maxW: number, maxH: number) => {
  try {
    const { width, height } = await getImageDimensions(src);
    const ratio = width / height;

    let finalW = maxW;
    let finalH = maxW / ratio;

    if (finalH > maxH) {
      finalH = maxH;
      finalW = maxH * ratio;
    }

    // Center in the box
    const offsetX = (maxW - finalW) / 2;
    const offsetY = (maxH - finalH) / 2;

    let format = 'JPEG';
    const lowerSrc = src.toLowerCase();
    if (lowerSrc.includes('png')) format = 'PNG';
    else if (lowerSrc.includes('webp')) format = 'WEBP';

    doc.addImage(src, format, x + offsetX, y + offsetY, finalW, finalH, undefined, 'FAST');
    return { width: finalW, height: finalH };
  } catch (e) {
    console.warn("Image failed to load in PDF", e);
    return null;
  }
};

/**
 * Helper to process and add a 3x4 student photo with center crop and compression
 */
const addStudentPhoto3x4 = async (doc: any, src: string, x: number, y: number) => {
  return new Promise<{ width: number, height: number } | null>((resolve) => {
    const img = new Image();
    img.crossOrigin = "anonymous";
    img.onload = () => {
      const canvas = document.createElement('canvas');
      // 300x400 for 300 DPI approx (30mm x 40mm)
      const targetW = 354; // 30mm at 300 DPI is approx 354px
      const targetH = 472; // 40mm at 300 DPI is approx 472px

      canvas.width = targetW;
      canvas.height = targetH;
      const ctx = canvas.getContext('2d');
      if (!ctx) {
        resolve(null);
        return;
      }

      const imgRatio = img.width / img.height;
      const targetRatio = targetW / targetH;

      let sourceW, sourceH, sourceX, sourceY;

      if (imgRatio > targetRatio) {
        // Image is wider than 3x4 - crop sides
        sourceH = img.height;
        sourceW = img.height * targetRatio;
        sourceX = (img.width - sourceW) / 2;
        sourceY = 0;
      } else {
        // Image is taller than 3x4 - crop top/bottom
        sourceW = img.width;
        sourceH = img.width / targetRatio;
        sourceX = 0;
        sourceY = (img.height - sourceH) / 2;
      }

      ctx.drawImage(img, sourceX, sourceY, sourceW, sourceH, 0, 0, targetW, targetH);

      // Compress to JPEG with 0.6 quality for instant opening
      const dataUrl = canvas.toDataURL('image/jpeg', 0.6);
      doc.addImage(dataUrl, 'JPEG', x, y, 30, 40, undefined, 'FAST');
      resolve({ width: 30, height: 40 });
    };
    img.onerror = () => resolve(null);
    img.src = src;
  });
};

/**
 * Helper to add header/logo to PDF
 */
export const addHeader = async (doc: any, schoolData: SchoolData) => {
  const profile = schoolData.profile;

  if (schoolData.logo) {
    await addImageProportional(doc, schoolData.logo, 20, 10, 25, 25);
  }

  doc.setFontSize(12);
  doc.setTextColor(0);
  doc.setFont('helvetica', 'bold');
  doc.text(profile.name || 'EduManager School', 50, 18);

  doc.setFontSize(8);
  doc.setTextColor(0);
  doc.setFont('helvetica', 'normal');
  doc.text(`CNPJ: ${profile.cnpj || 'Não informado'}`, 50, 23);
  doc.text(profile.address || '', 50, 27);
  doc.text(`${profile.phone || ''} ${profile.email ? '| ' + profile.email : ''}`, 50, 31);

  doc.setDrawColor(0);
  doc.setLineWidth(0.1);
  doc.line(20, 38, 190, 38);
  return 45;
};

/**
 * Helper to calculate age and get signer info
 */
const getSignerInfo = (student: Student) => {
  if (!student.birthDate) {
    return {
      name: student.guardianName || student.name,
      cpf: student.guardianCpf || student.cpf,
      label: student.guardianName ? 'ASSINATURA DO RESPONSÁVEL' : 'ASSINATURA DO ALUNO'
    };
  }

  const today = new Date();
  const birth = new Date(student.birthDate);
  let age = today.getFullYear() - birth.getFullYear();
  const m = today.getMonth() - birth.getMonth();
  if (m < 0 || (m === 0 && today.getDate() < birth.getDate())) {
    age--;
  }

  if (age >= 18) {
    return {
      name: student.name,
      cpf: student.cpf,
      label: 'ASSINATURA DO ALUNO'
    };
  } else {
    return {
      name: student.guardianName || 'NÃO INFORMADO',
      cpf: student.guardianCpf || '---',
      label: 'ASSINATURA DO RESPONSÁVEL'
    };
  }
};

/**
 * Helper to get Director info from employees
 */
const getDirectorInfo = (schoolData: SchoolData) => {
  const employees = schoolData.employees || [];
  const categories = schoolData.employeeCategories || [];
  
  const director = employees.find(e => {
    const cat = categories.find(c => c.id === e.categoryId);
    const catName = cat?.name.toLowerCase() || '';
    const empName = e.name.toLowerCase();
    const roleMatch = catName.includes('diretor') || catName.includes('diretoria');
    const nameMatch = empName.includes('diretor') || empName.includes('diretoria');
    return roleMatch || nameMatch;
  });

  if (director) {
    return {
      name: director.name,
      cpf: director.cpf,
      role: 'Diretor'
    };
  }
  
  return null;
};

/**
 * Helper to add page numbers to footer
 */
const addPageNumbers = (doc: any) => {
  const pageCount = doc.internal.getNumberOfPages();
  doc.setFont('helvetica', 'normal');
  doc.setFontSize(7);
  doc.setTextColor(0);
  for (let i = 1; i <= pageCount; i++) {
    doc.setPage(i);
    doc.text(
      `Página ${i} de ${pageCount}`,
      doc.internal.pageSize.width / 2,
      doc.internal.pageSize.height - 10,
      { align: 'center' }
    );
  }
};

/**
 * Helper to draw justified text with paragraph support
 */
const drawJustifiedText = async (doc: any, text: string, x: number, y: number, maxWidth: number, lineHeight: number, schoolData: SchoolData) => {
  const paragraphs = text.split('\n').filter(p => p.trim() !== '');
  let currentY = y;
  const margin = x;
  const pageHeight = doc.internal.pageSize.height;

  for (const p of paragraphs) {
    const isClause = p.toUpperCase().startsWith('CLÁUSULA') || p.toUpperCase().startsWith('CLAUSULA');

    // Check for page break before paragraph
    if (currentY > pageHeight - 30) {
      doc.addPage();
      await addHeader(doc, schoolData);
      currentY = 50;
    }

    doc.setFont('helvetica', isClause ? 'bold' : 'normal');
    doc.setFontSize(9);

    // Indent for non-clause paragraphs
    const startX = isClause ? margin : margin + 10;
    const currentMaxWidth = isClause ? maxWidth : maxWidth - 10;

    const lines = doc.splitTextToSize(p, currentMaxWidth);

    for (let i = 0; i < lines.length; i++) {
      // Check for page break before line
      if (currentY > pageHeight - 20) {
        doc.addPage();
        await addHeader(doc, schoolData);
        currentY = 50;
        doc.setFont('helvetica', isClause ? 'bold' : 'normal');
      }

      const line = lines[i];
      const isLastLine = i === lines.length - 1;

      if (isClause || isLastLine || line.trim().length < (currentMaxWidth / 4)) {
        doc.text(line, startX, currentY);
      } else {
        // Justify line
        const words = line.trim().split(/\s+/);
        if (words.length > 1) {
          const totalWordsWidth = words.reduce((sum: number, word: string) => sum + doc.getTextWidth(word), 0);
          const totalSpacing = currentMaxWidth - totalWordsWidth;
          const spacingPerWord = totalSpacing / (words.length - 1);

          let currentX = startX;
          for (let j = 0; j < words.length; j++) {
            doc.text(words[j], currentX, currentY);
            currentX += doc.getTextWidth(words[j]) + spacingPerWord;
          }
        } else {
          doc.text(line, startX, currentY);
        }
      }
      currentY += lineHeight;
    }
    currentY += 4; // Space between paragraphs
  }
  return currentY;
};

/**
 * Helper to draw justified text specifically for the contract
 */
const drawContractText = async (doc: any, text: string, x: number, y: number, maxWidth: number, lineHeight: number, schoolData: SchoolData) => {
  let cleanText = text
    .replace(/PROFISSINALIZANTE/g, 'PROFISSIONALIZANTE')
    .replace(/CONTRADA/g, 'CONTRATADA')
    .replace(/terar/g, 'terá')
    .replace(/apredisagem/g, 'aprendizagem');

  // Preserve the exact organization by splitting strictly by newline
  let paragraphs = cleanText.split('\n');

  let currentY = y;
  const margin = x;
  const pageHeight = doc.internal.pageSize.height;
  const bottomMargin = 20;
  const fontSize = 11; // Uniform font size for the body

  for (const p of paragraphs) {
    if (!p.trim()) {
      currentY += lineHeight * 0.5; // Provide spacing for empty lines
      continue;
    }

    const isClause = /^(CLÁUSULA|CLAUSULA)/i.test(p.trim());

    if (currentY > pageHeight - bottomMargin - 10) {
      doc.addPage();
      currentY = await addHeader(doc, schoolData);
    }

    doc.setFont('helvetica', 'normal');
    doc.setFontSize(fontSize);

    let title = "";
    let restOfText = p.trim();

    if (isClause) {
      const match = restOfText.match(/^(CLÁUSULA\s+\d+.*?[-–—:]\s*|CLAUSULA\s+\d+.*?[-–—:]\s*)/i);
      if (match) {
        title = match[0];
        restOfText = restOfText.substring(title.length).trim();
      } else {
        const match2 = restOfText.match(/^(CLÁUSULA\s+\d+|CLAUSULA\s+\d+)/i);
        if (match2) {
          title = match2[0] + " - ";
          restOfText = restOfText.substring(match2[0].length).trim();
        }
      }
    }

    const startX = margin;
    const currentMaxWidth = maxWidth;

    if (title) {
      if (currentY > pageHeight - bottomMargin - 10) {
        doc.addPage();
        currentY = await addHeader(doc, schoolData);
      }
      doc.setFont('helvetica', 'bold');
      doc.text(title, startX, currentY);
      currentY += lineHeight;
      doc.setFont('helvetica', 'normal');
    }

    if (!restOfText) {
      currentY += lineHeight * 0.5;
      continue;
    }

    const lines = doc.splitTextToSize(restOfText, currentMaxWidth);

    for (let i = 0; i < lines.length; i++) {
      if (currentY > pageHeight - bottomMargin) {
        doc.addPage();
        currentY = await addHeader(doc, schoolData);
        doc.setFont('helvetica', 'normal');
        doc.setFontSize(fontSize);
      }

      const line = lines[i];
      const isLastLine = i === lines.length - 1;

      if (isLastLine || line.trim().length < (currentMaxWidth / 2)) {
        doc.text(line, startX, currentY);
      } else {
        // Justify line
        const words = line.trim().split(/\s+/);
        if (words.length > 1) {
          const totalWordsWidth = words.reduce((sum: number, word: string) => sum + doc.getTextWidth(word), 0);
          const totalSpacing = currentMaxWidth - totalWordsWidth;
          const spacingPerWord = totalSpacing / (words.length - 1);

          let currentX = startX;
          for (let j = 0; j < words.length; j++) {
            doc.text(words[j], currentX, currentY);
            currentX += doc.getTextWidth(words[j]) + spacingPerWord;
          }
        } else {
          doc.text(line, startX, currentY);
        }
      }
      currentY += lineHeight;
    }
    currentY += lineHeight * 0.5; // Space between paragraphs
  }
  return currentY;
};

export const pdfService = {
  generateStudentRegistrationPDF: async (student: Student, schoolData: SchoolData) => {
    const doc = new jsPDF() as any;
    const startY = await addHeader(doc, schoolData);
    const cls = schoolData.classes.find(c => c.id === student.classId);
    const course = schoolData.courses.find(c => c.id === cls?.courseId);

    // Title and Date (Centered)
    doc.setFontSize(16);
    doc.setTextColor(0);
    doc.setFont('helvetica', 'bold');
    doc.text('Ficha de Matrícula', 105, startY + 10, { align: 'center' });

    doc.setFontSize(10);
    doc.setFont('helvetica', 'normal');
    doc.text(`Data: ${new Date().toLocaleDateString('pt-BR')}`, 105, startY + 16, { align: 'center' });

    // Photo Positioning - Top Right (Standard 3x4cm = 30x40mm)
    const photoX = 155;
    const photoY = startY + 25;
    const photoW = 30;
    const photoH = 40;

    if (student.photo) {
      await addStudentPhoto3x4(doc, student.photo, photoX, photoY);
    }

    // Border around photo area
    doc.setDrawColor(0);
    doc.setLineWidth(0.1);
    doc.rect(photoX, photoY, photoW, photoH);
    if (!student.photo) {
      doc.setFontSize(7);
      doc.setTextColor(150);
      doc.text('FOTO 3X4', photoX + 15, photoY + 20, { align: 'center' });
    }

    let currentY = startY + 30;
    const labelX = 20;

    // 1. Dados do Aluno
    doc.setFontSize(12);
    doc.setTextColor(0);
    doc.setFont('helvetica', 'bold');
    doc.text('Dados do Aluno', labelX, currentY);

    currentY += 8;
    doc.setFontSize(10);

    const drawField = (label: string, value: string, y: number) => {
      doc.setFont('helvetica', 'normal');
      doc.text(`${label}: ${value || '-'}`, labelX, y);
      return y + 6;
    };

    currentY = drawField('Nº Matrícula', student.enrollmentNumber || 'Não gerado', currentY);
    currentY = drawField('Nome', student.name, currentY);
    currentY = drawField('CPF', student.cpf, currentY);
    currentY = drawField('RG', student.rg, currentY);
    currentY = drawField('Data de Nascimento', student.birthDate ? student.birthDate.split('-').reverse().join('/') : '', currentY);
    currentY = drawField('Email', student.email, currentY);
    currentY = drawField('Telefone', student.phone, currentY);

    currentY += 4;

    // 2. Endereço
    doc.setFontSize(11);
    doc.setFont('helvetica', 'bold');
    doc.text('Endereço', labelX, currentY);
    currentY += 6;
    doc.setFontSize(10);
    doc.setFont('helvetica', 'normal');
    doc.text(`${student.addressStreet || ''}${student.addressNumber ? `, ${student.addressNumber}` : ''} - ${student.addressNeighborhood || ''}`, labelX, currentY);
    currentY += 6;
    doc.text(`${student.addressCity || ''} - ${student.addressState || ''} CEP: ${student.addressZip || ''}`, labelX, currentY);

    currentY += 10;

    // 3. Dados do Curso
    doc.setFontSize(11);
    doc.setFont('helvetica', 'bold');
    doc.text('Dados do Curso', labelX, currentY);
    currentY += 8;
    doc.setFontSize(10);
    currentY = drawField('Curso', course?.name || 'Não vinculado', currentY);
    currentY = drawField('Turma', cls?.name || 'Não atribuída', currentY);
    currentY = drawField('Horário', cls?.schedule || 'N/A', currentY);
    currentY = drawField('Professor', cls?.teacher || 'N/A', currentY);
    currentY = drawField('Data Matrícula', student.registrationDate ? student.registrationDate.split('T')[0].split('-').reverse().join('/') : '', currentY);

    currentY += 10;

    // 4. Termos e Condições
    doc.setFontSize(11);
    doc.setFont('helvetica', 'bold');
    doc.text('Termos e Condições', labelX, currentY);

    currentY += 8;
    doc.setFontSize(9);
    doc.setFont('helvetica', 'normal');
    const termsText = "Declaro que as informações acima são verdadeiras e assumo a responsabilidade pelo pagamento das mensalidades escolares conforme contrato de prestação de serviços educacionais.";
    const splitTerms = doc.splitTextToSize(termsText, 170);
    doc.text(splitTerms, labelX, currentY);

    // Footer - Signatures
    const pageHeight = doc.internal.pageSize.height;
    const signer = getSignerInfo(student);

    doc.setDrawColor(0);
    doc.setLineWidth(0.2);

    // Signer Signature
    const sigY = pageHeight - 45;
    doc.line(20, sigY, 90, sigY);
    doc.setFont('helvetica', 'bold');
    doc.setFontSize(9);
    doc.text(signer.name.toUpperCase(), 55, sigY + 5, { align: 'center' });
    doc.setFont('helvetica', 'normal');
    doc.setFontSize(8);
    doc.text(`CPF: ${signer.cpf || '---'}`, 55, sigY + 9, { align: 'center' });
    doc.text(signer.label, 55, sigY + 13, { align: 'center' });

    // School Signature
    const director = getDirectorInfo(schoolData);
    const dirName = director ? director.name.toUpperCase() : schoolData.profile.name.toUpperCase();
    const dirDoc = director ? `CPF: ${director.cpf}` : `CNPJ: ${schoolData.profile.cnpj || '---'}`;
    const dirRole = director ? director.role : 'Assinatura da Escola';

    doc.line(120, sigY, 190, sigY);
    doc.setFont('helvetica', 'bold');
    doc.setFontSize(9);
    doc.text(dirName, 155, sigY + 5, { align: 'center' });
    doc.setFont('helvetica', 'normal');
    doc.setFontSize(8);
    doc.text(dirDoc, 155, sigY + 9, { align: 'center' });
    doc.text(dirRole, 155, sigY + 13, { align: 'center' });

    doc.save(`ficha_matricula_${student.name.replace(/\s+/g, '_').toLowerCase()}.pdf`);
  },

  generateStudentHistoryPDF: async (student: Student, schoolData: SchoolData) => {
    const doc = new jsPDF() as any;
    const startY = await addHeader(doc, schoolData);
    const payments = schoolData.payments.filter(p => p.studentId === student.id);
    const contracts = schoolData.contracts.filter(c => c.studentId === student.id);

    doc.setFontSize(16);
    doc.setTextColor(0);
    doc.text(`Histórico Acadêmico e Financeiro: ${student.name}`, 105, startY + 5, { align: 'center' });

    doc.setFontSize(12);
    doc.setTextColor(0);
    doc.text('Contratos Ativos', 20, startY + 20);

    doc.autoTable({
      startY: startY + 25,
      margin: { top: 45 },
      didDrawPage: async (data: any) => {
        if (data.pageNumber > 1) await addHeader(doc, schoolData);
      },
      head: [['Título', 'Data Emissão']],
      body: contracts.map(c => [
        c.title,
        c.createdAt ? c.createdAt.split('T')[0].split('-').reverse().join('/') : ''
      ]),
      headStyles: { fillColor: [0, 0, 0] }
    });

    const nextY = (doc as any).lastAutoTable.finalY + 15;
    doc.setFontSize(12);
    doc.text('Histórico de Pagamentos', 20, nextY);

    doc.autoTable({
      startY: nextY + 5,
      margin: { top: 45 },
      didDrawPage: async (data: any) => {
        if (data.pageNumber > 1) await addHeader(doc, schoolData);
      },
      head: [['Descrição', 'Vencimento', 'Valor', 'Status']],
      body: payments.map(p => [
        p.description || (p.type === 'registration' ? 'Matrícula' : 'Mensalidade'),
        p.dueDate ? p.dueDate.split('T')[0].split('-').reverse().join('/') : '',
        `R$ ${p.amount.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}`,
        p.status === 'paid' ? 'Pago' : p.status === 'overdue' ? 'Atrasado' : 'Pendente'
      ]),
      headStyles: { fillColor: [0, 0, 0] }
    });

    doc.save(`historico_${student.name.replace(/\s+/g, '_').toLowerCase()}.pdf`);
  },

  generatePaymentReceiptPDF: async (payment: Payment, student: Student, schoolData: SchoolData) => {
    const doc = new jsPDF() as any;

    doc.setDrawColor(0);
    doc.setLineWidth(0.5);
    doc.rect(10, 10, 190, 140); // Border

    const profile = schoolData.profile;
    if (schoolData.logo) {
      await addImageProportional(doc, schoolData.logo, 20, 15, 20, 20);
    }
    doc.setFontSize(12);
    doc.setTextColor(0);
    doc.text(profile.name, 45, 18);
    doc.setFontSize(8);
    doc.text(`CNPJ: ${profile.cnpj || '---'}`, 45, 22);
    doc.text(profile.address || '', 45, 26);

    doc.setFontSize(16);
    doc.setTextColor(0);
    doc.text('RECIBO DE PAGAMENTO', 105, 45, { align: 'center' });

    doc.setFontSize(9);
    doc.setTextColor(0);
    doc.text(`Nº do Documento: ${payment.id.substring(0, 8).toUpperCase()}`, 150, 55);

    doc.setFontSize(11);
    doc.setTextColor(0);
    doc.text(`Recebemos de: ${student.name}`, 20, 70);
    doc.text(`CPF: ${student.cpf || '---'}`, 20, 76);
    doc.text(`A quantia de: R$ ${payment.amount.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}`, 20, 85);

    const typeLabel = payment.type === 'registration' ? 'Taxa de Matrícula' :
      payment.type === 'monthly' ? 'Mensalidade do Curso' : 'Outros Serviços';

    doc.text(`Referente a: ${typeLabel} ${payment.description ? `(${payment.description})` : ''}`, 20, 95);
    doc.text(`Data de Vencimento: ${payment.dueDate ? payment.dueDate.split('T')[0].split('-').reverse().join('/') : ''}`, 20, 105);

    if (payment.status === 'paid' && payment.paidDate) {
      doc.setFontSize(12);
      doc.setTextColor(0);
      doc.text(`PAGO EM: ${payment.paidDate}`, 105, 120, { align: 'center' });
    }

    doc.setTextColor(0);
    doc.setFontSize(9);
    doc.text('_________________________________', 105, 140, { align: 'center' });
    doc.text('Assinatura / Carimbo', 105, 145, { align: 'center' });

    doc.save(`recibo_${student.name.replace(/\s+/g, '_').toLowerCase()}_${payment.id.substring(0, 4)}.pdf`);
  },

  generateContractPDF: async (contract: Contract, student: Student, schoolData: SchoolData) => {
    const doc = new jsPDF({
      orientation: 'portrait',
      unit: 'mm',
      format: 'a4'
    }) as any;

    let currentY = await addHeader(doc, schoolData);

    // Title
    doc.setFontSize(14);
    doc.setTextColor(0);
    doc.setFont('helvetica', 'bold');
    doc.text('CONTRATO DE PRESTAÇÃO DE SERVIÇOS EDUCACIONAIS', 105, currentY, { align: 'center' });

    currentY += 10;

    // Contract Header Info
    doc.setFontSize(10);
    doc.setFont('helvetica', 'normal');

    doc.text(`DATA DE EMISSÃO: ${contract.createdAt ? contract.createdAt.split('T')[0].split('-').reverse().join('/') : ''}`, 20, currentY);
    currentY += 6;
    doc.text(`CONTRATANTE: ${student.name.toUpperCase()}`, 20, currentY);
    currentY += 6;
    doc.text(`CPF: ${student.cpf || '---'}`, 20, currentY);

    currentY += 10;

    // Draw Justified Content with Pagination
    const margin = 20; // 2cm
    const pageWidth = doc.internal.pageSize.width;
    const maxWidth = pageWidth - (margin * 2);
    const lineHeight = 5.5; // 1.5 spacing approx for 10pt font

    currentY = await drawContractText(doc, contract.content, margin, currentY, maxWidth, lineHeight, schoolData);

    // Signatures
    const pageHeight = doc.internal.pageSize.height;
    const signer = getSignerInfo(student);

    // Check if signatures fit on current page (need about 45mm to keep them together without breaking)
    if (currentY > pageHeight - 45) {
      doc.addPage();
      currentY = await addHeader(doc, schoolData);
      currentY += 10;
    } else {
      currentY += 25; // Extra space before signatures
    }

    // Signature Block - Unbreakable, Side by Side
    doc.setDrawColor(0);
    doc.setLineWidth(0.2);

    const sigY = currentY;

    // Signer Signature (Left Column)
    doc.line(20, sigY, 90, sigY);
    doc.setFont('helvetica', 'bold');
    doc.setFontSize(9);
    doc.text(signer.name.toUpperCase(), 55, sigY + 5, { align: 'center' });
    doc.setFont('helvetica', 'normal');
    doc.setFontSize(8);
    doc.text(`CPF: ${signer.cpf || '---'}`, 55, sigY + 9, { align: 'center' });
    doc.text(signer.label, 55, sigY + 13, { align: 'center' });

    // School Signature (Right Column)
    const director = getDirectorInfo(schoolData);
    const dirName = director ? director.name.toUpperCase() : schoolData.profile.name.toUpperCase();
    const dirDoc = director ? `CPF: ${director.cpf}` : `CNPJ: ${schoolData.profile.cnpj || '---'}`;
    const dirRole = director ? director.role : 'Assinatura da Escola';

    doc.line(120, sigY, 190, sigY);
    doc.setFont('helvetica', 'bold');
    doc.setFontSize(9);
    doc.text(dirName, 155, sigY + 5, { align: 'center' });
    doc.setFont('helvetica', 'normal');
    doc.setFontSize(8);
    doc.text(dirDoc, 155, sigY + 9, { align: 'center' });
    doc.text(dirRole, 155, sigY + 13, { align: 'center' });

    // Add Page Numbers to all pages
    addPageNumbers(doc);

    doc.save(`contrato_${contract.title.replace(/\s+/g, '_').toLowerCase()}.pdf`);
  },

  generateClassListPDF: async (cls: Class, schoolData: SchoolData) => {
    const doc = new jsPDF() as any;
    const startY = await addHeader(doc, schoolData);
    const course = schoolData.courses.find(c => c.id === cls.courseId);
    const students = schoolData.students.filter(s => s.classId === cls.id);

    doc.setFontSize(16);
    doc.setTextColor(0);
    doc.text(`Relatório de Turma: ${cls.name}`, 105, startY + 5, { align: 'center' });

    doc.setFontSize(10);
    doc.setTextColor(0);
    doc.text(`Curso: ${course?.name || 'N/A'}`, 20, startY + 15);
    doc.text(`Professor: ${cls.teacher}`, 20, startY + 22);
    doc.text(`Horário: ${cls.schedule}`, 20, startY + 29);

    doc.autoTable({
      startY: startY + 35,
      margin: { top: 45 },
      didDrawPage: async (data: any) => {
        if (data.pageNumber > 1) await addHeader(doc, schoolData);
      },
      head: [['Nº', 'Nome do Aluno', 'Telefone', 'Status']],
      body: students.map((s, idx) => [
        idx + 1,
        s.name,
        s.phone,
        s.status === 'active' ? 'Ativo' : 'Inativo'
      ]),
      headStyles: { fillColor: [0, 0, 0] }
    });

    doc.save(`turma_${cls.name.replace(/\s+/g, '_').toLowerCase()}.pdf`);
  },

  generateStudentListPDF: async (schoolData: SchoolData) => {
    const doc = new jsPDF() as any;
    const startY = await addHeader(doc, schoolData);

    doc.setFontSize(16);
    doc.setTextColor(0);
    doc.text('Relatório Geral de Alunos', 105, startY + 5, { align: 'center' });

    doc.autoTable({
      startY: startY + 15,
      margin: { top: 45 },
      didDrawPage: async (data: any) => {
        if (data.pageNumber > 1) await addHeader(doc, schoolData);
      },
      head: [['Nome', 'CPF', 'Email', 'Turma', 'Status']],
      body: schoolData.students.map(s => {
        const cls = schoolData.classes.find(c => c.id === s.classId);
        return [
          s.name,
          s.cpf || '-',
          s.email,
          cls?.name || '-',
          s.status === 'active' ? 'Ativo' : 'Inativo'
        ];
      }),
      headStyles: { fillColor: [0, 0, 0] }
    });

    doc.save(`lista_alunos_${new Date().toISOString().split('T')[0]}.pdf`);
  },

  generateFullSchoolReportPDF: async (schoolData: SchoolData) => {
    const doc = new jsPDF() as any;
    const startY = await addHeader(doc, schoolData);

    doc.setFontSize(18);
    doc.setTextColor(0);
    doc.text('Relatório Consolidado', 105, startY + 5, { align: 'center' });

    doc.setFontSize(12);
    doc.text('Visão Geral', 20, startY + 20);
    doc.setFontSize(10);
    doc.text(`Total Alunos: ${schoolData.students.length}`, 20, startY + 28);
    doc.text(`Alunos Ativos: ${schoolData.students.filter(s => s.status === 'active').length}`, 20, startY + 34);
    doc.text(`Turmas Ativas: ${schoolData.classes.length}`, 20, startY + 40);

    doc.autoTable({
      startY: startY + 50,
      margin: { top: 45 },
      didDrawPage: async (data: any) => {
        if (data.pageNumber > 1) await addHeader(doc, schoolData);
      },
      head: [['Alunos', 'Turmas', 'Financeiro Pago', 'Pendente']],
      body: [[
        schoolData.students.length,
        schoolData.classes.length,
        `R$ ${schoolData.payments.filter(p => p.status === 'paid').reduce((sum, p) => sum + p.amount, 0).toFixed(2)}`,
        `R$ ${schoolData.payments.filter(p => p.status !== 'paid').reduce((sum, p) => sum + p.amount, 0).toFixed(2)}`
      ]],
      headStyles: { fillColor: [0, 0, 0] }
    });

    doc.save(`relatorio_geral_${new Date().toISOString().split('T')[0]}.pdf`);
  },

  generateCancellationTermPDF: async (student: Student, schoolData: SchoolData, cancellationReason: string) => {
    const doc = new jsPDF() as any;
    const startY = await addHeader(doc, schoolData);
    const cls = schoolData.classes.find(c => c.id === student.classId);
    const course = schoolData.courses.find(c => c.id === cls?.courseId);

    // Title
    doc.setFontSize(16);
    doc.setTextColor(0);
    doc.setFont('helvetica', 'bold');
    doc.text('TERMO DE CANCELAMENTO DE MATRÍCULA', 105, startY + 10, { align: 'center' });

    let currentY = startY + 25;

    doc.setFontSize(12);
    doc.setFont('helvetica', 'bold');
    doc.text('Escola:', 20, currentY);
    doc.setFont('helvetica', 'normal');
    doc.text(schoolData.profile.name || 'Microtec Informática Cursos', 38, currentY);

    currentY += 15;

    // Student Data
    doc.setFont('helvetica', 'bold');
    doc.text('Dados do Aluno:', 20, currentY);
    currentY += 8;

    doc.setFontSize(11);
    doc.setFont('helvetica', 'normal');
    doc.text(`Nome: ${student.name} | CPF: ${student.cpf || 'Não informado'}`, 20, currentY);
    currentY += 6;
    doc.text(`Curso: ${course?.name || 'Não informado'} | Turma: ${cls?.name || 'Não informado'}`, 20, currentY);

    currentY += 12;

    // Guardian Data
    if (student.guardianName) {
      doc.setFontSize(12);
      doc.setFont('helvetica', 'bold');
      doc.text('Dados do Responsável (se menor de idade):', 20, currentY);
      currentY += 8;

      doc.setFontSize(11);
      doc.setFont('helvetica', 'normal');
      doc.text(`Nome: ${student.guardianName} | CPF: ${student.guardianCpf || 'Não informado'}`, 20, currentY);
      currentY += 12;
    }

    // Reason
    doc.setFontSize(12);
    doc.setFont('helvetica', 'bold');
    doc.text('Motivo do Cancelamento:', 20, currentY);
    currentY += 8;

    doc.setFontSize(11);
    doc.setFont('helvetica', 'normal');
    const splitReason = doc.splitTextToSize(cancellationReason, 170);
    doc.text(splitReason, 20, currentY);
    currentY += (splitReason.length * 6) + 10;

    // Term Text
    const termText1 = 'Pelo presente termo, o(a) aluno(a) ou seu responsável legal acima qualificado, solicita formalmente o CANCELAMENTO DA MATRÍCULA no curso especificado.';
    const termText2 = 'Declara estar ciente de que o cancelamento encerra o vínculo educacional a partir desta data, não isentando o contratante de eventuais pendências financeiras adquiridas e vencidas até o presente momento, conforme contrato de prestação de serviços educacionais assinado no ato da matrícula.';

    const splitTerm1 = doc.splitTextToSize(termText1, 170);
    doc.text(splitTerm1, 20, currentY);
    currentY += (splitTerm1.length * 6) + 4;

    const splitTerm2 = doc.splitTextToSize(termText2, 170);
    doc.text(splitTerm2, 20, currentY);
    currentY += (splitTerm2.length * 6) + 20;

    // Date and Signatures
    const dateStr = new Date().toLocaleDateString('pt-BR', { day: 'numeric', month: 'long', year: 'numeric' });
    doc.text(`Redenção - CE, ${dateStr}.`, 20, currentY);

    currentY += 30;

    doc.line(20, currentY, 90, currentY);
    doc.line(120, currentY, 190, currentY);

    currentY += 5;
    doc.setFontSize(10);
    doc.text('Assinatura do Aluno ou Responsável Legal', 55, currentY, { align: 'center' });
    doc.text(`${schoolData.profile.name || 'Microtec Informática Cursos'} (Administração)`, 155, currentY, { align: 'center' });

    doc.save(`termo_cancelamento_${student.name.replace(/\s+/g, '_')}.pdf`);
  }
};