var md = require('../kaverti_modules/markdown-it')({
	html:         false,        // Enable HTML tags in source
	xhtmlOut:     false,        // Use '/' to close single tags (<br />).
								// This is only for full CommonMark compatibility.
	breaks:       true,        // Convert '\n' in paragraphs into <br>
	langPrefix:   'language-',  // CSS language prefix for fenced blocks. Can be
								// useful for external highlighters.
	linkify:      true,        // Autoconvert URL-like text to links
	image: false,

	// Enable some language-neutral replacement + quotes beautification
	typographer:  true,

	// Double + single quotes replacement pairs, when typographer enabled,
	// and smartquotes on. Could be either a String or an Array.
	//
	// For example, you can use '«»„“' for Russian, '„“‚‘' for German,
	// and ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'] for French (including nbsp).
	quotes: '“”‘’',

	// Highlighter function. Should return escaped HTML,
	// or '' if the source string is not changed and should be escaped externally.
	// If result starts with <pre... internal wrapper is skipped.
	highlight: function (/*str, lang*/) { return ''; }
});
md.disable('image')
var emoji = require('markdown-it-emoji');
var twemoji = require('twemoji')
md.use(emoji);
md.renderer.rules.emoji = function(token, idx) {
	return twemoji.parse(token[idx].content);
};
let createDOMPurify = require('dompurify');
let { JSDOM } = require('jsdom');
var marked = require('marked')
let window = new JSDOM('').window;
let DOMPurify = createDOMPurify(window);
var escaped_str = require('querystring')
const Errors = require('../lib/errors')


const renderer = new marked.Renderer();
renderer.image = function (text) {
	return text;
};
renderer.link = function (href, title, text) {
	if (!href.match(/[a-z]+:\/\/.+/i)) {
		href = 'http://' + href;
	}

	return `
		<a href='/out/?uri=${href}' ${title ? "title='" + title + "'" : ""} target='_blank' rel='noopener'>
			${text}
		</a>
	`;
}


module.exports = (sequelize, DataTypes) => {
	let Post = sequelize.define('Post', {
		content: {
			type: DataTypes.TEXT,
			set (val) {
				if(!val) {
					throw Errors.sequelizeValidation(sequelize, {
						error: 'content must be a string',
						path: 'content'
					})
				}

				let rawHTML = md.render(val);
				let cleanHTML = DOMPurify.sanitize(rawHTML);
				let plainText =  (new JSDOM(cleanHTML)).window.document.body.textContent;

				if (!plainText.trim().length) {
					throw Errors.sequelizeValidation(sequelize, {
						error: 'Post content must not be empty',
						path: 'content'
					})
				}


				this.setDataValue('content', cleanHTML)
				this.setDataValue('plainText', plainText)
			},
			allowNull: false
		},
		plainText: {
			type: DataTypes.TEXT,
		},
		postNumber: DataTypes.INTEGER,
		replyingToUsername: DataTypes.STRING,
		removed: {
			type: DataTypes.BOOLEAN,
			defaultValue: false
		}
	})
	Post.associate = function (models) {
		Post.belongsTo(models.User)
		Post.belongsTo(models.Thread)
		Post.hasMany(models.Post, { as: 'Replies', foreignKey: 'replyId' })
		Post.belongsToMany(models.User, { as: 'Likes', through: 'user_post' })

		Post.hasMany(models.Report, { foreignKeyConstraint: true, onDelete: 'CASCADE', hooks: true })
	}
	Post.includeOptions = function () {
		let models = sequelize.models

		return [
			{ model: models.User, attributes: ['username', 'createdAt', 'id', 'color', 'picture'] },
			{ model: models.User, as: 'Likes', attributes: ['username', 'createdAt', 'id', 'color', 'picture'] },
			{ model: models.Thread, include: [models.Category]} ,
			{
				model: models.Post, as: 'Replies', include:
					[{ model: models.User, attributes: ['username', 'id', 'color', 'picture'] }]
			}
		]
	}
	Post.prototype.getReplyingToPost = function (id, thread) {
		let { Thread, User } = sequelize.models
		let replyingToPost = Post.findByPk(
			id,
			{ include: [Thread, { model: User, attributes: ['username'] }] }
		)

		if(!replyingToPost) {
			throw Errors.invalidParameter('replyingToId', 'post does not exist')
		} else if(replyingToPost.Thread.id !== thread.id) {
			throw Errors.invalidParameter('replyingToId', 'replies must be in same thread')
		} else if (replyingToPost.removed) {
			throw Errors.postRemoved
		} else {
			return replyingToPost
		}
	}
	Post.prototype.setReplyingTo = function (post) {
		return post.getUser().then(user => {
			return this.update({ replyingToUsername: user.username, replyId: post.id })
		})
	}
	Post.prototype.getReplyingTo = function () {
		return Post.findByPrimary(this.replyId)
	}
		return Post
}
