const fs = require("fs");
const gm = require("./gm");

const app = require("express")();
const tasks = new Object();

app.use((req, res, next) => {
	//return next();  // <-- Disable All CORS
	res.setHeader("Access-Control-Allow-Origin", "*");
	res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
	res.setHeader("Access-Control-Allow-Headers", "Content-Type");

	if (req.method === "OPTIONS") {
		return res.sendStatus(200);
	}

	next();
});
app.use(require("body-parser").json());

function shuffle(array) {
	for (let i = array.length - 1; i > 0; i--) {
		let j = Math.floor(Math.random() * (i + 1));
		[array[i], array[j]] = [array[j], array[i]];
	}
}

function getHash(length = 3) {
	return Buffer.from(
		[...new Array(length)].map((x) => Math.round(Math.random() * 255)),
	).toString("hex");
}

app.post("/test", async (req, res) => {
	if (!tasks.test) {
		return res.status(400).json({
			isError: true,
			message: "'test' is unknown task",
		});
	}

	console.log(req.body);
	if (!req.body?.answer)
		return res.status(400).json({
			isError: true,
			message: "Empty field 'answer' in JSON-body",
		});
	const solve = req.body.answer;
	if (solve === tasks.test.solve) {
		const successCode = tasks.test.solveHash
		delete tasks.test;
		return res.json({
			isError: false,
			isSuccess: true,
			successCode,
		});
	} else {
		delete tasks.test;
		return res.json({
			isError: false,
			isSuccess: false,
			tryAgain: "/test",
		});
	}
});

app.get("/test", async (req, res) => {
	if (tasks.test)
		return res.json({
			isError: false,
			mode: "3x3",
			fragments: tasks.test.fragments,
		});

	//const choosenImage = fs.readFileSync("./images/791082.jpg");
	//const choosenImage = fs.readFileSync("./images/f2bc8547eb879cef0b782ff2cda8baaf.jpg");
	const choosenImage = fs.readFileSync("./images/5922524_16876101.jpg");
	//const choosenImage = fs.readFileSync("./images/g619806.jpg");
	//const choosenImage = fs.readFileSync("./images/576746.jpg");
	const results = [];

	const fragments = new Object();
	let solve = "";
	const addOps = [];
	for (let row = 0; row < 3; row++)
		for (let col = 0; col < 3; col++) {
			let key;
			do {
				key = getHash();
			} while (!!fragments[key]);
			solve += key;
			const shardBytes = await gm.repixelise(
				await gm.cropImage(choosenImage, 50, 50, col * 50, row * 50),
			);
			addOps.push(
				() =>
					(fragments[key] =
						`data:image/png;base64,${shardBytes.toString("base64")}`),
			);
		}

	shuffle(addOps);
	addOps.forEach((f) => f());
	const solveHash = getHash(8);

	tasks.test = { fragments, solve, solveHash };
	console.log("Required solve:", solve);
	res.json({
		isError: false,
		mode: "3x3",
		fragments,
	});
});

app.listen(8081, (err) => {
	if (err) throw err;
	console.info(`Listening: 8081`);
});
