const express = require('express');
const https = require('https');
const fs = require('fs');
const path = require('path');
const cors = require('cors');
const AdmZip = require('adm-zip');
const Docxtemplater = require('docxtemplater');
const PizZip = require('pizzip');

const app = express();

const randomData = {
    names: ['Max Mustermann', 'Anna Schmidt', 'Tom Weber', 'Lisa König', 'Jan Peters'],
    emails: ['max@example.com', 'anna@example.com', 'tom@example.com', 'lisa@example.com'],
    products: ['Premium Service', 'Standard Lösung', 'Enterprise Paket'],
    companies: ['TechCorp GmbH', 'Innovation AG', 'Digital Solutions']
};

function randomChoice(array) {
    return array[Math.floor(Math.random() * array.length)];
}

function generateRandomValue(tag) {
    const tagLower = tag.toLowerCase();
    if (tagLower.includes('name')) return randomChoice(randomData.names);
    if (tagLower.includes('email')) return randomChoice(randomData.emails);
    if (tagLower.includes('datum')) return new Date().toLocaleDateString('de-DE');
    if (tagLower.includes('projekt')) return 'Dynamisches Projekt ' + Math.floor(Math.random() * 1000);
    if (tagLower.includes('status')) return randomChoice(['Aktiv', 'In Bearbeitung', 'Abgeschlossen']);
    return `[${tag}]`;
}

function generateTableData(tableName, rowCount = 3) {
    const tableData = [];
    for (let i = 0; i < rowCount; i++) {
        if (tableName.toLowerCase().includes('mitarbeiter')) {
            tableData.push({
                nr: i + 1,
                name: randomChoice(randomData.names),
                position: randomChoice(['Manager', 'Developer', 'Designer']),
                email: randomChoice(randomData.emails)
            });
        } else {
            tableData.push({
                nr: i + 1,
                bezeichnung: `Eintrag ${i + 1}`,
                wert: (Math.random() * 1000).toFixed(2)
            });
        }
    }
    return tableData;
}

function extractTemplateTagsFromDocx(filePath) {
    try {
        const zip = new AdmZip(filePath);
        const documentXml = zip.readAsText('word/document.xml');
        const tags = new Set();
        const tableNames = new Set();
        
        const simpleTagRegex = /\{([^{}#\/]+)\}/g;
        let match;
        while ((match = simpleTagRegex.exec(documentXml)) !== null) {
            if (!match[1].startsWith('#') && !match[1].startsWith('/')) {
                tags.add(match[1]);
            }
        }
        
        const loopTagRegex = /\{#([^{}]+)\}/g;
        while ((match = loopTagRegex.exec(documentXml)) !== null) {
            tableNames.add(match[1]);
        }
        
        return {
            simpleTags: Array.from(tags),
            tableNames: Array.from(tableNames),
            tagCount: tags.size + tableNames.size
        };
    } catch (error) {
        return { simpleTags: [], tableNames: [], tagCount: 0 };
    }
}

app.use(cors());
app.use(express.json());
app.use(express.static('public'));

const templatesDir = path.join(__dirname, 'templates');
const outputDir = path.join(__dirname, 'output');

[templatesDir, outputDir].forEach(dir => {
    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
    }
});

let httpsOptions = null;
const certPath = path.join(__dirname, 'ssl', 'cert.pem');
const keyPath = path.join(__dirname, 'ssl', 'key.pem');

if (fs.existsSync(certPath) && fs.existsSync(keyPath)) {
    httpsOptions = {
        cert: fs.readFileSync(certPath),
        key: fs.readFileSync(keyPath)
    };
    console.log('🔒 SSL-Zertifikate gefunden und geladen');
}

// NEUE DOCXTEMPLATER ROUTEN

app.get('/analyze/:templateName', (req, res) => {
    try {
        const templateName = req.params.templateName;
        const templatePath = path.join(templatesDir, templateName);
        
        if (!fs.existsSync(templatePath)) {
            return res.status(404).json({ error: `Template ${templateName} nicht gefunden` });
        }
        
        const analysis = extractTemplateTagsFromDocx(templatePath);
        res.json({
            template: templateName,
            analysis,
            syntax: 'docxtemplater',
            examples: {
                simple: 'Einfache Tags: {name}, {datum}',
                tables: 'Tabellen: {#mitarbeiter}{name}{/mitarbeiter}'
            }
        });
    } catch (error) {
        res.status(500).json({ error: 'Analyse-Fehler', details: error.message });
    }
});

app.post('/generate/:templateName', async (req, res) => {
    try {
        const templateName = req.params.templateName;
        const { tables = {}, data = {} } = req.body;
        
        console.log(`🔄 Generiere: ${templateName}`);
        
        const templatePath = path.join(templatesDir, templateName);
        if (!fs.existsSync(templatePath)) {
            return res.status(404).json({ error: `Template nicht gefunden` });
        }
        
        const content = fs.readFileSync(templatePath, 'binary');
        const zip = new PizZip(content);
        const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true });
        
        const templateData = { ...data };
        const analysis = extractTemplateTagsFromDocx(templatePath);
        
        analysis.simpleTags.forEach(tag => {
            if (!templateData[tag]) {
                templateData[tag] = generateRandomValue(tag);
            }
        });
        
        Object.entries(tables).forEach(([tableName, rowCount]) => {
            console.log(`📊 ${tableName}: ${rowCount} Zeilen`);
            templateData[tableName] = generateTableData(tableName, parseInt(rowCount));
        });
        
        doc.render(templateData);
        
        const buffer = doc.getZip().generate({ type: 'nodebuffer', compression: 'DEFLATE' });
        const timestamp = Date.now();
        const outputFileName = `${templateName.replace('.docx', '')}_${timestamp}.docx`;
        const outputPath = path.join(outputDir, outputFileName);
        
        fs.writeFileSync(outputPath, buffer);
        
        res.json({
            success: true,
            message: `✅ Dokument erstellt`,
            file: outputFileName,
            download: `/download/${outputFileName}`
        });
        
    } catch (error) {
        console.error('Fehler:', error);
        res.status(500).json({ error: 'Generierungs-Fehler', details: error.message });
    }
});

app.post('/demo/:templateName', async (req, res) => {
    try {
        const templateName = req.params.templateName;
        const { tables = {} } = req.body;
        
        console.log(`🎪 Demo: ${templateName}`);
        
        const templatePath = path.join(templatesDir, templateName);
        if (!fs.existsSync(templatePath)) {
            return res.status(404).json({ error: `Template nicht gefunden` });
        }
        
        const analysis = extractTemplateTagsFromDocx(templatePath);
        console.log(`🔍 ${analysis.simpleTags.length} Tags, ${analysis.tableNames.length} Tabellen`);
        
        const autoTables = { ...tables };
        analysis.tableNames.forEach(tableName => {
            if (!autoTables[tableName]) {
                autoTables[tableName] = Math.floor(Math.random() * 5) + 3;
            }
        });
        
        const content = fs.readFileSync(templatePath, 'binary');
        const zip = new PizZip(content);
        const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true });
        
        const templateData = {};
        analysis.simpleTags.forEach(tag => {
            templateData[tag] = generateRandomValue(tag);
        });
        
        Object.entries(autoTables).forEach(([tableName, rowCount]) => {
            templateData[tableName] = generateTableData(tableName, parseInt(rowCount));
        });
        
        doc.render(templateData);
        
        const buffer = doc.getZip().generate({ type: 'nodebuffer', compression: 'DEFLATE' });
        const timestamp = Date.now();
        const outputFileName = `demo_${templateName.replace('.docx', '')}_${timestamp}.docx`;
        const outputPath = path.join(outputDir, outputFileName);
        
        fs.writeFileSync(outputPath, buffer);
        
        res.json({
            success: true,
            message: `🎉 Demo erstellt`,
            file: outputFileName,
            download: `/download/${outputFileName}`,
            analysis: {
                simpleTags: analysis.simpleTags,
                tables: Object.keys(autoTables)
            }
        });
        
    } catch (error) {
        res.status(500).json({ error: 'Demo-Fehler', details: error.message });
    }
});

