const alert = require("../../../alerts");
const configuration = require('../../configuration');

async function getDistance (client, payload) {
	const text = `
		SELECT ST_Distance(pp0.geometry, pp1.geometry) distance
		FROM preplot_points pp0,
		preplot_points pp1
		WHERE
			pp0.line = $1 AND pp1.line = $1
			AND pp0.class = $4 AND pp1.class = $4
			AND pp0.point = $2 AND pp1.point = $3;
	`;

	const p = payload;
	const res = await client.query(text, [p.line, p.fsp, p.lsp, p.class || "V"]);
	if (res.rows.length) {
		return res.rows[0].distance;
	} // else undefined
}

async function getSequence (client) {
	// Get the next free sequence from planned data
	// if there is any planned lines, if not get the
	// next available from raw lines
	const text = `
		WITH p AS (
			SELECT max(sequence) AS sequence
			FROM planned_lines
		),
		r AS (
			SELECT max(sequence) AS sequence
			FROM raw_lines
		)
		SELECT COALESCE(p.sequence, r.sequence)+1 AS sequence
		FROM p, r;
	`;

	const res = await client.query(text);
	// If no sequences have been found, assume none have been shot
	// and return 1
	return (res.rows[0] && res.rows[0].sequence) || 1;
}

async function getTimestamps (client, projectId, payload) {

	const defaultLineChangeDuration = (await configuration.get(projectId, "planner/defaultLineChangeDuration") || 30) * 60*1000; // minutes to milliseconds

	const defaultAcquisitionSpeed = (await configuration.get(projectId, "planner/defaultAcquisitionSpeed") || 4.8) * 1.852 / 3.6; // Knots to m/s

	const distance = await getDistance(client, payload);

	const text = `
		SELECT * FROM planned_lines;
	`;

	const res = await client.query(text);

	const ts0 = new Date(
		(res.rows.length
			? res.rows.map(r => r.ts1).reduce( (a, b) => Math.max(a, b) )
			: Date.now()
		) + defaultLineChangeDuration
	);

	const ts1 = new Date(ts0.valueOf() + (distance / defaultAcquisitionSpeed)*1000);

	return {ts0, ts1};
}

async function getSequencesForLine (client, line) {
	const text  = `
		SELECT * from sequences_summary WHERE line = $1 ORDER BY sequence;
	`;

	const res = await client.query(text, [line]);
	return res.rows;
}

async function getPlanned (client) {
	const text = `
		SELECT * FROM planned_lines ORDER BY sequence;
	`;

	const res = await client.query(text);
	return res.rows;
}


async function getLineName (client, projectId, payload) {
	// FIXME TODO Get line name script from configuration
	// Ref.: https://gitlab.com/wgp/dougal/software/-/issues/129

	// This is to monitor #165
	// https://gitlab.com/wgp/dougal/software/-/issues/incident/165
	if (!payload?.line) {
		alert({function: "getLineName", client, projectId, payload});
	}

	const planned = await getPlanned(client);
	const previous = await getSequencesForLine(client, payload.line);
	const attempt = planned.filter(r => r.line == payload.line).concat(previous).length;
	const p = payload;
	const incr = p.lsp > p.fsp;
	const sequence = p.sequence || 1;
	const line = p.line;
	return `${incr?"1":"2"}0${line}${attempt}${sequence.toString().padStart(3, "0")}S00000`;
}


module.exports = {
	getDistance,
	getSequence,
	getTimestamps,
	getSequencesForLine,
	getPlanned,
	getLineName
};
