const http = require('http');
const  url = require('url');
const   fs = require('fs');
const  ejs = require('ejs');

const { people, anonImg, getNextID } = require('./data/members');


// Helper function for sending 404 message
function send404(response) {
	response.writeHead(404, {'Content-Type': 'text/plain'});
	response.write('Error 404: Resource not found.');
	response.end();
}

// Return the MIME type given the filename
function getMimeType(filename) {
	if (filename.endsWith(".js")) return "application/javascript";
	if (filename.endsWith(".css")) return "text/css";
	if (filename.endsWith(".jpg") || filename.endsWith(".jpeg")) return "image/jpeg";
	if (filename.endsWith(".png")) return "image/png";
	if (filename.endsWith(".html")) return "text/html";
	return "text/plain";
}

// Send back the specific file requested (html, JavaScript, css, jpg, or plain text)
function serveStaticFile(filePath, res) {
	fs.readFile(filePath, function(err, data)  {
		if (err) {
			res.writeHead(404);
			res.end("File not found");
		} else {
			res.writeHead(200, { "Content-Type": getMimeType(filePath) });
			res.end(data);
    	}
	});
}

// Render an EJS page
function renderPage(templatePath, res, data = {}) {
	ejs.renderFile(templatePath, data, function(err, html) {
		if (err) {
			console.error(err);
			res.writeHead(500);
			res.end("Internal Server Error");
		} else {
			res.writeHead(200, { 'Content-Type': 'text/html' });
			res.end(html);
		}
	});
}

// Handle individual profile
function respondWithProfile(res, id) {
	// This is not an efficient way of finding people. You may want to use a HashMap.
	let person = null;
	for (let i=0; i<people.length; i++) {
		if (people[i].id == id) {
			person = people[i];
			break;
		}
	}
	// If the person is not found, send back an error
	if (person === null) {
		send404(res);
		return;
	}
  	renderPage('./views/profile.ejs', res, { person, anonImg });
}

// 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);
	});
}

// Helper function to add a message to a person's profile
function addMessage(msg) {
	for (let i=0; i<people.length; i++) {
		if (people[i].id === msg.id) {
			people[i].messages.push(msg.message); // add it
			return true;
		}
	}
	return false;
}

// Listener for incoming client requests
function handleRequest(req, res) {
	const parsed = url.parse(req.url, true); // get the query params (for profile pages)
	const pathname = parsed.pathname;        // get path without query

	// Handle all GET requests
	if (req.method === 'GET') {
		if (pathname === '/' || pathname === '/home') {// Return the main page
			renderPage('./views/index.ejs', res, { people });
		} else if (pathname.startsWith("/profile")) { // Return a specific profile
			respondWithProfile(res, parsed.query.id);
		} else if (pathname.startsWith("/about")) {    // Return the about page
			renderPage('./views/about.ejs', res);
		} else if (pathname === '/clientscript.js') {  // Return the client-side javascript
			serveStaticFile('./clientscript.js', res);
		} else if (pathname.startsWith('/images/')) {  // Return an image for a page
			serveStaticFile('.' + pathname, res);
		} else if (pathname === "/style.css") {        // Return the style file
			serveStaticFile('.' + pathname, res);
		} else { // If anything else ... respond with 404 error
			send404(res);
		}
  	}
	// Combination of PUT and /newprofile is interpreted as a request to create a profile
	else if (req.method === 'PUT' && pathname === '/newprofile') {
		readRequestBody(req, function(body) {
			const newPerson = JSON.parse(body);
			newPerson.id = getNextID();
			newPerson.messages = [];
 			people.push(newPerson);
			res.writeHead(200, { 'Content-Type': 'text/plain' });
			res.end();
		});
	// Combination of POST and /message is interpreted as a request to add a message
	} else if (req.method === 'POST' && pathname === '/message') {
		readRequestBody(req, function(body) {
			const msg = JSON.parse(body);
			if (addMessage(msg)) {
				res.writeHead(200, { 'Content-Type': 'text/plain' });
				res.end();
			} else {
				send404(res);
			}
		});
	} else {
		res.writeHead(405);
		res.end("Unsupported method");
	}
}

// Start server
http.createServer(handleRequest).listen(3000);
console.log("Server running on http://localhost:3000");
