import { jsPDF } from 'jspdf';
import autoTable from 'jspdf-autotable';
import { format } from 'date-fns';

// Helper to format currency
const formatCurrency = (amount) => {
  const value = parseFloat(amount);
  if (isNaN(value)) return '$0.00';
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  }).format(value);
};

const REPORT_LAYOUT = {
  MARGIN: 40,
  HEADER_HEIGHT: 60,
  FOOTER_HEIGHT: 40
};

// Table Configuration
const TABLE_THEME = {
  headStyles: { fillColor: [30, 41, 59], textColor: 255, fontStyle: 'bold', fontSize: 10 },
  bodyStyles: { textColor: [51, 65, 85], fontSize: 9, cellPadding: 6 },
  alternateRowStyles: { fillColor: [248, 250, 252] },
  grid: { lineColor: [226, 232, 240], lineWidth: 0.5 },
  margin: { top: REPORT_LAYOUT.HEADER_HEIGHT, right: REPORT_LAYOUT.MARGIN, bottom: REPORT_LAYOUT.FOOTER_HEIGHT, left: REPORT_LAYOUT.MARGIN }
};

const drawSectionHeader = (doc, title, startY) => {
  doc.setFontSize(16);
  doc.setFont('helvetica', 'bold');
  doc.setTextColor(30, 41, 59);
  doc.text(title, REPORT_LAYOUT.MARGIN, startY);
  doc.setLineWidth(0.5);
  doc.setDrawColor(203, 213, 225);
  doc.line(REPORT_LAYOUT.MARGIN, startY + 5, doc.internal.pageSize.width - REPORT_LAYOUT.MARGIN, startY + 5);
  return startY + 20;
};

const drawPageFooter = (doc, pageNum, reportTitle) => {
  const pageHeight = doc.internal.pageSize.height;
  const pageWidth = doc.internal.pageSize.width;
  doc.setFontSize(8);
  doc.setTextColor(148, 163, 184);
  doc.text(`${reportTitle} — Page ${pageNum}`, REPORT_LAYOUT.MARGIN, pageHeight - 15);
  doc.text(format(new Date(), 'MMM dd, yyyy'), pageWidth - REPORT_LAYOUT.MARGIN, pageHeight - 15, { align: 'right' });
};

const cleanText = (text) => {
  if (!text) return '';
  return text.replace(/<[^>]*>/g, '').replace(/&nbsp;/g, ' ').trim();
};

const formatDate = (dateStr) => {
  if (!dateStr) return '-';
  try {
    return format(new Date(dateStr), 'MM/dd/yyyy');
  } catch {
    return '-';
  }
};

