import { promises as fs } from "fs";
import path from "path";
import dateFns from "date-fns";
import slugify from "@sindresorhus/slugify";
import { Page, PostMetadata } from "../metadata";
import * as metadata from "../metadata";
import * as markdown from "../markdown";
import layout from "../layout";
import * as util from "../util";

async function generateTutorials(group: string): Promise<Page[]> {
	const tutorials: Page[] = [];

	const files = await fs.readdir(`site/tutorials/${group}`);
	for (const f of files) {
		let page = await metadata.get(path.join("site/tutorials", group, f));

		if (!(<PostMetadata>page.metadata).permalink) {
			let postMeta = <PostMetadata>page.metadata;
			postMeta.date = dateFns.parse(postMeta.date);
			postMeta.slug = postMeta.slug || slugify(postMeta.title);
			postMeta.permalink = `/tutorials/${group}/${postMeta.slug}/`;
		}

		if (page.metadata.source && page.metadata.source!.endsWith(".md")) {
			(<PostMetadata>page.metadata).wordCount = util.getWordCount(page.text);
			(<PostMetadata>page.metadata).readingTime = util.getReadingTime((<PostMetadata>page.metadata).wordCount);

			page.text = markdown.render(page.text);
		}

		const renderedText = await layout(page.text, page.metadata, page.metadata.layout || "tutorial.html.ejs");

		let dest = page.metadata.permalink;
		if (dest.endsWith("/")) {
			dest += "index.html";
		}

		util.write(dest, renderedText);

		tutorials.push(page);
	}

	return tutorials;
}

export interface TutorialSeries {
	index: Page;
	posts: Page[];
	series: string;
	seriesName: string;
}

interface TutorialIndexMetadata extends PostMetadata {
	lastUpdated?: Date;
	group?: string;
}

async function generateTutorialsAndIndex(group: string, title: string): Promise<TutorialSeries> {
	let tutorials = await generateTutorials(group);
	tutorials = tutorials.sort((a, b) => {
		const aDate = <Date>(<PostMetadata>a.metadata).date;
		const bDate = <Date>(<PostMetadata>b.metadata).date;
		return aDate.getTime() - bDate.getTime();
	});

	const page = await metadata.get("site/tutorial-series.html.ejs");

	(<PostMetadata>page.metadata).permalink = `/tutorials/${group}/`;
	(<PostMetadata>page.metadata).title = title;
	(<TutorialIndexMetadata>page.metadata).group = group;
	(<TutorialIndexMetadata>page.metadata).lastUpdated = <Date>(<PostMetadata>tutorials[tutorials.length - 1].metadata).date

	page.text = util.render(page.text, {
		tutorials,
		metadata: page.metadata
	}, "site/tutorial-series.html.ejs");

	page.text = await layout(page.text, page.metadata, page.metadata.layout!);

	util.write(path.join("tutorials", group, "index.html"), page.text);

	return {
		index: page,
		posts: tutorials,
		series: group,
		seriesName: title
	};
}

async function generateIndex(allSeries: TutorialSeries[]) {
	const page = await metadata.get("site/tutorials.html.ejs");

	page.text = util.render(page.text, {
		allSeries
	}, "site/tutorials.html.ejs");

	page.text = await layout(page.text, page.metadata, page.metadata.layout!);

	util.write("tutorials/index.html", page.text);
}

export default async function tutorials(): Promise<TutorialSeries[]> {
	const series = [
		await generateTutorialsAndIndex("forge-modding-1102", "Forge Mods for 1.10.2"),
		await generateTutorialsAndIndex("forge-modding-1112", "Forge Mods for 1.11.2"),
		await generateTutorialsAndIndex("forge-modding-112", "Forge Mods for 1.12")
	];

	generateIndex(series);

	return series;
}
