let db = require('@config/database')

let Notes = module.exports = {}

Notes.create = (userId, noteText) => {
	return new Promise((resolve, reject) => {

		const created = Math.round((+new Date)/1000)

		db.promise()
		.query('INSERT INTO notes (user, text, created) VALUES (?,?,?)', [userId, noteText, created])
		.then((rows, fields) => {
			resolve(rows[0].insertId) //Only return the new note ID when creating a new note
		})
		.catch(console.log)
	})
}

Notes.update = (userId, noteId, noteText) => {
	return new Promise((resolve, reject) => {

		const now = Math.round((+new Date)/1000)

		db.promise()
		.query('UPDATE notes SET text = ?, updated = ? WHERE id = ? AND user = ? LIMIT 1', [noteText, now, noteId, userId])
		.then((rows, fields) => {
			resolve(rows[0])
		})
		.catch(console.log)
	})
}

Notes.delete = (userId, noteId) => {
	return new Promise((resolve, reject) => {
		//Create new note, return created or finger your butt
	})
}

Notes.get = (userId, noteId) => {
	return new Promise((resolve, reject) => {
		db.promise()
		.query('SELECT text, updated FROM notes WHERE user = ? AND id = ? LIMIT 1', [userId,noteId])
		.then((rows, fields) => {
			resolve(rows[0][0])
		})
		.catch(console.log)
	})
}

Notes.getLatest = (userId) => {
	return new Promise((resolve, reject) => {
		db.promise()
		.query('SELECT id, SUBSTRING(text, 1, 100) as text FROM notes WHERE user = ? ORDER BY updated DESC, created DESC', [userId])
		.then((rows, fields) => {
			resolve(rows[0])
		})
		.catch(console.log)
	})
}

Notes.search = (userId, searchQuery, searchTags) => {
	return new Promise((resolve, reject) => {


		//Default note lookup gets all notes
		let noteSearchQuery = `
			SELECT notes.id, SUBSTRING(text, 1, 200) as text, updated 
			FROM notes 
			LEFT JOIN notes_tags ON (notes.id = notes_tags.note_id)
			WHERE user = ?`
		let searchParams = [userId]

		if(searchQuery != ''){
			//If a search query is defined, search notes for that word
			searchParams.push('%'+searchQuery+'%')
			noteSearchQuery += ' AND text LIKE ?'
		}
		if(searchTags.length > 0){
			//If tags are passed, use those tags in search
			searchParams.push(searchTags)
			noteSearchQuery += ' AND notes_tags.tag_id IN (?)'
		}

		//Finish up note query
		noteSearchQuery += ' GROUP BY notes.id ORDER BY updated DESC, created DESC, id DESC'

		//Define return data objects
		let returnData = {
			'notes':[],
			'tags':[]
		}

		db.promise()
		.query(noteSearchQuery, searchParams)
		.then((noteRows, noteFields) => {

			//Push all notes
			returnData['notes'] = noteRows[0]

			//pull out all note ids so we can fetch all tags for those notes
			let noteIds = []
			returnData['notes'].forEach(note => {

				//Grab note ID for finding tags
				noteIds.push(note.id)
				
				//Attempt to pull string out of first tag in note
				let reg = note.text.match(/<([\w]+)[^>]*>(.*?)<\/\1>/)
				if(reg != null){
					note.text = reg[2]
				}
				//Return all notes with HTML tags pulled out
				note.text = note.text
					.replace(/&[#A-Za-z0-9]+;/g,'') //Rip out all HTML entities
					.replace(/<[^>]+>/g, '') //Rip out all HTML tags
					
			})

			//If no notes are returned, there are no tags, return empty
			if(noteIds.length == 0){
				resolve(returnData)
			}

			//Only show tags of selected notes
			db.promise()
			.query(`SELECT tags.id, tags.text, count(tags.id) as usages FROM notes_tags
					JOIN tags ON (tags.id = notes_tags.tag_id)
					WHERE notes_tags.user_id = ?
					AND note_id IN (?)
					GROUP BY tags.id
					ORDER BY usages DESC;`,[userId, noteIds])
			.then((tagRows, tagFields) => {

				returnData['tags'] = tagRows[0]

				resolve(returnData)
			})
			.catch(console.log)

		})
		.catch(console.log)
	})
}