const express = require('express');
const fs = require('fs');
const path = require('path');
const { createReport } = require('docx-templates');
const cors = require('cors');
const auth = require('basic-auth');

const app = express();
const PORT = process.env.PORT || 3000;

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

// Template-Ordner erstellen falls nicht vorhanden
const templatesDir = path.join(__dirname, 'templates');
const outputDir = path.join(__dirname, 'output');

if (!fs.existsSync(templatesDir)) {
    fs.mkdirSync(templatesDir, { recursive: true });
}

if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
}

// WebDAV-ähnliche Routen für Dateizugriff (ohne Authentifizierung)
app.use('/webdav/output', express.static(outputDir));
app.use('/webdav/templates', express.static(templatesDir));

// Output-Dateien über WebDAV-ähnliche URL bereitstellen
app.use('/webdav/output', express.static(outputDir, {
    setHeaders: (res, path) => {
        res.set('DAV', '1, 2');
        res.set('MS-Author-Via', 'DAV');
    }
}));

// Templates über WebDAV-ähnliche URL bereitstellen
app.use('/webdav/templates', express.static(templatesDir, {
    setHeaders: (res, path) => {
        res.set('DAV', '1, 2');
        res.set('MS-Author-Via', 'DAV');
    }
}));

// WebDAV PROPFIND Support (vereinfacht)
app.propfind('/webdav/*', (req, res) => {
    const requestPath = req.path.replace('/webdav/', '');
    const isOutput = requestPath.startsWith('output');
    const dirPath = isOutput ? outputDir : templatesDir;
    
    try {
        const files = fs.readdirSync(dirPath);
        const xml = `<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:">
${files.map(file => {
    const filePath = path.join(dirPath, file);
    const stats = fs.statSync(filePath);
    return `
    <D:response>
        <D:href>/webdav/${requestPath}/${file}</D:href>
        <D:propstat>
            <D:prop>
                <D:displayname>${file}</D:displayname>
                <D:getcontentlength>${stats.size}</D:getcontentlength>
                <D:getlastmodified>${stats.mtime.toUTCString()}</D:getlastmodified>
                <D:resourcetype>${stats.isDirectory() ? '<D:collection/>' : ''}</D:resourcetype>
            </D:prop>
            <D:status>HTTP/1.1 200 OK</D:status>
        </D:propstat>
    </D:response>`;
}).join('')}
</D:multistatus>`;
        
        res.set('Content-Type', 'application/xml; charset=utf-8');
        res.send(xml);
    } catch (error) {
        res.status(404).send('Not found');
    }
});

// Route: Template hochladen
app.post('/upload-template', (req, res) => {
    // Hier würde normalerweise multer für File-Upload verwendet
    res.json({ message: 'Template-Upload-Endpoint bereit' });
});

// Route: DOCX mit Daten befüllen
app.post('/generate-document', async (req, res) => {
    try {
        const { templateName, data } = req.body;
        
        if (!templateName || !data) {
            return res.status(400).json({ 
                error: 'Template-Name und Daten sind erforderlich' 
            });
        }

        const templatePath = path.join(templatesDir, templateName);
        
        if (!fs.existsSync(templatePath)) {
            return res.status(404).json({ 
                error: 'Template nicht gefunden' 
            });
        }

        // Template laden
        const template = fs.readFileSync(templatePath);

        // Dokument mit Daten befüllen
        const buffer = await createReport({
            template,
            data: data,
            cmdDelimiter: ['{{', '}}'], // Template-Syntax
        });

        // Eindeutigen Dateinamen erstellen
        const timestamp = Date.now();
        const outputFileName = `document_${timestamp}.docx`;
        const outputPath = path.join(outputDir, outputFileName);

        // Befülltes Dokument speichern
        fs.writeFileSync(outputPath, buffer);

        // Download-Link zurückgeben
        res.json({
            success: true,
            downloadUrl: `/download/${outputFileName}`,
            message: 'Dokument erfolgreich erstellt'
        });

    } catch (error) {
        console.error('Fehler beim Erstellen des Dokuments:', error);
        res.status(500).json({ 
            error: 'Fehler beim Erstellen des Dokuments',
            details: error.message 
        });
    }
});

// Route: Dokument herunterladen
app.get('/download/:filename', (req, res) => {
    const filename = req.params.filename;
    const filePath = path.join(outputDir, filename);

    if (!fs.existsSync(filePath)) {
        return res.status(404).json({ error: 'Datei nicht gefunden' });
    }

    res.download(filePath, filename, (err) => {
        if (err) {
            console.error('Download-Fehler:', err);
            res.status(500).json({ error: 'Download-Fehler' });
        }
    });
});

// Route: Verfügbare Templates auflisten
app.get('/templates', (req, res) => {
    try {
        const templates = fs.readdirSync(templatesDir)
            .filter(file => file.endsWith('.docx'))
            .map(file => ({
                name: file,
                path: `/templates/${file}`
            }));

        res.json(templates);
    } catch (error) {
        res.status(500).json({ 
            error: 'Fehler beim Auflisten der Templates' 
        });
    }
});

