const { setSurvey } = require('../../connection');
const definitions = require('../definitions');

async function getShots (client, sequenceId) {
	const text = `
		SELECT *
		FROM event_log
		WHERE
			($1::numeric IS NULL OR sequence = $1)
			AND meta ? 'qc_id'
		ORDER BY sequence, point, meta->>'qc_id';
	`;

	const values = [ sequenceId ?? null ];

	const res = await client.query(text, values);

	return res?.rows;
}

async function getSequences (client, sequenceId) {
	const text = `
		SELECT *
		FROM raw_lines
		WHERE
			($1::numeric IS NULL OR sequence = $1)
		ORDER BY sequence;
	`;

	const values = [ sequenceId ?? null ];

	const res = await client.query(text, values);

	return res?.rows;
}

function makeTree (leaf, sequences, shots) {
	if (!leaf.disabled) {
		const res = {...leaf};

		if (leaf.children) {
			res.children = leaf.children.map(child => makeTree(child, sequences, shots));
		}

		// Get sequences that mention this test's ID in their
		// own metadata or in their shots metadata.
		const leafSequences = sequences.map(seq => {
			const sequenceShots = shots.filter(pnt => pnt.sequence == seq.sequence && pnt.meta.qc_id == leaf.id);

			if (seq.meta?.qc?.[leaf.id] || sequenceShots.length) {
				const sequence = {...seq};
				sequence.shots = sequenceShots;
				return sequence;
			}

			return null;
		}).filter(seq => seq !== null);

		res.sequences = leafSequences;

		return res;
	}
	// return undefined
}

async function get (projectId, sequenceId, opts = {}) {
	const client = await setSurvey(projectId);

	const tree = await definitions.get(projectId) ?? [];
	const shots = await getShots(client, sequenceId);
	const sequences = await getSequences(client, sequenceId);

	let res;

	if (opts.flat) {
		res = {
			sequences: sequences.filter(i => i.meta?.qc),
			shots
		}
	} else {
		res = tree.map(leaf => makeTree(leaf, sequences, shots));
	}

	client.release();
	return res;
}

module.exports = get;
