<template>
	<AppContent :class="{ loading: loading || isManualSave, 'icon-error': !loading && (!note || note.error), 'sidebar-open': sidebarOpen }">
		<div v-if="!loading && note && !note.error && !note.deleting"
			id="note-container"
			class="note-container"
			:class="{ fullscreen: fullscreen }"
		>
			<div class="note-editor">
				<div v-show="!note.content" class="placeholder">
					{{ preview ? t('notes', 'Empty note') : t('notes', 'Write …') }}
				</div>
				<ThePreview v-if="preview" :value="note.content" />
				<TheEditor v-else :value="note.content" @input="onEdit" />
			</div>
			<span class="action-buttons">
				<Actions :open.sync="actionsOpen" menu-align="right">
					<ActionButton v-show="!sidebarOpen && !fullscreen"
						icon="icon-details"
						@click="onToggleSidebar"
					>
						{{ t('notes', 'Details') }}
					</ActionButton>
					<ActionButton v-if="!preview"
						icon="icon-toggle"
						@click="onTogglePreview"
					>
						{{ t('notes', 'Preview') }}
					</ActionButton>
					<ActionButton v-else
						icon="icon-rename"
						@click="onTogglePreview"
					>
						{{ t('notes', 'Edit') }}
					</ActionButton>
					<ActionButton
						icon="icon-fullscreen"
						:class="{ active: fullscreen }"
						@click="onToggleDistractionFree"
					>
						{{ fullscreen ? t('notes', 'Exit full screen') : t('notes', 'Full screen') }}
					</ActionButton>
				</Actions>
				<button v-show="note.saveError"
					v-tooltip.right="t('notes', 'Save failed. Click to retry.')"
					class="action-error icon-error-color"
					@click="onManualSave"
				/>
			</span>
		</div>
	</AppContent>
</template>
<script>

import {
	Actions,
	ActionButton,
	AppContent,
	Tooltip,
} from '@nextcloud/vue'

import { fetchNote, saveNote, saveNoteManually } from '../NotesService'
import { closeNavbar } from '../nextcloud'
import TheEditor from './EditorEasyMDE'
import ThePreview from './EditorMarkdownIt'
import store from '../store'

export default {
	name: 'Note',

	components: {
		Actions,
		ActionButton,
		AppContent,
		TheEditor,
		ThePreview,
	},

	directives: {
		tooltip: Tooltip,
	},

	props: {
		noteId: {
			type: String,
			required: true,
		},
	},

	data: function() {
		return {
			loading: false,
			fullscreen: false,
			preview: false,
			actionsOpen: false,
		}
	},

	computed: {
		note() {
			return store.getters.getNote(parseInt(this.noteId))
		},
		title() {
			return this.note ? this.note.title : ''
		},
		isManualSave() {
			return store.state.isManualSave
		},
		sidebarOpen() {
			return store.state.sidebarOpen
		},
	},

	watch: {
		// call again the method if the route changes
		'$route': 'fetchData',
		title: 'onUpdateTitle',
	},

	created() {
		this.fetchData()
		// TODO move the following from jQuery to plain JS
		$(document).bind('webkitfullscreenchange mozfullscreenchange fullscreenchange', this.onDetectFullscreen)
		$(document).bind('keypress.notes.save', this.onKeyPress)
	},

	destroyed() {
		$(document).unbind('keypress.notes.save')
		store.commit('setSidebarOpen', false)
		this.onUpdateTitle(null)
	},

	methods: {
		fetchData() {
			store.commit('setSidebarOpen', false)

			closeNavbar()

			this.onUpdateTitle(this.title)
			this.loading = true
			this.preview = false
			fetchNote(this.noteId)
				.then((note) => {
					if (note.errorMessage) {
						OC.Notification.showTemporary(note.errorMessage)
					}
				})
				.catch(() => {
					// note not found
				})
				.then(() => {
					this.loading = false
				})
		},

		onUpdateTitle(title) {
			const defaultTitle = store.state.documentTitle
			if (title) {
				document.title = title + ' - ' + defaultTitle
			} else {
				document.title = defaultTitle
			}
		},

		onTogglePreview() {
			this.preview = !this.preview
			this.actionsOpen = false
		},

		onDetectFullscreen() {
			this.fullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen
		},

		onToggleDistractionFree() {
			function launchIntoFullscreen(element) {
				if (element.requestFullscreen) {
					element.requestFullscreen()
				} else if (element.mozRequestFullScreen) {
					element.mozRequestFullScreen()
				} else if (element.webkitRequestFullscreen) {
					element.webkitRequestFullscreen()
				} else if (element.msRequestFullscreen) {
					element.msRequestFullscreen()
				}
			}

			function exitFullscreen() {
				if (document.exitFullscreen) {
					document.exitFullscreen()
				} else if (document.mozCancelFullScreen) {
					document.mozCancelFullScreen()
				} else if (document.webkitExitFullscreen) {
					document.webkitExitFullscreen()
				}
			}

			if (this.fullscreen) {
				exitFullscreen()
			} else {
				launchIntoFullscreen(document.getElementById('note-container'))
			}
			this.actionsOpen = false
		},

		onToggleSidebar() {
			store.commit('setSidebarOpen', !store.state.sidebarOpen)
			this.actionsOpen = false
		},

		onEdit(newContent) {
			if (this.note.content !== newContent) {
				const note = {
					...this.note,
					content: newContent,
					unsaved: true,
				}
				store.commit('add', note)
				setTimeout(saveNote.bind(this, note.id), 1000)
			}
		},

		onKeyPress(event) {
			if (event.ctrlKey || event.metaKey) {
				switch (String.fromCharCode(event.which).toLowerCase()) {
				case 's':
					event.preventDefault()
					this.onManualSave()
					break
				}
			}
		},

		onManualSave() {
			saveNoteManually(this.note.id)
		},
	},
}
</script>
<style scoped>
.note-container {
	min-height: 100%;
	width: 100%;
	background-color: var(--color-main-background);
}

.note-editor {
	max-width: 47em;
	font-size: 16px;
	padding: 1em;
}

/* center editor on large screens */
@media (min-width: 1600px) {
	.note-editor {
		margin: 0 auto;
	}
	.note-container {
		padding-right: 250px;
		transition-duration: var(--animation-quick);
		transition-property: padding-right;
	}
	.sidebar-open .note-container {
		padding-right: 0px;
	}
}

/* distraction free styles */
.note-container.fullscreen {
	width: 100vw;
	height: 100vh;
	overflow-y: auto;
	padding: 0;
}

.note-container.fullscreen .note-editor {
	margin: 0 auto;
}

/* placeholder */
.placeholder {
	position: absolute;
	padding: 1em;
	opacity: 0.5;
}

/* main editor button */
.action-buttons {
	position: fixed;
	top: 50px;
	right: 20px;
	width: 44px;
	margin-top: 1em;
	z-index: 2000;
}

.action-buttons .action-error {
	width: 44px;
	height: 44px;
}

.note-container.fullscreen .action-buttons {
	top: 0px;
}

.action-buttons button {
	padding: 15px;
}
</style>