// Beispiel-Route: Daten von externem Service abrufen
app.get('/external-data/:id', async (req, res) => {
    try {
        const id = req.params.id;
        
        // Hier würden Sie normalerweise Daten von einem externen API abrufen
        // Beispiel mit fetch oder axios
        
        // Beispiel-Daten für Demonstration
        const exampleData = {
            id: id,
            name: 'Max Mustermann',
            email: 'max@beispiel.de',
            date: new Date().toLocaleDateString('de-DE'),
            items: [
                { product: 'Produkt A', quantity: 2, price: 29.99 },
                { product: 'Produkt B', quantity: 1, price: 49.99 },
                { product: 'Produkt C', quantity: 3, price: 19.99 }
            ],
            total: 129.95
        };

        res.json(exampleData);
    } catch (error) {
        res.status(500).json({ 
            error: 'Fehler beim Abrufen der externen Daten' 
        });
    }
});

// Kombinierte Route: Externe Daten abrufen und Dokument erstellen
app.post('/generate-from-external/:id', async (req, res) => {
    try {
        const id = req.params.id;
        const { templateName } = req.body;

        // Externe Daten abrufen (simulation)
        const externalData = {
            id: id,
            name: 'Max Mustermann',
            email: 'max@beispiel.de',
            date: new Date().toLocaleDateString('de-DE'),
            items: [
                { product: 'Produkt A', quantity: 2, price: 29.99 },
                { product: 'Produkt B', quantity: 1, price: 49.99 },
                { product: 'Produkt C', quantity: 3, price: 19.99 }
            ],
            total: 129.95
        };

        // Template-Pfad
        const templatePath = path.join(templatesDir, templateName);
        
        if (!fs.existsSync(templatePath)) {
            return res.status(404).json({ 
                error: 'Template nicht gefunden' 
            });
        }

        // Template laden und befüllen
        const template = fs.readFileSync(templatePath);
        const buffer = await createReport({
            template,
            data: externalData,
            cmdDelimiter: ['{{', '}}'],
        });

        // Datei speichern
        const timestamp = Date.now();
        const outputFileName = `document_${id}_${timestamp}.docx`;
        const outputPath = path.join(outputDir, outputFileName);
        fs.writeFileSync(outputPath, buffer);

        res.json({
            success: true,
            downloadUrl: `/download/${outputFileName}`,
            data: externalData,
            message: 'Dokument mit externen Daten erstellt'
        });

    } catch (error) {
        console.error('Fehler:', error);
        res.status(500).json({ 
            error: 'Fehler beim Erstellen des Dokuments mit externen Daten' 
        });
    }
});

// Health Check
app.get('/health', (req, res) => {
    res.json({ 
        status: 'OK', 
        message: 'DOCX Template Server läuft',
        webdav: 'WebDAV-ähnliche Endpoints auf Port 3000',
        timestamp: new Date().toISOString()
    });
});

// WebDAV Info Endpoint
app.get('/webdav-info', (req, res) => {
    res.json({
        webdav: {
            url: 'http://localhost:3000',
            endpoints: {
                templates: 'http://localhost:3000/webdav/templates/',
                output: 'http://localhost:3000/webdav/output/'
            },
            credentials: {
                admin: 'password123',
                user: 'docx2024'
            },
            instructions: {
                windows: 'Als Netzlaufwerk: http://localhost:3000/webdav/output/',
                macos: 'Finder > Mit Server verbinden: http://localhost:3000/webdav/output/',
                linux: 'dav://localhost:3000/webdav/output/ oder direkt über Browser'
            },
            note: 'Vereinfachte WebDAV-Implementation - verwenden Sie Browser oder HTTP-Clients'
        }
    });
});

// Datei-Management Endpoints
app.get('/files/output', (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,
                    modified: stats.mtime,
                    webdavUrl: `http://localhost:3000/webdav/output/${file}`,
                    downloadUrl: `/download/${file}`
                };
            })
            .sort((a, b) => b.modified - a.modified);

        res.json({
            files,
            count: files.length,
            webdavAccess: 'http://localhost:3000/webdav/output/'
        });
    } catch (error) {
        res.status(500).json({ 
            error: 'Fehler beim Auflisten der Dateien' 
        });
    }
});

app.delete('/files/output/:filename', (req, res) => {
    try {
        const filename = req.params.filename;
        const filePath = path.join(outputDir, filename);
        
        if (!fs.existsSync(filePath)) {
            return res.status(404).json({ error: 'Datei nicht gefunden' });
        }
        
        fs.unlinkSync(filePath);
        res.json({ 
            success: true, 
            message: `Datei ${filename} gelöscht` 
        });
    } catch (error) {
        res.status(500).json({ 
            error: 'Fehler beim Löschen der Datei' 
        });
    }
});

// Server starten
app.listen(PORT, () => {
    console.log(`🚀 DOCX Template Server läuft auf Port ${PORT}`);
    console.log(`📁 Templates-Ordner: ${templatesDir}`);
    console.log(`📄 Output-Ordner: ${outputDir}`);
    console.log(`🌐 Health Check: http://localhost:${PORT}/health`);
    console.log(`🗂️ WebDAV-ähnliche Endpoints:`);
    console.log(`   Templates: http://localhost:${PORT}/webdav/templates/`);
    console.log(`   Output:    http://localhost:${PORT}/webdav/output/`);
    console.log(`👤 Login: admin/password123 oder user/docx2024`);
});

module.exports = app;