const EleventyFetch = require('@11ty/eleventy-fetch');
const fs = require('fs');
const merge = require('lodash/merge')

const wordpressPassword = process.env.WORDPRESS_PASSWORD;
const auth = Buffer.from(`lewis:${wordpressPassword}`).toString('base64');

const dateSort = (a, b) => new Date(b.date) - new Date(a.date);

class PostCache {
	constructor() {
		this.readCache();
	}

	readCache() {
		if (!fs.existsSync(".cache")) {
			fs.mkdirSync(".cache");
		}
		
		if (!fs.existsSync(".cache/wordpress_post_fetch.json")) {
			this.last_read_date = null;
			this.posts = {};
		} else {
			const data = JSON.parse(fs.readFileSync(".cache/wordpress_post_fetch.json"));
			this.last_read_date = new Date(data.last_read_date);
			this.posts = data.posts;
		}
	}

	writeCache() {
		fs.writeFileSync(".cache/wordpress_post_fetch.json", JSON.stringify(this, null, 2));
	}

	async fetchCommentsByType(type = "comment") {
		const params = new URLSearchParams();
		params.set("per_page", 100);
		params.set("type", type);

		if (this.last_read_date) {
			params.set("modified_after", this.last_read_date.toISOString());
		}

		const response = await fetch(`https://lewisdale.dev/wp-json/wp/v2/comments?${params.toString()}`, {
			headers: {
				"Authorization": `Basic ${auth}`
			}
		});
		return await response.json()
	}

	async fetchComments() {
		const comments = [...await this.fetchCommentsByType(), ...await this.fetchCommentsByType("webmention")];
		
		comments.forEach(comment => {
			if (this.posts[comment.post]) {
				this.posts[comment.post].comments[comment.id] = comment;
			}
		});
	}

	async fetchPosts() {
		const params = new URLSearchParams();
		params.set("per_page", 100);

		if (this.last_read_date) {
			params.set("modified_after", this.last_read_date.toISOString());
		}

		const response = await fetch(`https://lewisdale.dev/wp-json/wp/v2/posts?${params.toString()}`, {
			headers: {
				"Authorization": `Basic ${auth}`
			}
		});
		const posts = await response.json();

		posts.forEach(post => {
			this.posts[post.id] = merge({ comments: {} }, this.posts[post.id], post);
		});
	}

	async fetchLatest() {
		await this.fetchPosts();
		await this.fetchComments();

		this.last_read_date = new Date();
		this.writeCache();
	}
}

const mapComment = comment => ({
	author: {
		name: comment.author_name,
		avatars: comment.author_avatar_urls,
		url: comment.meta.semantic_linkbacks_author_url,
	},
	content: comment.content.rendered,
	canonical: comment.meta.semantic_linkbacks_canonical,
	date: comment.date,
});


module.exports = async () => {
	const cache = new PostCache();
	await cache.fetchLatest();

	return Object.values(cache.posts)
		.sort(dateSort)
		.map(post => ({
			...post,
			comments: Object.values(post.comments)
				.sort(dateSort)
				.reduce((comments, comment) => {
					if (!comments[comment.meta.semantic_linkbacks_type]) {
						comments[comment.meta.semantic_linkbacks_type] = [];
					}

					comments[comment.meta.semantic_linkbacks_type].push(mapComment(comment));
					return comments;
				}, { like: [], reply: [], repost: [] })
		}));
};