export const generateMonthEndReportPdf = async ({
  clientDetails,
  reportMeta,
  sections,
  customSections = [],
  attachments = []
}) => {
  const doc = new jsPDF({
    orientation: 'portrait',
    unit: 'pt',
    format: 'letter'
  });

  const tocEntries = [];
  let pageCounter = 1;

  const addSectionHeader = (title) => {
    if (pageCounter > 1 || tocEntries.length > 0) {
      doc.addPage();
      pageCounter++;
    }
    tocEntries.push({ title, relativePageNumber: doc.internal.getNumberOfPages() });
    return drawSectionHeader(doc, title, 50);
  };

  for (const section of sections) {
    if (!section.data || (Array.isArray(section.data) && section.data.length === 0)) continue;

    let startY = addSectionHeader(section.title);

    switch(section.type) {
      case 'status':
        const statusBody = [];
        section.data.forEach(item => {
          statusBody.push([
            formatDate(item.created_at),
            item.title,
            item.status,
            item.address || 'Association-level'
          ]);
          if (item.content) {
            statusBody.push([{ content: cleanText(item.content), colSpan: 4, styles: { fontStyle: 'italic', textColor: 100 } }]);
          }
        });

        autoTable(doc, {
          startY,
          head: [['Date', 'Title', 'Status', 'Address']],
          body: statusBody,
          ...TABLE_THEME
        });
        break;

      case 'owner':
        autoTable(doc, {
          startY,
          head: [['Posted Date', 'Update Content']],
          body: section.data.map(item => [
            formatDate(item.created_at),
            cleanText(item.content)
          ]),
          columnStyles: { 1: { cellWidth: 400 } },
          ...TABLE_THEME
        });
        break;

      case 'violations':
        const violationsBody = [];
        section.data.forEach(item => {
          violationsBody.push([
            formatDate(item.created_at),
            item.address || 'Association-level',
            item.violation_type || '-',
            item.status,
            item.stage || '-'
          ]);
          const details = [item.description, item.notes].filter(Boolean).join('\n\nNOTES: ');
          if (details) {
            violationsBody.push([{ content: cleanText(details), colSpan: 5, styles: { fontStyle: 'italic', textColor: 100, fontSize: 8 } }]);
          }
        });

        autoTable(doc, {
          startY,
          head: [['Date', 'Address', 'Type', 'Status', 'Stage']],
          body: violationsBody,
          ...TABLE_THEME
        });
        break;

      case 'collections_detailed':
        const { open, resolved, stats } = section.data;
        
        doc.setFontSize(12);
        doc.text('Summary', REPORT_LAYOUT.MARGIN, startY);
        autoTable(doc, {
          startY: startY + 10,
          head: [['Category', 'Count', 'Total Amount']],
          body: [
            ['Open Cases', stats.openCount, formatCurrency(stats.totalAmountOpen)],
            ['Resolved Cases', stats.resolvedCount, formatCurrency(stats.totalAmountResolved)]
          ],
          theme: 'striped',
          styles: { fontSize: 10 },
          margin: TABLE_THEME.margin
        });

        let nextY = doc.lastAutoTable.finalY + 30;

        if (open.length > 0) {
          doc.setFontSize(12);
          doc.text('Open Collections', REPORT_LAYOUT.MARGIN, nextY);
          
          const openBody = [];
          open.forEach(c => {
            openBody.push([
              c.address || 'Association-level',
              c.owner_name,
              formatCurrency(c.amount_due),
              c.stage,
              c.status
            ]);
            if (c.notes) {
              openBody.push([{ content: `NOTES: ${cleanText(c.notes)}`, colSpan: 5, styles: { fontStyle: 'italic', textColor: 100, fontSize: 8 } }]);
            }
          });

          autoTable(doc, {
            startY: nextY + 10,
            head: [['Address', 'Owner', 'Amount Due', 'Stage', 'Status']],
            body: openBody,
            ...TABLE_THEME
          });
          nextY = doc.lastAutoTable.finalY + 30;
        }

        if (resolved.length > 0) {
          doc.setFontSize(12);
          doc.text('Resolved Collections', REPORT_LAYOUT.MARGIN, nextY);
          
          const resolvedBody = [];
          resolved.forEach(c => {
            resolvedBody.push([
              c.address || 'Association-level',
              c.owner_name,
              formatCurrency(c.amount_due),
              c.status
            ]);
            if (c.notes) {
              resolvedBody.push([{ content: `NOTES: ${cleanText(c.notes)}`, colSpan: 4, styles: { fontStyle: 'italic', textColor: 100, fontSize: 8 } }]);
            }
          });

          autoTable(doc, {
            startY: nextY + 10,
            head: [['Address', 'Owner', 'Final Amount', 'Status']],
            body: resolvedBody,
            ...TABLE_THEME
          });
        }
        break;

      case 'estoppels':
        autoTable(doc, {
          startY,
          head: [['Date', 'Address', 'Status', 'Notes']],
          body: section.data.map(item => [
            formatDate(item.created_at),
            item.address || 'Association-level',
            item.status,
            cleanText(item.notes || '-')
          ]),
          ...TABLE_THEME
        });
        break;
      
      case 'callLogs':
        autoTable(doc, {
          startY,
          head: [['Date', 'Caller', 'Type', 'Notes']],
          body: section.data.map(item => [
            formatDate(item.created_at),
            item.caller_name || 'Unknown',
            item.call_type,
            cleanText(item.notes)
          ]),
          columnStyles: { 3: { cellWidth: 200 } },
          ...TABLE_THEME
        });
        break;
    }
  }

  for (const custom of customSections) {
    const startY = addSectionHeader(custom.title);
    
    const stripHtml = (html) => {
      const tmp = document.createElement("DIV");
      tmp.innerHTML = html;
      return tmp.textContent || tmp.innerText || "";
    };
    
    const plainText = stripHtml(custom.content);
    const splitText = doc.splitTextToSize(plainText, doc.internal.pageSize.getWidth() - 80);
    doc.setFont('helvetica', 'normal');
    doc.setFontSize(10);
    doc.text(splitText, REPORT_LAYOUT.MARGIN, startY);
  }

  const pageCount = doc.internal.getNumberOfPages();
  const PAGE_OFFSET = 3; 

  for (let i = 1; i <= pageCount; i++) {
    doc.setPage(i);
    drawPageFooter(doc, i + PAGE_OFFSET, "Management Report");
  }
  
  return {
    pdfBuffer: doc.output('arraybuffer'),
    sectionMap: tocEntries
  };
};
