"use strict";

const crypto = require("crypto");

const htmlentities = require("html-entities");
const markdown = require("markdown-it")({
	xhtmlOut: true
});
const chroma = require("chroma-js");

const markdown_prism = require("markdown-it-prism");
markdown.use(markdown_prism, {
	init: (Prism) => {
		Prism.languages.weacmd = {
			"string": /\<[^>]+?\>/,
			"function": /^(?:\/\/\S+)\b/m,
			"number": /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?%?/i,
			"operator": /[<>:=\[\]|{}]/,
			"keyword": /\b(?:[-+]?[zyx])\b/
		}
	}
});

function extract_title(line) {
	return line.match(/#+\s+(.+)\s*/)[1].replace(/^`*|`*$/g, "")
}

function make_section(acc, cat_current, cats) {
	let title = extract_title(acc[0]);
	return {
		category: cat_current,
		category_colour: cats.get(cat_current),
		category_colour_dark: chroma(cats.get(cat_current))
			.set("hsl.s", 0.8)
			.set("hsl.l", "*0.6")
			.css("hsl"),
		title: htmlentities.encode(title),
		slug: title.toLowerCase().replace(/[^a-z0-9-_\s]+/gi, "")
			.replace(/\s+/g, "-")
			.replace(/-.*$/, ""),
		content: markdown.render(acc.slice(1).join("\n"))
			.replace(/<h4(\/?)>/g, "<h3$1>")
			.replace(/<h5(\/?)>/g, "<h4$1>")
	};
}

module.exports = function parse_sections(source) {
	const cats = new Map();
	source.match(/^##\s+.*$/gm)
		.map(extract_title)
		.map((item, i, all) => cats.set(
			item,
			chroma(`hsl(${i/all.length*(360-360/all.length)}, 60%, 90%)`).css("hsl")
		));
	const lines = source.split(/\r?\n/gi);
	const result = [];
	let acc = [];
	let cat_current = null;
	for(let line of lines) {
		
		if(line.startsWith(`#`)) {
			let heading_level = line.match(/^#+/)[0].length;
			
			// 1: Deal with the previous section
			if(acc.length > 0) {
				let heading_level_prev = acc[0].match(/^#+/)[0].length;
				if(heading_level_prev === 3 && acc.length > 0 && heading_level <= 3) {
					result.push(make_section(acc, cat_current, cats));
				}
				
			}
			
			// 2: Deal with the new line
			
			if(heading_level === 2)
				cat_current = extract_title(line);
			
			if(heading_level > 3)
				acc.push(line)
			else
				acc = [ line ];
		}
		else
			acc.push(line);
	}
	
	if(acc.length > 0)
		result.push(make_section(acc, cat_current, cats));
	
	return { sections: result, categories: cats };
}
