const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
const pug = require('pug'); 
const querystring = require('querystring');

const { products } = require('./data/product-data.js');
let { messages, messageCount } = require('./data/product-data.js');

const PORT = 3000;
const mimeTypes = {
    '.html': 'text/html',
    '.css':  'text/css',
    '.js':   'application/javascript',
    '.png':  'image/png',
    '.jpg':  'image/jpeg',
    '.ico':  'image/x-icon'
};


function send404(response){
	response.statusCode = 404;
	response.write("Not Found");
	response.end();
}


// Precompiled templates - done at startup
const compiledTemplateFunctions = {};
['./views/pages/index.pug', './views/pages/about.pug', './views/pages/contact.pug', 
 './views/pages/product.pug', './views/pages/products.pug', './views/pages/messageReceived.pug'].forEach(name => {
  compiledTemplateFunctions[name] = pug.compileFile(`${name}`);
});


// Render a PUG file as requested
function renderPage(fileName, res, pageName) {
    console.log("RENDERING: " + fileName);
    try {
        const renderFn = compiledTemplateFunctions[fileName];
        if (!renderFn) { // Make sure that things pre-compiled ok
            res.writeHead(404);
            res.end('Template Not Found');
            return;
        }
        const html = renderFn({products: products, currentPage: pageName}); // Call the precompiled function
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.end(html);
    } catch (err) {
        console.error(err);
        res.writeHead(500);
        res.end('Internal Server Error');
    }
}


// Render a product PUG file as requested
function renderProductPage(fileName, res, id) {
    try {
        const renderFn = compiledTemplateFunctions[fileName];
        if (!renderFn) { // Make sure that things pre-compiled ok
            res.writeHead(404);
            res.end('Template Not Found');
            return;
        }
        const html = renderFn({prod: products[id-1], currentPage: 'products'}); // Call the precompiled function
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.end(html);
    } catch (err) {
        console.error(err);
        res.writeHead(500);
        res.end('Internal Server Error');
    }
}


// Serve static files as requested
function serveStaticFile(req, res) {
    const filePath = path.join(__dirname, req.url);
    const ext = path.extname(filePath);
    const contentType = mimeTypes[ext] || 'application/octet-stream';

    fs.readFile(filePath, (err, data) => {
        if (err) {
            send404(res);
        } else {
            res.writeHead(200, { 'Content-Type': contentType });
            res.end(data);
        }
    });
}


// Helper function to read the request body
function readRequestBody(req, callback) {
	let body = ""
	req.on('data', (chunk) => {
		body += chunk;
	})
	//Once the entire body is ready, process the request
	req.on('end', () => {
		callback(body);
	});
}

// Handle the message post
function handlePost(req, res) {
    readRequestBody(req, function(body) {
		const mesgObj = querystring.parse(body);
        console.log(messages);
        messages.push(mesgObj);
        messageCount++;
        renderPage('./views/pages/messageReceived.pug', res, 'contact/message')
    });
}

// Handle incoming requests
function requestListener(req, res) {
    let parsedUrl = url.parse(req.url, true); // true parses query string
    let pathName = parsedUrl.pathname;
    let query = parsedUrl.query;

    // Serve static files if the URL matches typical file folders
    if (pathName.startsWith('/styles/') || pathName.startsWith('/images/') || pathName.startsWith('/icons/') || pathName.startsWith('/scripts/')) {
        serveStaticFile(req, res);
        return;
    }

    // Render PUG pages
    switch (pathName) {
        case '/':
        case '/home':
        case '/index':
            renderPage('./views/pages/index.pug', res, 'home');
            break;
        case '/about':
            renderPage('./views/pages/about.pug', res, 'about');
            break;
        case '/contact':
            renderPage('./views/pages/contact.pug', res, 'contact');
            break;
        case '/products':
            renderPage('./views/pages/products.pug', res, 'products');
            break;
        case '/product':
            if (query.id) 
                renderProductPage('./views/pages/product.pug', res, query.id);
            else 
                send404(res);
            break;
        case '/contact/message':
            handlePost(req, res);
            break;
        default:
            send404(res);
    } 
}

http.createServer(requestListener).listen(PORT);
console.log(`Server running at http://localhost:${PORT}`);
