let g_hash;

async function query(sql, params) {
	let results = [];
	await ssb.sqlAsync(sql, params, function (row) {
		results.push(row);
	});
	return results;
}

async function resolve(id) {
	try {
		let blob = await ssb.blobGet(id);
		if (blob) {
			let json;
			try {
				json = JSON.parse(utf8Decode(blob));
			} catch {
				return {id: utf8Decode(blob)};
			}
			if (json?.links) {
				for (let [key, value] of Object.entries(json.links)) {
					json.links[key] = await resolve(value);
				}
				return json;
			} else {
				return 'huh?' + json;
			}
		} else {
			return `missing<${id}>`;
		}
	} catch (e) {
		return id + ': ' + e.message;
	}
}

async function get_names(identities) {
	return Object.fromEntries(
		(
			await query(
				`
		SELECT author, name FROM (
			SELECT
				messages.author,
				RANK() OVER (PARTITION BY messages.author ORDER BY messages.sequence DESC) AS author_rank,
				messages.content ->> 'name' AS name
			FROM messages
			JOIN json_each(?) AS identities ON identities.value = messages.author
			WHERE
				json_extract(messages.content, '$.type') = 'about' AND
				content ->> 'about' = messages.author AND name IS NOT NULL)
		WHERE author_rank = 1
	`,
				[JSON.stringify(identities)]
			)
		).map((x) => [x.author, x.name])
	);
}

async function render(hash) {
	g_hash = hash;
	if (!hash) {
		let sites = await query(
			`
			SELECT site.author, site.id
			FROM messages site
			WHERE site.content ->> 'type' = 'web-init'
		`,
			[]
		);
		let names = await get_names(sites.map((x) => x.author));
		if (hash === g_hash) {
			await app.setDocument(
				`<ul style="background-color: #ddd">${sites.map((x) => `<li><a target="_top" href="#${encodeURIComponent(x.id)}">${names[x.author] ?? x.author} - ${x.id}</a></li>`).join('\n')}</ul>`
			);
		}
	} else {
		let site_id =
			hash.charAt(0) == '#'
				? decodeURIComponent(hash.substring(1))
				: decodeURIComponent(hash);
		await app.setDocument(`<html style="margin: 0; padding: 0; width: 100vw; height: 100vh; margin: 0; padding: 0">
			<body style="display: flex; flex-direction: column; width: 100vw; height: 100vh">
				<iframe src="${encodeURIComponent(site_id)}/index.html" style="flex: 1 1; border: 0; background-color: #fff"></iframe>
			</body>
		</html>`);
	}
}

core.register('message', async function message_handler(message) {
	if (message.event == 'hashChange') {
		await render(message.hash);
	}
});

async function main() {
	render(null);
}

main();
