import PDFKit from 'pdfkit';
import { ReportDataPayload } from '@shieldai/types';

interface PdfContext {
  reportTitle: string;
  periodStart: string;
  periodEnd: string;
  generatedAt: string;
  data: ReportDataPayload;
  reportId: string;
}

function formatDate(dateStr: string): string {
  return new Date(dateStr).toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  });
}

function getScoreColor(score: number): string {
  if (score >= 70) return '#22c55e';
  if (score >= 40) return '#eab308';
  return '#ef4444';
}

export class PdfGenerator {
  async generate(context: PdfContext): Promise<Buffer> {
    return new Promise((resolve, reject) => {
      const doc = new PDFKit({
        size: 'A4',
        margins: { top: 40, bottom: 40, left: 40, right: 40 },
      });

      const chunks: Buffer[] = [];

      doc.on('data', (chunk: Buffer) => chunks.push(chunk));
      doc.on('end', () => resolve(Buffer.concat(chunks)));
      doc.on('error', reject);

      const w = doc.page.width;
      const h = doc.page.height;

      // Header
      doc
        .rect(0, 0, w, 120)
        .fill('#1e40af')
        .fillColor('white')
        .font('Helvetica-Bold')
        .fontSize(24)
        .text(context.reportTitle, 40, 30, { align: 'center' })
        .fontSize(12)
        .fillColor('rgba(255,255,255,0.8)')
        .text(`${formatDate(context.periodStart)} — ${formatDate(context.periodEnd)}`, 40, 70, { align: 'center' })
        .text(`Generated ${formatDate(context.generatedAt)}`, 40, 85, { align: 'center' });

      let y = 140;

      // Protection Score Section
      y = this.drawSectionHeader(doc, 'Protection Score', y);
      const score = context.data.protectionScore;
      const scoreColor = getScoreColor(score);
      doc
        .fillColor(scoreColor)
        .fontSize(48)
        .font('Helvetica-Bold')
        .text(`${score}/100`, 40, y, { align: 'center' });
      y += 60;

      if (context.data.previousProtectionScore !== undefined) {
        const change = score - context.data.previousProtectionScore;
        const changeText = change > 0 ? `+${change} from previous period` : `${change} from previous period`;
        doc
          .fillColor('#64748b')
          .fontSize(11)
          .font('Helvetica')
          .text(changeText, 40, y, { align: 'center' });
        y += 20;
      }

      // Exposure Summary
      y = this.drawSectionHeader(doc, 'Dark Web Exposure Summary', y);
      y = this.drawStatGrid(doc, [
        { label: 'Critical', value: context.data.exposureSummary.criticalExposures, color: '#ef4444' },
        { label: 'Warnings', value: context.data.exposureSummary.warningExposures, color: '#eab308' },
        { label: 'New Findings', value: context.data.exposureSummary.newExposures, color: '#2563eb' },
        { label: 'Resolved', value: context.data.exposureSummary.resolvedExposures, color: '#22c55e' },
      ], y);

      // Spam Protection
      y = this.drawSectionHeader(doc, 'Spam Protection', y);
      y = this.drawStatGrid(doc, [
        { label: 'Calls Blocked', value: context.data.spamStats.callsBlocked, color: '#2563eb' },
        { label: 'Texts Blocked', value: context.data.spamStats.textsBlocked, color: '#2563eb' },
        { label: 'Total Events', value: context.data.spamStats.totalSpamEvents, color: '#2563eb' },
        { label: 'False Positives', value: context.data.spamStats.falsePositives, color: '#64748b' },
      ], y);

      // Voice Protection
      y = this.drawSectionHeader(doc, 'Voice Protection', y);
      y = this.drawStatGrid(doc, [
        { label: 'Analyses Run', value: context.data.voiceStats.analysesRun, color: '#2563eb' },
        { label: 'Threats Detected', value: context.data.voiceStats.threatsDetected, color: '#ef4444' },
        { label: 'Active Enrollments', value: context.data.voiceStats.enrollmentsActive, color: '#2563eb' },
        { label: 'Synthetic Voices', value: context.data.voiceStats.syntheticDetections, color: '#eab308' },
      ], y);

      // Home Title Monitoring (Premium only)
      if (context.data.homeTitleStats) {
        y = this.drawSectionHeader(doc, 'Home Title Monitoring', y);
        y = this.drawStatGrid(doc, [
          { label: 'Properties Monitored', value: context.data.homeTitleStats.propertiesMonitored, color: '#2563eb' },
          { label: 'Changes Detected', value: context.data.homeTitleStats.changesDetected, color: '#eab308' },
          { label: 'Alerts Triggered', value: context.data.homeTitleStats.alertsTriggered, color: '#2563eb' },
        ], y);
      }

      // Recommendations
      if (context.data.recommendations.length > 0) {
        y = this.drawSectionHeader(doc, 'Recommendations', y);
        for (const rec of context.data.recommendations) {
          const priorityColor =
            rec.priority === 'high' ? '#ef4444' : rec.priority === 'medium' ? '#eab308' : '#22c55e';
          doc
            .rect(40, y, 4, 30)
            .fill(priorityColor)
            .fillColor('#1a202c')
            .font('Helvetica-Bold')
            .fontSize(12)
            .text(rec.title, 50, y + 2, { width: w - 100 })
            .font('Helvetica')
            .fontSize(10)
            .fillColor('#475569')
            .text(rec.description, 50, y + 18, { width: w - 100 });
          y += 45;
        }
      }

      // Footer
      doc
        .rect(0, h - 60, w, 60)
        .fill('#f5f7fa')
        .fillColor('#94a3b8')
        .fontSize(10)
        .font('Helvetica')
        .text('ShieldAI — Your Digital Identity Protection', 40, h - 45, { align: 'center' })
        .text(`Report ID: ${context.reportId}`, 40, h - 30, { align: 'center' });

      doc.end();
    });
  }

  private drawSectionHeader(doc: PDFKit.PDFDocument, title: string, y: number): number {
    if (y > 680) {
      doc.addPage();
      y = 40;
    }

    doc
      .fillColor('#1e40af')
      .fontSize(16)
      .font('Helvetica-Bold')
      .text(title, 40, y)
      .rect(40, y + 18, 480, 2)
      .fill('#e2e8f0');

    return y + 30;
  }

  private drawStatGrid(
    doc: PDFKit.PDFDocument,
    stats: Array<{ label: string; value: number; color: string }>,
    y: number
  ): number {
    const cols = Math.min(stats.length, 4);
    const colWidth = (doc.page.width - 80) / cols;

    for (let i = 0; i < stats.length; i += cols) {
      for (let j = 0; j < cols && i + j < stats.length; j++) {
        const stat = stats[i + j];
        const x = 40 + j * colWidth;

        doc
          .rect(x, y, colWidth - 8, 60)
          .fill('#f8fafc')
          .fillColor(stat.color)
          .fontSize(20)
          .font('Helvetica-Bold')
          .text(String(stat.value), x + 4, y + 8, { width: colWidth - 16, align: 'center' })
          .fillColor('#64748b')
          .fontSize(9)
          .font('Helvetica')
          .text(stat.label, x + 4, y + 35, { width: colWidth - 16, align: 'center' });
      }
      y += 70;
    }

    return y + 10;
  }
}

export const pdfGenerator = new PdfGenerator();
