import { describe, it, expect } from 'vitest';
import { pdfGenerator } from './pdf-generator';

const mockData = {
  exposureSummary: {
    totalExposures: 10,
    newExposures: 3,
    resolvedExposures: 2,
    criticalExposures: 1,
    warningExposures: 4,
    infoExposures: 5,
    exposuresBySource: {},
  },
  spamStats: {
    callsBlocked: 15,
    textsBlocked: 20,
    callsFlagged: 5,
    textsFlagged: 8,
    falsePositives: 2,
    totalSpamEvents: 35,
  },
  voiceStats: {
    analysesRun: 50,
    threatsDetected: 3,
    enrollmentsActive: 2,
    syntheticDetections: 3,
    voiceMismatchEvents: 3,
  },
  recommendations: [],
  protectionScore: 75,
};

const pdfContext = {
  reportTitle: 'Monthly Protection Report — January 2025',
  periodStart: '2025-01-01T00:00:00.000Z',
  periodEnd: '2025-01-31T23:59:59.000Z',
  generatedAt: '2025-02-01T00:00:00.000Z',
  data: mockData,
  reportId: 'test-1',
};

describe('PdfGenerator', () => {
  it('generates a non-empty PDF buffer', async () => {
    const pdf = await pdfGenerator.generate(pdfContext);
    expect(pdf).toBeInstanceOf(Buffer);
    expect(pdf.length).toBeGreaterThan(100);
  });

  it('PDF starts with PDF magic bytes', async () => {
    const pdf = await pdfGenerator.generate(pdfContext);
    const header = pdf.subarray(0, 5).toString();
    expect(header).toBe('%PDF-');
  });

  it('PDF ends with %%EOF', async () => {
    const pdf = await pdfGenerator.generate(pdfContext);
    const footer = pdf.subarray(-6).toString();
    expect(footer).toContain('%%EOF');
  });

  it('PDF contains xref table', async () => {
    const pdf = await pdfGenerator.generate(pdfContext);
    const text = pdf.toString('utf8');
    expect(text).toContain('xref');
    expect(text).toContain('trailer');
    expect(text).toContain('startxref');
  });

  it('PDF contains multiple pages', async () => {
    const pdf = await pdfGenerator.generate(pdfContext);
    const text = pdf.toString('utf8');
    // PDFKit creates multiple pages for our report
    expect(text).toContain('/Count 3');
  });

  it('PDF registers both font families', async () => {
    const pdf = await pdfGenerator.generate(pdfContext);
    const text = pdf.toString('utf8');
    expect(text).toContain('Helvetica');
    expect(text).toContain('Helvetica-Bold');
  });

  it('generates PDF with home title section (more content)', async () => {
    const basePdf = await pdfGenerator.generate(pdfContext);
    const premiumPdf = await pdfGenerator.generate({
      ...pdfContext,
      data: {
        ...mockData,
        homeTitleStats: {
          propertiesMonitored: 2,
          changesDetected: 1,
          alertsTriggered: 3,
        },
      },
    });
    // Premium report with extra section should be larger
    expect(premiumPdf.length).toBeGreaterThan(basePdf.length);
  });

  it('generates PDF with recommendations (more content)', async () => {
    const basePdf = await pdfGenerator.generate(pdfContext);
    const withRecs = await pdfGenerator.generate({
      ...pdfContext,
      data: {
        ...mockData,
        recommendations: [
          {
            category: 'dark_web',
            priority: 'high',
            title: 'Address Critical Exposures',
            description: '1 critical exposure detected.',
          },
        ],
      },
    });
    // Report with recommendations should be larger
    expect(withRecs.length).toBeGreaterThan(basePdf.length);
  });

  it('generates PDF with score change (more content)', async () => {
    const basePdf = await pdfGenerator.generate(pdfContext);
    const withChange = await pdfGenerator.generate({
      ...pdfContext,
      data: {
        ...mockData,
        protectionScore: 80,
        previousProtectionScore: 70,
      },
    });
    // Report with score change text should be larger
    expect(withChange.length).toBeGreaterThan(basePdf.length);
  });

  it('generates valid PDF with all required sections', async () => {
    const pdf = await pdfGenerator.generate(pdfContext);
    const text = pdf.toString('utf8');
    // Structural validation
    expect(text).toContain('%PDF-');
    expect(text).toContain('/Type /Catalog');
    expect(text).toContain('/Type /Pages');
    expect(text).toContain('/Type /Page');
    expect(text).toContain('/ProcSet [/PDF /Text');
  });

  it('handles empty recommendations gracefully', async () => {
    const pdf = await pdfGenerator.generate(pdfContext);
    expect(pdf).toBeInstanceOf(Buffer);
    expect(pdf.length).toBeGreaterThan(100);
    const header = pdf.subarray(0, 5).toString();
    expect(header).toBe('%PDF-');
  });
});
