import PDFKit from 'pdfkit';
import { Invoice } from '../../types/invoice.types';

export class ItemsTableSection {
  private doc: PDFKit.PDFDocument;
  private currentY: number;
  private pageHeight: number = 842; // A4 Höhe in Punkten
  private footerHeight: number = 120; // Platz für Footer
  private minRowHeight: number = 20;
  private maxRowHeight: number = 60;

  constructor(doc: PDFKit.PDFDocument, currentY: number) {
    this.doc = doc;
    this.currentY = currentY;
  }

  /**
   * Bereich 3: Tabelle mit Rechnungspositionen
   * DIN 5008: Klare Tabellenstruktur mit ausreichend Abständen
   * Flexibel mit automatischem Seitenumbruch
   */
  public draw(invoice: Invoice): number {
    const tableWidth = 480; // Schmalere Tabelle
    const colWidths = [35, 170, 45, 45, 45, 70, 70]; // Angepasste Spaltenbreiten

    // Tabellenkopf
    this.drawTableHeader(tableWidth, colWidths);

    // Tabellenzeilen mit dynamischer Höhe
    this.drawTableRows(invoice, tableWidth, colWidths);

    // Summen-Bereich
    this.drawTotalsArea(invoice);

    return this.currentY;
  }

  private drawTableHeader(tableWidth: number, colWidths: number[]): void {
    // Kein Rahmen, keine Linien
    this.doc.font('Helvetica-Bold')
      .fontSize(8)
      .fillColor('black')
      .text('', 55, this.currentY + 8, { width: colWidths[0], continued: false }) // Leere erste Spalte
      .text('Bezeichnung', 55 + colWidths[0], this.currentY + 8, { width: colWidths[1], continued: false })
      .text('Menge', 55 + colWidths[0] + colWidths[1], this.currentY + 8, { width: colWidths[2], align: 'center', continued: false })
      .text('Einh.', 55 + colWidths[0] + colWidths[1] + colWidths[2], this.currentY + 8, { width: colWidths[3], align: 'center', continued: false })
      .text('MwSt.', 55 + colWidths[0] + colWidths[1] + colWidths[2] + colWidths[3], this.currentY + 8, { width: colWidths[4], align: 'center', continued: false })
      .text('Einzelpreis', 55 + colWidths[0] + colWidths[1] + colWidths[2] + colWidths[3] + colWidths[4], this.currentY + 8, { width: colWidths[5], align: 'right', continued: false })
      .text('Summe', 55 + colWidths[0] + colWidths[1] + colWidths[2] + colWidths[3] + colWidths[4] + colWidths[5], this.currentY + 8, { width: colWidths[6], align: 'right', continued: false });

    this.currentY += 25;
  }

  private drawTableRows(invoice: Invoice, tableWidth: number, colWidths: number[]): void {
    invoice.items.forEach((item, index) => {
      const descriptionHeight = this.calculateTextHeight(item.description, colWidths[1], 8);
      const rowHeight = Math.max(this.minRowHeight, Math.min(this.maxRowHeight, descriptionHeight + 12));

      if (this.currentY + rowHeight > this.pageHeight - this.footerHeight) {
        this.addNewPage();
        this.drawTableHeader(tableWidth, colWidths);
      }

      // Keine Rahmen, nur horizontale Linie unten
      // Zellen-Inhalte - alle nach oben orientiert
      const topY = this.currentY + 5; // Alle Inhalte 5px vom oberen Rand

      // Position (vertikal oben ausgerichtet, nicht eingerückt)
      this.doc.text((index + 1).toString(), 50, topY, {
        width: colWidths[0],
        align: 'center',
        continued: false
      });

      // Beschreibung (mehrzeilig) - oben ausgerichtet mit fettem Anfang
      this.drawFormattedDescription(item.description, 55 + colWidths[0], topY, colWidths[1]);

      this.doc.text(item.quantity.toString(), 55 + colWidths[0] + colWidths[1], topY, {
        width: colWidths[2],
        align: 'center',
        continued: false
      });

      this.doc.text(item.unit, 55 + colWidths[0] + colWidths[1] + colWidths[2], topY, {
        width: colWidths[3],
        align: 'center',
        continued: false
      });

      this.doc.text(`${item.vatRate}`, 55 + colWidths[0] + colWidths[1] + colWidths[2] + colWidths[3], topY, {
        width: colWidths[4],
        align: 'center',
        continued: false
      });

      this.doc.text(`${item.unitPrice.toFixed(2).replace('.', ',')} ${item.currency}`, 55 + colWidths[0] + colWidths[1] + colWidths[2] + colWidths[3] + colWidths[4], topY, {
        width: colWidths[5],
        align: 'right',
        continued: false
      });

      this.doc.font('Helvetica-Bold')
        .text(`${item.total.toFixed(2).replace('.', ',')} ${item.currency}`, 55 + colWidths[0] + colWidths[1] + colWidths[2] + colWidths[3] + colWidths[4] + colWidths[5], topY, {
          width: colWidths[6],
          align: 'right',
          continued: false
        });

      this.currentY += rowHeight;
    });

    this.currentY += 20;
  }

