const express = require('express');
const multer = require('multer');
const Joi = require('joi');
const pdfProcessor = require('./pdfProcessor');

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

// Configure multer for memory storage
const upload = multer({
    storage: multer.memoryStorage(),
    fileFilter: (req, file, cb) => {
        if (file.mimetype === 'application/pdf') {
            cb(null, true);
        } else {
            cb(new Error('Only PDF files are allowed'));
        }
    },
    limits: {
        fileSize: 10 * 1024 * 1024 // 10MB limit
    }
});

// Middleware for parsing JSON
app.use(express.json());

// Input validation schema
const metadataSchema = Joi.array().items(
    Joi.object({
        name: Joi.string().required(),
        lastname: Joi.string().required()
    })
).required();

const requestSchema = Joi.object({
    pagesPerDoc: Joi.number().integer().min(1).required(),
    metadata: metadataSchema
});

// Route for processing PDF
app.post('/process-pdf', upload.single('file'), async (req, res) => {
    try {
        // Parse metadata from form field
        let metadata;
        try {
            metadata = JSON.parse(req.body.metadata);
        } catch (error) {
            return res.status(400).json({ error: 'Invalid metadata JSON format' });
        }

        const data = {
            pagesPerDoc: parseInt(req.body.pagesPerDoc, 10),
            metadata: metadata
        };

        // Validate request body
        const { error, value } = requestSchema.validate(data);
        if (error) {
            return res.status(400).json({ error: error.details[0].message });
        }

        if (!req.file) {
            return res.status(400).json({ error: 'No PDF file uploaded' });
        }

        const { pagesPerDoc } = value;

        // Process the PDF
        const outputFiles = await pdfProcessor.splitPDF(
            req.file.buffer,
            pagesPerDoc,
            metadata
        );

        // Convert files to base64 and prepare response
        const processedFiles = outputFiles.map(file => ({
            filename: file.filename,
            content: file.buffer.toString('base64'),
            contentType: 'application/pdf'
        }));

        // Return the processed files
        res.json({
            message: 'PDF processed successfully',
            files: processedFiles
        });

    } catch (error) {
        console.error('Error processing PDF:', error);
        res.status(500).json({ error: error.message });
    }
});

// Error handling middleware
app.use((error, req, res, next) => {
    if (error instanceof multer.MulterError) {
        return res.status(400).json({ error: 'File upload error: ' + error.message });
    }
    next(error);
});

// Function to start server with port finding
const startServer = (initialPort) => {
    const server = app.listen(initialPort)
        .on('error', (err) => {
            if (err.code === 'EADDRINUSE') {
                console.log(`Port ${initialPort} is busy, trying ${initialPort + 1}...`);
                startServer(initialPort + 1);
            } else {
                console.error('Server error:', err);
            }
        })
        .on('listening', () => {
            const actualPort = server.address().port;
            console.log(`Server running at http://localhost:${actualPort}`);
        });
};

// Start the server with initial port
startServer(port);