/* PDF expediente completo del alumno — diseño comprobante Tecos Elite */

/** Teléfonos registrados del alumno para envío por WhatsApp. */
function getStudentPhoneRecipients (alumno) {
  const list = [];
  const add = (id, role, phone) => {
    const display = String(phone || '').trim();
    if (!display || display === '—') return;
    const digits = typeof normalizeWaPhoneDigits === 'function'
      ? normalizeWaPhoneDigits(display)
      : String(display).replace(/\D/g, '');
    if (!digits) return;
    list.push({ id, role, display, digits });
  };
  add('tutor', 'Tutor / responsable', alumno?.phone);
  add('student', 'Alumno', alumno?.student_phone);
  return list;
}

function expedienteDocPublicUrl (doc) {
  if (typeof getStudentDocumentPublicUrl === 'function') return getStudentDocumentPublicUrl(doc);
  if (!doc?.file_path || typeof getStoragePublicUrl !== 'function') return null;
  const base = getStoragePublicUrl('gallery', doc.file_path);
  const v = doc.uploaded_at || doc.id || doc.file_path;
  return base ? `${base}${base.includes('?') ? '&' : '?'}v=${encodeURIComponent(String(v))}` : null;
}

function expedienteDocIsPdf (doc) {
  if (typeof isStudentDocumentPdf === 'function') return isStudentDocumentPdf(doc);
  const mime = (doc?.mime_type || '').toLowerCase();
  const name = (doc?.file_name || doc?.file_path || '').toLowerCase();
  return mime.includes('pdf') || name.endsWith('.pdf');
}

function getExpedienteDocumentsToEmbed (documents, requirements) {
  const types = typeof STUDENT_DOCUMENT_TYPES !== 'undefined' ? STUDENT_DOCUMENT_TYPES : [];
  const byType = {};
  (documents || []).forEach((d) => {
    if (d?.doc_type && d?.file_path) byType[d.doc_type] = d;
  });
  const req = requirements && typeof requirements === 'object' ? requirements : null;
  return types
    .filter((dt) => {
      if (!byType[dt.id]) return false;
      if (req && Object.keys(req).length && req[dt.id] === false) return false;
      return true;
    })
    .map((dt) => ({ label: dt.label, row: byType[dt.id] }));
}

async function fetchExpedienteDocumentBlob (doc) {
  const url = expedienteDocPublicUrl(doc);
  if (!url) return null;
  try {
    const res = await fetch(url, { mode: 'cors', cache: 'no-cache' });
    if (!res.ok) return null;
    return res.blob();
  } catch {
    return null;
  }
}

async function pdfBlobToPageDataUrls (blob, maxPages = 15) {
  const pdfjsLib = typeof window !== 'undefined' ? window.pdfjsLib : null;
  if (!pdfjsLib?.getDocument) return [];
  if (!pdfjsLib.GlobalWorkerOptions?.workerSrc) {
    pdfjsLib.GlobalWorkerOptions.workerSrc =
      'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';
  }
  const data = await blob.arrayBuffer();
  const pdf = await pdfjsLib.getDocument({ data }).promise;
  const total = Math.min(pdf.numPages, maxPages);
  const images = [];
  for (let i = 1; i <= total; i++) {
    const page = await pdf.getPage(i);
    const viewport = page.getViewport({ scale: 1.35 });
    const canvas = document.createElement('canvas');
    canvas.width = Math.floor(viewport.width);
    canvas.height = Math.floor(viewport.height);
    const ctx = canvas.getContext('2d');
    if (!ctx) continue;
    ctx.fillStyle = '#ffffff';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    await page.render({ canvasContext: ctx, viewport }).promise;
    images.push(canvas.toDataURL('image/jpeg', 0.9));
  }
  return {
    images,
    truncatedExtra: Math.max(0, pdf.numPages - maxPages),
  };
}

function addExpedienteImageToPdf (doc, dataUrl, y, margin, pageW) {
  const maxW = pageW - margin * 2;
  const maxH = 230;
  const fmt = typeof receiptImgFormat === 'function' ? receiptImgFormat(dataUrl) : 'JPEG';
  let props;
  try {
    props = doc.getImageProperties(dataUrl);
  } catch {
    doc.setFont('helvetica', 'normal');
    doc.setFontSize(10);
    doc.text('No se pudo incrustar la imagen.', margin, y);
    return y + 12;
  }
  let w = maxW;
  let h = (props.height / props.width) * w;
  if (h > maxH) {
    h = maxH;
    w = (props.width / props.height) * h;
  }
  doc.addImage(dataUrl, fmt, margin + (maxW - w) / 2, y, w, h, undefined, 'FAST');
  return y + h + 10;
}

