const PDFDocument = require('pdfkit');
const fs = require('fs');
const path = require('path');

class PDFGenerator {
    constructor() {
        this.doc = new PDFDocument({
            size: 'A4',
            margins: {
                top: 50,
                bottom: 50,
                left: 50,
                right: 50
            }
        });
        this.currentY = 50;
    }

    /**
     * Add Cereda Systems header with logo
     */
    addHeader(title, subtitle = '') {
        // Company name
        this.doc
            .fontSize(20)
            .fillColor('#3fa3a3')
            .font('Helvetica-Bold')
            .text('Cereda Systems GmbH', { align: 'center' });

        this.currentY = this.doc.y + 10;

        // Title
        this.doc
            .fontSize(16)
            .fillColor('#1e293b')
            .font('Helvetica-Bold')
            .text(title, { align: 'center' });

        this.currentY = this.doc.y + 5;

        // Subtitle
        if (subtitle) {
            this.doc
                .fontSize(10)
                .fillColor('#64748b')
                .font('Helvetica')
                .text(subtitle, { align: 'center' });

            this.currentY = this.doc.y + 5;
        }

        // Horizontal line
        this.doc
            .moveTo(50, this.currentY + 10)
            .lineTo(545, this.currentY + 10)
            .strokeColor('#3fa3a3')
            .lineWidth(2)
            .stroke();

        this.currentY += 30;
        this.doc.y = this.currentY;

        return this;
    }

    /**
     * Add section title
     */
    addSectionTitle(title) {
        this.currentY = this.doc.y + 10;

        this.doc
            .fontSize(14)
            .fillColor('#1e293b')
            .font('Helvetica-Bold')
            .text(title, 50, this.currentY);

        this.currentY = this.doc.y + 10;
        this.doc.y = this.currentY;

        return this;
    }

    /**
     * Add text paragraph
     */
    addText(text, options = {}) {
        const defaultOptions = {
            fontSize: 10,
            color: '#334155',
            font: 'Helvetica',
            align: 'left'
        };

        const opts = { ...defaultOptions, ...options };

        this.doc
            .fontSize(opts.fontSize)
            .fillColor(opts.color)
            .font(opts.font)
            .text(text, {
                align: opts.align,
                continued: opts.continued || false
            });

        this.currentY = this.doc.y + 5;

        return this;
    }

    /**
     * Add key-value pair
     */
    addKeyValue(key, value, options = {}) {
        const x = options.x || 50;
        const y = this.currentY;

        this.doc
            .fontSize(10)
            .fillColor('#64748b')
            .font('Helvetica-Bold')
            .text(`${key}:`, x, y, { continued: true, width: 150 })
            .fillColor('#1e293b')
            .font('Helvetica')
            .text(` ${value || '-'}`);

        this.currentY = this.doc.y + 5;

        return this;
    }

    /**
     * Add table
     */
    addTable(headers, rows, options = {}) {
        const startX = options.x || 50;
        const startY = this.currentY;
        const columnWidth = options.columnWidth || 120;
        const rowHeight = options.rowHeight || 25;

        // Draw header
        this.doc
            .fontSize(9)
            .fillColor('#ffffff')
            .font('Helvetica-Bold');

        headers.forEach((header, index) => {
            const x = startX + (index * columnWidth);

            // Header background
            this.doc
                .rect(x, startY, columnWidth, rowHeight)
                .fillAndStroke('#3fa3a3', '#3fa3a3');

            // Header text
            this.doc
                .fillColor('#ffffff')
                .text(header, x + 5, startY + 8, {
                    width: columnWidth - 10,
                    ellipsis: true
                });
        });

        // Draw rows
        rows.forEach((row, rowIndex) => {
            const y = startY + rowHeight + (rowIndex * rowHeight);

            this.doc
                .fontSize(9)
                .fillColor('#1e293b')
                .font('Helvetica');

            row.forEach((cell, colIndex) => {
                const x = startX + (colIndex * columnWidth);

                // Row background (alternating)
                this.doc
                    .rect(x, y, columnWidth, rowHeight)
                    .fillAndStroke(rowIndex % 2 === 0 ? '#f8fafc' : '#ffffff', '#e2e8f0');

                // Cell text
                this.doc
                    .fillColor('#1e293b')
                    .text(cell || '-', x + 5, y + 8, {
                        width: columnWidth - 10,
                        ellipsis: true
                    });
            });
        });

        this.currentY = startY + rowHeight + (rows.length * rowHeight) + 20;
        this.doc.y = this.currentY;

        return this;
    }