  private drawFormattedDescription(description: string, x: number, y: number, width: number): void {
    // Teile die Beschreibung in Bezeichnung und Rest
    const parts = this.splitDescription(description);
    
    if (parts.length === 2) {
      // Bezeichnung fett
      this.doc.font('Helvetica-Bold')
        .fontSize(8)
        .text(parts[0], x, y, { width, continued: false });
      
      // Rest normal
      this.doc.font('Helvetica')
        .fontSize(8)
        .text(parts[1], x, y + 10, { width, continued: false });
    } else {
      // Fallback: normale Beschreibung
      this.doc.font('Helvetica')
        .fontSize(8)
        .text(description, x, y, { width, continued: false });
    }
  }

  private splitDescription(description: string): string[] {
    // Suche nach dem ersten Komma oder Bindestrich
    const commaIndex = description.indexOf(',');
    const dashIndex = description.indexOf(' - ');
    
    if (dashIndex !== -1 && (commaIndex === -1 || dashIndex < commaIndex)) {
      // Teile bei " - "
      return [
        description.substring(0, dashIndex),
        description.substring(dashIndex + 3)
      ];
    } else if (commaIndex !== -1) {
      // Teile bei erstem Komma
      return [
        description.substring(0, commaIndex),
        description.substring(commaIndex + 2)
      ];
    }
    
    // Keine Aufteilung möglich
    return [description];
  }

  private calculateTextHeight(text: string, width: number, fontSize: number): number {
    // Temporärer Text zur Höhenberechnung
    const lines = this.wrapText(text, width, fontSize);
    return lines.length * (fontSize + 2); // fontSize + 2 für Zeilenabstand
  }

  private wrapText(text: string, width: number, fontSize: number): string[] {
    // Einfache Text-Umbrüche basierend auf Zeichenbreite
    const avgCharWidth = fontSize * 0.6; // Durchschnittliche Zeichenbreite
    const charsPerLine = Math.floor(width / avgCharWidth);
    
    if (text.length <= charsPerLine) {
      return [text];
    }
    
    const words = text.split(' ');
    const lines: string[] = [];
    let currentLine = '';
    
    words.forEach(word => {
      if ((currentLine + word).length <= charsPerLine) {
        currentLine += (currentLine ? ' ' : '') + word;
      } else {
        if (currentLine) {
          lines.push(currentLine);
        }
        currentLine = word;
      }
    });
    
    if (currentLine) {
      lines.push(currentLine);
    }
    
    return lines;
  }

  private addNewPage(): void {
    this.doc.addPage();
    this.currentY = 50; // Reset Y-Position für neue Seite
  }

  private drawTotalsArea(invoice: Invoice): number {
    // Prüfe ob genug Platz für Summen-Bereich ist
    const totalsHeight = 100; // Geschätzte Höhe für Summen
    
    if (this.currentY + totalsHeight > this.pageHeight - this.footerHeight) {
      this.addNewPage();
    }
    
    // Trennlinie vor Summen
    this.doc.moveTo(50, this.currentY)
      .lineTo(550, this.currentY)
      .lineWidth(0.5) // Dünne Linie
      .stroke();
    this.currentY += 20;
    
    // Zusammenfassung in einer Zeile mit angepassten Schriftgrößen
    this.doc.font('Helvetica')
      .fontSize(9) // Kleinere Schrift für Nettobetrag
      .text(`Nettobetrag: ${invoice.totals.netAmount.toFixed(2).replace('.', ',')} ${invoice.totals.currency}`, 50, this.currentY, { continued: false })
      .text(`MwSt. (${invoice.totals.vatRate.toFixed(2).replace('.', ',')}%): ${invoice.totals.vatAmount.toFixed(2).replace('.', ',')} ${invoice.totals.currency}`, 250, this.currentY, { continued: false })
      .font('Helvetica-Bold')
      .fontSize(12) // Größere Schrift für Gesamtbetrag
      .text(`Gesamtbetrag: ${invoice.totals.grossAmount.toFixed(2).replace('.', ',')} ${invoice.totals.currency}`, 450, this.currentY, { continued: false });
    
    this.currentY += 40;
    
    return this.currentY;
  }
} 