async function appendUploadedDocumentsToExpediente (doc, alumno, documents, requirements, ctx) {
  const items = getExpedienteDocumentsToEmbed(documents, requirements);
  if (!items.length) return ctx.y;

  const { margin, pageW, schoolName, logoData } = ctx;
  const loadImg = typeof loadReceiptImage === 'function' ? loadReceiptImage : async () => null;
  const compress = typeof compressReceiptImageForPdf === 'function' ? compressReceiptImageForPdf : async (u) => u;

  let y = ctx.y;
  doc.setFont('helvetica', 'bold');
  doc.setFontSize(12);
  doc.text('Documentos cargados (archivos originales)', margin, y);
  y += 10;

  for (const { label, row } of items) {
    const fileLabel = row.file_name || row.file_path || label;
    const openBanner = (subtitle, pageNote) => {
      doc.addPage();
      return drawReceiptPdfBanner(doc, {
        schoolName,
        titleLine: subtitle,
        rightTop: alumno?.id || '—',
        rightBottom: pageNote || fileLabel,
        logoData,
        margin,
        pageW,
      }) + 10;
    };

    if (expedienteDocIsPdf(row)) {
      const blob = await fetchExpedienteDocumentBlob(row);
      if (!blob) {
        y = openBanner(`Papelería — ${label}`, 'No disponible');
        doc.setFont('helvetica', 'normal');
        doc.setFontSize(10);
        doc.text('No se pudo descargar el PDF desde el almacenamiento.', margin, y);
        continue;
      }
      const { images: pdfPages, truncatedExtra } = await pdfBlobToPageDataUrls(blob, 15);
      if (!pdfPages.length) {
        y = openBanner(`Papelería — ${label}`, 'Error al leer PDF');
        doc.setFont('helvetica', 'normal');
        doc.setFontSize(10);
        doc.text('No se pudo leer el PDF. Ábrelo desde el portal o admin.', margin, y);
        continue;
      }
      pdfPages.forEach((dataUrl, idx) => {
        const note = pdfPages.length > 1 ? `Pág. ${idx + 1} de ${pdfPages.length}` : fileLabel;
        y = openBanner(`Papelería — ${label}`, note);
        y = addExpedienteImageToPdf(doc, dataUrl, y, margin, pageW);
      });
      if (truncatedExtra > 0) {
        y = openBanner(`Papelería — ${label}`, '…');
        doc.setFont('helvetica', 'italic');
        doc.setFontSize(9);
        doc.text(`(${truncatedExtra} página(s) adicional(es) no incluidas — descarga el archivo original)`, margin, y);
      }
    } else {
      const url = expedienteDocPublicUrl(row);
      let dataUrl = await loadImg(url);
      if (dataUrl) dataUrl = await compress(dataUrl);
      y = openBanner(`Papelería — ${label}`, fileLabel);
      if (!dataUrl) {
        doc.setFont('helvetica', 'normal');
        doc.setFontSize(10);
        doc.text('No se pudo cargar la imagen.', margin, y);
      } else {
        y = addExpedienteImageToPdf(doc, dataUrl, y, margin, pageW);
      }
    }
  }
  return y;
}