// UTILITY ROUTEN

app.get('/download/:filename', (req, res) => {
    const filename = req.params.filename;
    const filePath = path.join(outputDir, filename);
    
    if (fs.existsSync(filePath)) {
        res.download(filePath);
    } else {
        res.status(404).json({ error: 'Datei nicht gefunden' });
    }
});

app.get('/templates', (req, res) => {
    try {
        const files = fs.readdirSync(templatesDir)
            .filter(file => file.endsWith('.docx'))
            .map(file => {
                const templatePath = path.join(templatesDir, file);
                const stats = fs.statSync(templatePath);
                const analysis = extractTemplateTagsFromDocx(templatePath);
                
                return {
                    name: file,
                    size: stats.size,
                    modified: stats.mtime,
                    tags: analysis.tagCount,
                    simpleTags: analysis.simpleTags.length,
                    tables: analysis.tableNames.length,
                    analyzeUrl: `/analyze/${file}`,
                    generateUrl: `/generate/${file}`,
                    demoUrl: `/demo/${file}`
                };
            });
        
        res.json({
            templates: files,
            count: files.length,
            syntax: 'docxtemplater',
            info: 'Tags: {tag}, Loops: {#table}{field}{/table}'
        });
    } catch (error) {
        res.status(500).json({ error: 'Template-Fehler', details: error.message });
    }
});

app.get('/files', (req, res) => {
    try {
        const files = fs.readdirSync(outputDir)
            .filter(file => file.endsWith('.docx'))
            .map(file => {
                const filePath = path.join(outputDir, file);
                const stats = fs.statSync(filePath);
                return {
                    name: file,
                    size: stats.size,
                    created: stats.birthtime,
                    download: `/download/${file}`
                };
            })
            .sort((a, b) => new Date(b.created) - new Date(a.created));
        
        res.json({ files, count: files.length });
    } catch (error) {
        res.status(500).json({ error: 'Dateien-Fehler', details: error.message });
    }
});

app.get('/health', (req, res) => {
    res.json({
        status: 'OK',
        engine: 'docxtemplater',
        timestamp: new Date().toISOString(),
        templates: fs.readdirSync(templatesDir).filter(f => f.endsWith('.docx')).length,
        outputs: fs.readdirSync(outputDir).filter(f => f.endsWith('.docx')).length
    });
});

app.use('/webdav/templates', express.static(templatesDir));
app.use('/webdav/output', express.static(outputDir));

// SERVER STARTEN

app.listen(3000, () => {
    console.log('🚀 DOCX Template Server (docxtemplater) läuft auf Port 3000');
    console.log('📁 Templates:', templatesDir);
    console.log('📄 Output:', outputDir);
    console.log('🌐 HTTP: http://localhost:3000');
    console.log('📂 WebDAV: http://localhost:3000/webdav/');
});

if (httpsOptions) {
    https.createServer(httpsOptions, app).listen(3443, () => {
        console.log('🔒 DOCX Template Server (docxtemplater) läuft auf Port 3443');
        console.log('🌐 HTTPS: https://localhost:3443');
        console.log('📂 WebDAV: https://localhost:3443/webdav/');
        console.log('🔐 SSL aktiv');
    });
}
