import { Document } from "mongoose";
import { IStory, Story } from "@models/stories";
import { FormStory } from "@client/types/form/story";
import { storyQuerier } from "@server/dbHelpers";
import { isLoggedIn } from "@server/middlewareButNotReally";
import { canModify } from "@server/middlewareButNotReally/storyPrivileges";
import { bodyHandler, getBucket, modelFormChapter, replaceOrUploadContent } from "@server/storyHelpers";
import { countWords } from "@functions";
import { messages } from "@server/constants";

export default eventHandler(async (ev) => {
	let os: (Document<unknown, {}, IStory> & IStory) | null = await storyQuerier(ev);
	isLoggedIn(ev);
	if (!canModify(ev, os)) {
		throw createError({
			statusCode: 403,
			message: messages[403],
		});
	}
	const body: FormStory = await readBody<FormStory>(ev);
	const update: Partial<IStory> = {
		title: body.title,
		completed: body.completed,
		coAuthor: !!body.coAuthor ? body.coAuthor : null,
	};
	for (const oc of os.chapters) {
		let filename = `/stories/${oc.id}.txt`;
		const bucket = getBucket();
		const curs = bucket.find({ filename }).limit(1);
		for await (const d of curs) {
			await bucket.delete(d._id);
		}
	}
	const cc = os.chapters;
	os.chapters = [];
	await os.save();
	for (const c of body.chapters) {
		let idx = cc.findIndex((k) => k.id === c.id);
		const cont = await bodyHandler(c);
		if (idx === -1) {
			os.chapters!.push({
				...modelFormChapter(c),
				posted: new Date(Date.now()),
			});
		} else {
			os.chapters!.push({
				...modelFormChapter(c),
				// id: os.chapters[idx].id,
				words: countWords(cont),
				posted: cc[idx].posted,
			});
		}
	}
	await os.save();
	for (let i = 0; i < os.chapters.length; i++) {
		const c = os.chapters[i];
		const cont = await bodyHandler(body.chapters[i]);
		await replaceOrUploadContent(c.id ?? c._id, cont);
	}
	os = await Story.findOneAndUpdate(
		{
			_id: os._id,
		},
		update,
		{ new: true },
	);
	if (!os) {
		throw createError({
			statusCode: 500,
			message: "Something went wrong.",
		});
	}
	return {
		success: true,
		story: os.toObject(),
	};
});