async function buildStudentExpedientePdfDoc (alumno, opts = {}) {
  const { jsPDF } = window.jspdf || {};
  if (!jsPDF) throw new Error('Librería PDF no disponible');

  const settings = opts.settings || {};
  const schoolName = settings?.venue_name || 'TECOS ELITE VOLLEYBALL';
  const year = opts.year || new Date().getFullYear();
  const payments = opts.payments || [];
  const orders = opts.orders || [];
  const documents = opts.documents || [];
  const calendarMonths = opts.calendarMonths || [];
  const dark = [15, 23, 42];
  const margin = 16;
  const logoPath = (typeof RECEIPT_LOGO_PATH !== 'undefined' && RECEIPT_LOGO_PATH)
    || (typeof window !== 'undefined' && window.TECOS_LOGO_PATH)
    || 'assets/logo-tecos.png?v=no-bg-2';
  const loadImg = typeof loadReceiptImage === 'function' ? loadReceiptImage : async () => null;
  const [logoData, photoData] = await Promise.all([
    loadImg(logoPath),
    loadImg(alumno?.photoUrl),
  ]);

  const doc = new jsPDF({ unit: 'mm', format: 'a4' });
  const pageW = doc.internal.pageSize.getWidth();
  let y = drawReceiptPdfBanner(doc, {
    schoolName,
    titleLine: 'Expediente completo del alumno',
    rightTop: `ID ${alumno?.id || '—'}`,
    rightBottom: new Date().toLocaleString('es-MX', { dateStyle: 'medium' }),
    logoData,
    margin,
    pageW,
  });

  y = drawReceiptStudentCard(doc, alumno, photoData, y, margin, pageW);

  const infoRows = [
    ['Edad', alumno?.age != null ? `${alumno.age} años` : '—'],
    ['Antigüedad', alumno?.antiguedad || (typeof computeSeniorityLabel === 'function' ? computeSeniorityLabel(alumno?.joined_at) : '—')],
    ['Fecha de ingreso', alumno?.joined || '—'],
    ['Estado', alumno?.status || '—'],
    ['Tel. alumno', alumno?.student_phone || '—'],
    ['Correo', alumno?.email || '—'],
    ['Adeudo (mes actual)', alumno?.adeudo > 0 ? `$${Number(alumno.adeudo).toLocaleString('es-MX')} MXN` : 'Al corriente'],
    ['Notas', alumno?.notes || '—'],
  ];

  doc.setFont('helvetica', 'bold');
  doc.setFontSize(12);
  doc.text('Datos del expediente', margin, y);
  y += 8;

  doc.autoTable({
    startY: y,
    body: infoRows,
    theme: 'plain',
    styles: { fontSize: 10, cellPadding: 3 },
    columnStyles: { 0: { fontStyle: 'bold', cellWidth: 48 } },
    margin: { left: margin, right: margin },
  });
  y = doc.lastAutoTable.finalY + 12;

  if (calendarMonths.length) {
    doc.setFont('helvetica', 'bold');
    doc.setFontSize(12);
    doc.text(`Calendario de pagos ${year}`, margin, y);
    y += 8;
    doc.autoTable({
      startY: y,
      head: [['Mes', 'Estado', 'Monto', 'Adelanto']],
      body: calendarMonths.map((m) => [
        m.name || '—',
        paymentStatusLabelPdf(m.status === 'revision' ? 'en_revision' : m.status),
        m.hideAmount ? '—' : `$${(Number(m.amt) || 0).toLocaleString('es-MX')}`,
        m.advancePay ? 'Sí' : '—',
      ]),
      theme: 'grid',
      headStyles: { fillColor: dark, textColor: 255, fontStyle: 'bold' },
      styles: { fontSize: 9, cellPadding: 3 },
      margin: { left: margin, right: margin },
    });
    y = doc.lastAutoTable.finalY + 12;
  }

  doc.setFont('helvetica', 'bold');
  doc.setFontSize(12);
  doc.text('Historial de pagos', margin, y);
  y += 8;

  if (!payments.length) {
    doc.setFont('helvetica', 'normal');
    doc.setFontSize(10);
    doc.text('Sin pagos registrados.', margin, y);
    y += 10;
  } else {
    doc.autoTable({
      startY: y,
      head: [['Concepto', 'Monto', 'Vencimiento', 'Fecha pago', 'Estado']],
      body: payments.map((p) => [
        p.c || p.concept || '—',
        p.hideAmount ? '—' : `$${(Number(p.a ?? p.amount) || 0).toLocaleString('es-MX')}`,
        p.d || '—',
        p.pago || (p.paid_at ? formatReceiptDateTime(p.paid_at) : '—'),
        paymentStatusLabelPdf(p.s || p.status),
      ]),
      theme: 'grid',
      headStyles: { fillColor: dark, textColor: 255, fontStyle: 'bold' },
      styles: { fontSize: 9, cellPadding: 3 },
      margin: { left: margin, right: margin },
    });
    y = doc.lastAutoTable.finalY + 12;
  }

  if (orders.length) {
    if (y > 240) { doc.addPage(); y = drawReceiptPdfBanner(doc, { schoolName, titleLine: 'Expediente — compras', rightTop: alumno?.id, logoData, margin, pageW }); y += 10; }
    doc.setFont('helvetica', 'bold');
    doc.setFontSize(12);
    doc.text('Compras en tienda', margin, y);
    y += 8;
    doc.autoTable({
      startY: y,
      head: [['Pedido', 'Producto', 'Total', 'Fecha', 'Estado']],
      body: orders.map((o) => [
        o.n || o.order_number || '—',
        o.p || '—',
        `$${(Number(o.a) || 0).toLocaleString('es-MX')}`,
        o.d || '—',
        paymentStatusLabelPdf(o.s || o.status),
      ]),
      theme: 'grid',
      headStyles: { fillColor: dark, textColor: 255, fontStyle: 'bold' },
      styles: { fontSize: 9, cellPadding: 3 },
      margin: { left: margin, right: margin },
    });
    y = doc.lastAutoTable.finalY + 12;
  }

  const docTypes = typeof STUDENT_DOCUMENT_TYPES !== 'undefined' ? STUDENT_DOCUMENT_TYPES : [];
  if (docTypes.length) {
    if (y > 220) {
      doc.addPage();
      y = drawReceiptPdfBanner(doc, { schoolName, titleLine: 'Expediente — papelería', rightTop: alumno?.id, logoData, margin, pageW });
      y += 10;
    }
    doc.setFont('helvetica', 'bold');
    doc.setFontSize(12);
    doc.text('Papelería y documentos', margin, y);
    y += 8;

    const papeleriaRows = docTypes.map((dt) => {
      const row = documents.find(d => d.doc_type === dt.id);
      return [
        dt.label,
        row ? 'Cargado' : 'Pendiente',
        row ? (row.file_name || row.file_path || '—') : '—',
        row?.uploaded_at ? new Date(row.uploaded_at).toLocaleDateString('es-MX') : '—',
      ];
    });

    doc.autoTable({
      startY: y,
      head: [['Documento', 'Estado', 'Archivo', 'Fecha']],
      body: papeleriaRows,
      theme: 'grid',
      headStyles: { fillColor: dark, textColor: 255, fontStyle: 'bold' },
      styles: { fontSize: 9, cellPadding: 3 },
      margin: { left: margin, right: margin },
    });
    y = doc.lastAutoTable.finalY + 8;
  }

  y = await appendUploadedDocumentsToExpediente(
    doc,
    alumno,
    documents,
    opts.documentRequirements ?? alumno?.document_requirements,
    { y, margin, pageW, schoolName, logoData },
  );

  drawReceiptPdfFooter(doc, schoolName, y, margin, pageW);
  return doc;
}

