#!/usr/bin/env node

import {findItemEDBID} from './lodestone.mjs';
import {MediaWikiClient} from './mediawiki.mjs';
import {diff} from './util.mjs';

/**
 * Matches an empty `id-edb` infobox parameter which can just have a value
 * inserted after it.
 */
const existingEmptyEDBIDParameter = /^(\s*\|\s*id-edb\s*=)\s*$/m;

/**
 * Matches an `id-gt` infobox parameter above which we can insert an `id-edb`
 * parameter above. Whitespace in capture groups so the inserted parameter can
 * use the exact same formatting.
 */
const existingGTIDParameter = /^(\s*)\|(\s*)id-gt(\s*)=(\s*).*$/m;

/**
 * Inserts the `id-edb` item infobox parameter into the given page contents.
 * @param {string} pageContent
 * @param {string} edbID
 * @returns {string}
 */
function insertInfoboxEDBID (pageContent, edbID) {
	if (pageContent.includes(`edb-id = ${edbID}`)) {
		console.log('what????', pageContent);
		throw new Error('Page seems to already contain its own EDB ID??');
	}
	if (pageContent.match(existingEmptyEDBIDParameter)) {
		console.log('Page has existing empty `id-edb` parameter');
		return pageContent.replace(existingEmptyEDBIDParameter, `$1 ${edbID}`);
	}
	if (pageContent.match(existingGTIDParameter)) {
		console.log('Page has `id-gt` parameter, inserting `id-edb` above that');
		return pageContent.replace(existingGTIDParameter, `$1|$2id-edb$3=$4${edbID}\n$&`);
	}
	console.log('bad', pageContent);
	throw new Error('Dunno how to insert the parameter into this page');
}

if (!process.env.MW_USERNAME || !process.env.MW_PASSWORD) {
	console.error('Environment variables `MW_USERNAME` and `MW_PASSWORD` are required.');
	process.exit(1);
}

// Log into our wiki client
const mw = new MediaWikiClient('https://ffxiv.consolegameswiki.com/mediawiki');
await mw.login(process.env.MW_USERNAME, process.env.MW_PASSWORD);

// Get pages in the "Missing EDB ID" category
const itemPagesWithoutEDBIDs = await mw.listCategoryPages('Category:Missing EDB ID', 500);
console.log('Processing', itemPagesWithoutEDBIDs.length, 'item pages from [[Category:Missing EDB ID]]\n');

for (const {title} of itemPagesWithoutEDBIDs) {
	// this runs serially with an artificial delay between requests to decrease
	// the chance of sqenix sending ninjas to my house
	await new Promise(resolve => setTimeout(resolve, 5000));

	console.log('Page:', title);
	// look up on EDB
	const edbID = await findItemEDBID(title);
	if (!edbID) {
		console.log('No EDB ID found for this item, skipping');
		continue;
	}
	console.log('EDB ID:', edbID, `(https://na.finalfantasyxiv.com/lodestone/playguide/db/item/${encodeURIComponent(edbID)})`);

	// rewrite wiki page to include id-edb infobox parameter
	let updatedText;
	try {
		const originalText = await mw.readPage(title);
		updatedText = insertInfoboxEDBID(originalText, edbID);
		diff(originalText, updatedText);
	} catch (error) {
		console.log(error);
		console.log('not doing anything with this item');
		continue;
	}

	// write the new stuff back to the wiki
	try {
		await mw.editPage(title, updatedText, "Add EDB item ID", true);
	} catch (error) {
		console.error(error);
		console.error('writes should not fail, this seems bad, dying now');
		process.exit(1);
	}
	console.log('Written.');
	console.log();
}

console.log('done!');