const { stringify } = require('csv');
const { transform, prepare } = require('../../../../../lib/sse');

const json = async function (req, res, next) {
	try {
		const query = req.query;
		query.sequence = req.params.sequence;
		const {events, sequences} = await prepare(req.params.project, query);
		if ("download" in query || "d" in query) {
			const extension = "csv";
			// Get the sequence number(s) (more than one sequence can be selected)
			const seqNums = query.sequence.split(";");
			// If we've only been asked for a single sequence, get its line name
			const lineName = (sequences.find(i => i.sequence == seqNums[0]) || {})?.meta?.lineName;
			const filename = (seqNums.length  == 1 && lineName)
				? `${lineName}-NavLog.${extension}`
				: `${req.params.project}-${query.sequence}.${extension}`;
			res.set("Content-Disposition", `attachment; filename="${filename}"`);
		}

		const columns = {
			id: "id",
			unix_epoch: (row) => Math.floor(row.tstamp/1000),
			timestamp: (row) => (new Date(row.tstamp)).toISOString(),
			sequence: "sequence",
			point: "point",
			text: "remarks",
			labels: (row) => row.labels.join(";"),
			latitude: (row) => {
				if (row.meta.geometry?.type == "Point" && row.meta.geometry?.coordinates) {
					return row.meta.geometry.coordinates[1];
				}
			},
			longitude: (row) => {
				if (row.meta.geometry?.type == "Point" && row.meta.geometry?.coordinates) {
					return row.meta.geometry.coordinates[0];
				}
			}
		};

		let fields = [ "timestamp", "sequence", "point", "text", "labels", "latitude", "longitude", "id" ];

		if (req.query.fields) {
			fields = req.query.fields.split(/[,;:.\s+*|]+/);
		}

		let delimiter = req.query.delimiter || ",";

		const stringifier = stringify({delimiter});
		stringifier.on('error', (err) => {
			console.error(err.message);
		});

		stringifier.on('readable', () => {
			while((row = stringifier.read()) !== null) {
				res.write(row);
			}
		});

		res.status(200);

		if (!req.query.header || req.query.header.toLowerCase() == "true" || req.query.header == "1") {
			// Send header
			stringifier.write(fields);
		}

		events.forEach( event => {
			stringifier.write(fields.map( field => {
				if (typeof columns[field] === "function") {
					return columns[field](event);
				} else {
					return event[columns[field]];
				}
			}));
		});

		stringifier.end();
		res.end();
		next();
	} catch (err) {
		next(err);
	}
};

module.exports = json;