async function exportStudentExpedientePdfBlob (alumno, opts = {}) {
  const doc = await buildStudentExpedientePdfDoc(alumno, opts);
  return doc.output('blob');
}

async function exportStudentExpedientePdf (alumno, opts = {}) {
  const doc = await buildStudentExpedientePdfDoc(alumno, opts);
  const code = alumno?.id || 'alumno';
  doc.save(`expediente-${code}-${new Date().toISOString().slice(0, 10)}.pdf`);
}

function downloadPdfBlob (blob, filename) {
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  a.click();
  URL.revokeObjectURL(url);
}

/**
 * Genera expediente PDF y abre WhatsApp al(los) número(s) elegidos.
 * En navegadores compatibles usa compartir archivo; si no, descarga el PDF y abre wa.me con mensaje.
 */
async function sendExpedientePdfViaWhatsApp (alumno, recipients, opts = {}) {
  if (!recipients?.length) throw new Error('Selecciona al menos un número.');

  const settings = opts.settings || await fetchAcademySettings();
  const blob = await exportStudentExpedientePdfBlob(alumno, {
    payments: opts.payments || [],
    orders: opts.orders || [],
    documents: opts.documents || [],
    documentRequirements: opts.documentRequirements ?? alumno?.document_requirements,
    calendarMonths: opts.calendarMonths || [],
    settings,
    year: opts.year || new Date().getFullYear(),
  });

  const filename = `expediente-${alumno?.id || 'alumno'}.pdf`;
  const file = new File([blob], filename, { type: 'application/pdf' });
  const msg = `Hola, le comparto el expediente de ${alumno?.name || 'su alumno'} (${alumno?.id || ''}) de Tecos Elite VOLLEYBALL.`;

  if (typeof navigator !== 'undefined' && navigator.share) {
    try {
      const canFiles = navigator.canShare?.({ files: [file] });
      if (canFiles) {
        await navigator.share({
          files: [file],
          title: `Expediente ${alumno?.id}`,
          text: msg,
        });
        return { mode: 'share' };
      }
    } catch (e) {
      if (e?.name === 'AbortError') throw e;
    }
  }

  downloadPdfBlob(blob, filename);

  const waText = `${msg}\n\nSe descargó el PDF del expediente; adjúntelo en este chat.`;
  recipients.forEach((r, i) => {
    window.setTimeout(() => {
      if (typeof openWhatsAppChat === 'function') {
        openWhatsAppChat(r.digits, waText);
      } else {
        const text = encodeURIComponent(waText);
        window.open(`https://wa.me/${r.digits}?text=${text}`, '_blank', 'noopener,noreferrer');
      }
    }, i * 600);
  });

  return { mode: 'download_and_wa', count: recipients.length };
}

Object.assign(window, {
  exportStudentExpedientePdf,
  exportStudentExpedientePdfBlob,
  getStudentPhoneRecipients,
  sendExpedientePdfViaWhatsApp,
});
