import PDFDocument from 'pdfkit';
import fs from 'fs';
import { Invoice, PDFOptions } from '../types/invoice.types';
import {
  HeaderSection,
  SalutationSection,
  ItemsTableSection,
  ClosingSection,
  FooterSection
} from './sections';

export class PDFGenerator {
  private doc: PDFKit.PDFDocument;
  private options: PDFOptions;
  private currentY: number = 50;

  constructor(options: PDFOptions = {}) {
    this.options = {
      template: 'default',
      language: 'de',
      includeLogo: false,
      logoPath: undefined,
      ...options
    };
    this.doc = new PDFDocument({
      size: 'A4',
      margin: 50,
      compress: false,
      bufferPages: true,
      info: {
        Title: 'Invoice',
        Author: 'Invoice Generator',
        Subject: 'Invoice Document',
        Creator: 'PDFKit',
        Producer: 'PDFKit'
      }
    });
    this.doc.font('Helvetica').fontSize(10);
  }

  public async generateInvoice(invoice: Invoice): Promise<Buffer> {
    return new Promise((resolve, reject) => {
      const chunks: Buffer[] = [];
      this.doc.on('data', (chunk: Buffer) => chunks.push(chunk));
      this.doc.on('end', () => resolve(Buffer.concat(chunks)));
      this.doc.on('error', reject);

      this.generateInvoiceContent(invoice);
      this.doc.end();
    });
  }

  public async generateInvoiceToFile(invoice: Invoice, outputPath: string): Promise<void> {
    return new Promise((resolve, reject) => {
      const writeStream = fs.createWriteStream(outputPath);
      this.doc.pipe(writeStream);

      writeStream.on('finish', resolve);
      writeStream.on('error', reject);
      this.doc.on('error', reject);

      this.generateInvoiceContent(invoice);
      this.doc.end();
    });
  }

  private generateInvoiceContent(invoice: Invoice): void {
    // Reset Y-Position
    this.currentY = 50;

    // Bereich 1: Header mit Adressen und Rechnungsdaten
    const headerSection = new HeaderSection(this.doc, this.currentY, this.options.logoPath);
    this.currentY = headerSection.draw(invoice);

    // Bereich 2: Ansprache zur Rechnung
    const salutationSection = new SalutationSection(this.doc, this.currentY);
    this.currentY = salutationSection.draw(invoice);

    // Bereich 3: Tabelle mit Rechnungspositionen
    const itemsTableSection = new ItemsTableSection(this.doc, this.currentY);
    this.currentY = itemsTableSection.draw(invoice);

    // Bereich 4: Grußformel
    const closingSection = new ClosingSection(this.doc, this.currentY);
    this.currentY = closingSection.draw(invoice);

    // Wiederkehrender Footer
    const footerSection = new FooterSection(this.doc, this.currentY);
    this.currentY = footerSection.draw(invoice);
  }
}

/**
 * Convenience-Funktionen für einfache Verwendung
 */
export async function generateInvoicePDF(invoice: Invoice, options?: PDFOptions): Promise<Buffer> {
  const generator = new PDFGenerator(options);
  return generator.generateInvoice(invoice);
}

export async function generateInvoicePDFToFile(invoice: Invoice, outputPath: string, options?: PDFOptions): Promise<void> {
  const generator = new PDFGenerator(options);
  return generator.generateInvoiceToFile(invoice, outputPath);
} 