    /**
     * Add checklist
     */
    addChecklist(items, checkedItems = {}) {
        this.currentY = this.doc.y + 10;

        items.forEach((item) => {
            const isChecked = checkedItems[item.key] || false;
            const checkbox = isChecked ? '[X]' : '[ ]';

            this.doc
                .fontSize(10)
                .fillColor(isChecked ? '#10b981' : '#64748b')
                .font('Helvetica-Bold')
                .text(checkbox, 50, this.currentY, { continued: true })
                .font('Helvetica')
                .fillColor('#1e293b')
                .text(' ' + item.label);

            this.currentY = this.doc.y + 8;
        });

        this.currentY += 10;
        this.doc.y = this.currentY;

        return this;
    }

    /**
     * Add signature fields
     */
    addSignatureFields(fields) {
        this.currentY = this.doc.y + 20;

        const fieldWidth = 200;
        const spacing = (545 - 50 - (fields.length * fieldWidth)) / (fields.length - 1);

        fields.forEach((field, index) => {
            const x = 50 + (index * (fieldWidth + spacing));

            // Signature line
            this.doc
                .moveTo(x, this.currentY + 40)
                .lineTo(x + fieldWidth, this.currentY + 40)
                .strokeColor('#94a3b8')
                .lineWidth(1)
                .stroke();

            // Field label
            this.doc
                .fontSize(9)
                .fillColor('#64748b')
                .font('Helvetica')
                .text(field.label, x, this.currentY + 45, {
                    width: fieldWidth,
                    align: 'center'
                });

            // Date field
            this.doc
                .fontSize(8)
                .fillColor('#94a3b8')
                .text('Datum: _______________', x, this.currentY + 60, {
                    width: fieldWidth,
                    align: 'center'
                });
        });

        this.currentY += 100;
        this.doc.y = this.currentY;

        return this;
    }

    /**
     * Add footer
     */
    addFooter(text) {
        const bottomY = 800;

        // Horizontal line
        this.doc
            .moveTo(50, bottomY - 20)
            .lineTo(545, bottomY - 20)
            .strokeColor('#e2e8f0')
            .lineWidth(1)
            .stroke();

        // Footer text
        this.doc
            .fontSize(8)
            .fillColor('#94a3b8')
            .font('Helvetica')
            .text(text, 50, bottomY - 10, {
                align: 'center'
            });

        return this;
    }

    /**
     * Add page break
     */
    addPageBreak() {
        this.doc.addPage();
        this.currentY = 50;
        this.doc.y = this.currentY;

        return this;
    }

    /**
     * Save PDF to file
     */
    async saveToFile(filePath) {
        return new Promise((resolve, reject) => {
            // Ensure directory exists
            const dir = path.dirname(filePath);
            if (!fs.existsSync(dir)) {
                fs.mkdirSync(dir, { recursive: true });
            }

            const stream = fs.createWriteStream(filePath);

            this.doc.pipe(stream);
            this.doc.end();

            stream.on('finish', () => resolve(filePath));
            stream.on('error', reject);
        });
    }

    /**
     * Get PDF as buffer
     */
    async getBuffer() {
        return new Promise((resolve, reject) => {
            const buffers = [];

            this.doc.on('data', buffers.push.bind(buffers));
            this.doc.on('end', () => resolve(Buffer.concat(buffers)));
            this.doc.on('error', reject);

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

module.exports = PDFGenerator;
