<template>
	<div>
		<n-space justify="space-around">
			<h1>Create Log</h1>
			<n-button
				type="primary" style="margin: 1em;"
				@click="getPDF"
				:disabled="!isValidId"
				:loading="isGeneratingPDF"
			>
				Save &amp; Generate
			</n-button>
		</n-space>

		<n-space justify="space-around">
			<n-input size="large" round placeholder="Photo Log title" v-model:value="title" @change="updateServerData" />
			<n-space vertical>
				<n-button size="small" @click="selectPhotoForStartSlide">Choose Cover Photo</n-button>
				<n-image
					width="100"
					:src="getPhotoSrcById(start_slide_image)"
				/>
			</n-space>
			<n-space vertical>
				<n-date-picker v-model:value="date" type="date" @update:value="updateServerData" />
				<n-checkbox v-model:checked="render_date">show date on first slide?</n-checkbox>
			</n-space>
			<n-button type="primary"
				:disabled="!unsaved_changes"
				:loading="currently_saving"
				@click="saveChanges"
				>
				<template #icon>
					<n-icon><SaveFilled /></n-icon>
				</template>
				{{saving_info}}
			</n-button>
		</n-space>

		<n-divider title-placement="center">Slides</n-divider>

		<n-space justify="center" style="min-width: 100vw;">
		<n-space vertical style="max-width: 80vw; width: 600px;">
			<n-card
				class="add-slide-between-button:hover"
				@click="addSlideAfter(-1)">
				<n-space justify="center">
					<n-button circle secondary type="info">
						<n-icon><LibraryAddRound /></n-icon>
					</n-button>
				</n-space>
			</n-card>

			<transition-group name="slide-cards">
			<draggable
				:list="slides"
				item-key="id"
				style="width: 100%;"
			>
				<template #item="{ element: slide, index }">

				
			<div>
				<n-card
					:title="'#'+(index+1)" class=".move-slide-handle">

					<template #header-extra>
						<n-space>
							<n-button round secondary type="success" @click="selectPhotosForSlide(index)">
								<template #icon>
									<n-icon><AddPhotoAlternateOutlined /></n-icon>
								</template>
								Select Photos
							</n-button>

							<n-popconfirm
								type="error"
								>
								<template #trigger>
								<n-button
									circle secondary
									type="error"
									>
									<n-icon><TrashBinSharp /></n-icon>
								</n-button>
								</template>
								Delete slide?
								<template #action>
									<n-button size="small" type="error" @click="removeSlide(index)"> Delete </n-button>
								</template>
							</n-popconfirm>
						</n-space>
					</template>

					<n-image-group>
						<draggable
							:list="slide"
							item-key="id"
							@start="drag = true"
							@end="drag = false"
						>
							<template #item="{element: photoid}">
								<n-image
									width="100"
									:src="getPhotoSrcById(photoid)"
								/>
							</template>
						</draggable>
					</n-image-group>					
				</n-card>

				<n-card
					class="add-slide-between-button"
					@click="addSlideAfter(index)">
					<n-space justify="center">
						<n-button circle secondary type="info">
							<n-icon><LibraryAddRound /></n-icon>
						</n-button>
					</n-space>
				</n-card>
				</div>
			</template>
			</draggable>
			</transition-group>
			
		</n-space>
		</n-space>

		<PhotoSelectModal
			v-model:showSelection="selectPhotosModal"
			@closed="selectPhotosModal=false"
			@selected="addPhotosToSlide"
			:max_select=max_photos_per_slide :or_less=true
			:already-selected=slides[selectedSlide] />
		
		<n-modal
			v-model:show="showPreventLeaveModal"
			:mask-closable="true"
			type="warning"
			preset="dialog"
			title="Unsaved Changes"
			content="Are you sure that you want to leave this page. All unsaved data might be lost!"
			transform-origin="center"
			positive-text="Stay on page"
			@negative-click="continueLeavePage"
			@positive-click="showPreventLeaveModal = false; leaving_to_page = null;"
			negative-text="Leave"
		/>

		<n-modal v-model:show="showCreateModal" :mask-closable=false>
			<n-spin :show="isCreateLoading">
				<n-card
					style="width: 600px;"
					title="Create a new Photo Log"
					:bordered="false"
					size="huge"
					role="dialog"
					aria-modal="true"
					>

					<n-form-item label="What's the name of the photo log?" path="title">
						<n-input v-model:value="title" type="text" placeholder="Photo Log title" />
					</n-form-item>
					<n-form-item label="When did the training take place?" path="date">
						<n-date-picker v-model:value="date" type="date" clearable />
					</n-form-item>

					<template #footer>
						<n-space justify="end">
							<n-button @click="navigateBack">Cancel</n-button>
							<n-button @click="createNewPhotoLog" type="success">Create</n-button>
						</n-space>
					</template>
				
				</n-card>
			</n-spin>
		</n-modal>
	</div>
</template>

<script>
import {ref} from 'vue'

import { useMeta } from 'vue-meta'
import { useMessage } from 'naive-ui'

import draggable from 'vuedraggable'

import TrashBinSharp from '@vicons/ionicons5/TrashBinSharp'
import LibraryAddRound from '@vicons/material/LibraryAddRound'
import AddPhotoAlternateOutlined from '@vicons/material/AddPhotoAlternateOutlined'
import SaveFilled from '@vicons/material/SaveFilled'

import PhotoSelectModal from '@/components/PhotoSelectModal'

import { getPhotoLogPDF } from '@/api'

export default {
	name: 'CreateLog',
	components: {
		draggable,
		PhotoSelectModal,
		TrashBinSharp,
		LibraryAddRound,
		AddPhotoAlternateOutlined,
		SaveFilled,
	},
	props: {
		e: {
			type: Number,
			required: false,
			default: -1,
		}
	},
	data() {
		return {
			id: Number.parseInt(this.e),
			title: '',
			date: null,
			start_slide_image: null,
			slides: [],

			selectPhotosModal: false,
			selectedSlide: null,
			max_photos_per_slide: 3,

			unsaved_changes: false,
			currently_saving: false,
			
			isLoadingData: false,
			isCreateLoading: false,
			isSavingServer: false,
			isGeneratingPDF: false,

			showPreventLeaveModal: false,
			leaving_to_page: null,

			drag: false,
		}
	},
	setup() {
		useMeta({ title: 'Create a new Photo Log' })
		const message = useMessage()
		return { message, render_date: ref(false) }
	},
	mounted() {
		if (this.isValidId()) {
			this.isLoadingData = true

			this.$store.dispatch('loadPhotoGroups').then(() => {
				this.photoGroups = this.$store.getters.photoGroups
				this.$store.dispatch('loadPhotosInAllGroups')
			})

			this.findPhotoLog().then(() => {
				this.updateLocalData()
			})
		}
	},
	watch: {
		title: function () { this.unsaved_changes = true },
		date: function () { this.unsaved_changes = true},
		render_date: function () { this.unsaved_changes = true},
		start_slide_image: function () { this.unsaved_changes = true},
		slides: {handler() { this.unsaved_changes = true}, deep: true},
	},
	computed: {
		saving_info() {
			if (!this.unsaved_changes)
				return 'No changes made'
			if (this.currently_saving)
				return 'Saving...'
			return 'Save Changes'
		},
		photos() {
			return this.$store.getters.photos
		},
		showCreateModal () {
			return !this.isValidId()
		},
		dateStr () {
			if (this.date !== null) {
				let date_obj = new Date(this.date)
				let month = Number.parseInt(date_obj.getMonth())+1
				month = month < 10 ? '0' + month : month
				let day = Number.parseInt(date_obj.getDate())
				day = day < 10 ? '0' + day : day
				let date_str = date_obj.getFullYear() + '-' + month + '-' + day
				return date_str
			}
			return '1970-01-01'
		}
	},
	methods: {
		saveChanges() {
			return new Promise((reject, resolve) => {
				this.currently_saving = true
				this.updateServerData().catch(() => {
					reject()
				}).finally(() => {
					this.currently_saving = false
					this.unsaved_changes = false
					resolve()
				})
			})
		},
		selectPhotosForSlide(slide_index) {
			this.selectedSlide = slide_index
			this.max_photos_per_slide = 3
			this.selectPhotosModal = true
		},
		selectPhotoForStartSlide() {
			this.selectedSlide = 'start_slide'
			this.max_photos_per_slide = 1
			this.selectPhotosModal = true
		},
		getPhotoSrcById(photo_id){
			for (const index in this.photos) {
				let group = this.photos[index]
				let photo = group.filter((photo) => photo.id == photo_id)
				if (photo.length > 0) {
					photo = photo[0]
					return photo.cropped_image !== null ? photo.cropped_image : photo.original_image
				}
			}
			return null
		},
		addPhotosToSlide(selected_photos) {
			if (this.selectedSlide === 'start_slide') {
				if (selected_photos.length > 0)
					this.start_slide_image = selected_photos[0]
				else
					this.start_slide_image = null
				this.max_photos_per_slide = 3
				return
			}
			this.slides[this.selectedSlide] = selected_photos
		},
		addSlideAfter(index) {
			this.slides.splice(index+1, 0, [])
		},
		removeSlide(index) {
			this.slides.splice(index, 1)
		},
		navigateBack() {
			this.$router.go(-1)
		},
		createNewPhotoLog() {
			if (this.title.length > 0 && this.date !== null) {
				this.isCreateLoading = true
				this.$store.dispatch('addNewPhotoLog', {title:this.title, date:this.dateStr}).then(id => {
					if (id > -1 && id !== null) {
						this.id = id
						this.$router.push({name: 'CreateLog', params: {e: id}})
					} else {
						this.message.error('Something went wrong. Please try again later.')
					}
				}).finally(() => {
					this.isCreateLoading = false
				})
			} else {
				if (this.title.length <= 0)
					this.message.error('Please enter a title')
				if (this.date === null)
					this.message.error('Please enter a date')
			}
		},
		isValidId() {
			return !(
				this.id == null
				|| Number.isNaN(this.id)
				|| this.id <= 0
				|| this.id === undefined
			)
		},
		findPhotoLog() {
			return new Promise((resolve, reject) => {
				let found_log = this.$store.getters.photoLogById(this.id)
				if (found_log === null) {
					this.$store.dispatch('loadPhotoLogList').then(() => {
						found_log = this.$store.getters.photoLogById(this.id)
						if (found_log === null) {
							this.message.error('Photo Log could not be found')
							reject()
						} else {
							resolve()
						}
					}).catch(() => {
						reject()
					})
				} else {
					resolve()
				}
			})
		},
		updateLocalData() {
			let found_log = null
			this.$store.dispatch('loadPhotoLog', this.id).then(() => {
				found_log = this.$store.getters.photoLogDetailsById(this.id)
				if (found_log !== null) {
					this.title = found_log.title
					this.date = new Date(found_log.date).getTime()
					this.render_date = found_log.render_date
					this.start_slide_image = found_log.start_slide_image
					this.slides = found_log.slides

					for(const idx in this.slides) {
						this.slides[idx] = this.slides[idx].filter((s)=>s!==null)
					}

					this.isLoadingData = false
					this.unsaved_changes = false
				} else {
					this.message.error('Photo Log could not be found')
				}
			})
		},
		getPDF() {
			this.saveChanges().then(() => {
				this.isGeneratingPDF = true
				getPhotoLogPDF(this.id).then((response) => {
					let url = response.data.pdf
					window.open(url, '_blank')
				}).catch((error) => {
					this.message.error('Cannot generate PDF file: ' + error)
				}).finally(() => {
					this.isGeneratingPDF = false
				})
			})
		},
		updateServerData() {
			return new Promise((reject, resolve) => {
				this.isSavingServer = true

				let server_slides = [...this.slides]
				for (const idx in server_slides) {
					server_slides[idx] = [
						...server_slides[idx],
						...new Array(
							this.max_photos_per_slide-server_slides[idx].length)
							.map(()=>null)]
				}

				this.$store.dispatch('updatePhotoLogDetails', {
					id: this.id,
					title: this.title,
					date: this.dateStr,
					render_date: this.render_date,
					start_slide_image: this.start_slide_image,
					slides: server_slides
				}).then(() => {
					this.message.success('Changes saved')
				}).catch((error) => {
					this.message.error('There was a problem saving the changes: '+error.message)
					reject()
				}).finally(() => {
					this.isSavingServer = false
					resolve()
				})
			})
		},
		continueLeavePage() {
			console.log(this.leaving_to_page)
			this.$router.push(this.leaving_to_page)
		},
	},
	beforeRouteUpdate (to) {
		this.id = Number.parseInt(to.params.e)
		if (this.isValidId()) {
			this.isLoadingData = true
			this.findPhotoLog().then(()=> {
				this.updateLocalData()
			})
		}
	},
	// eslint-disable-next-line no-unused-vars
	beforeRouteLeave (to, from) {
		if (this.unsaved_changes && this.leaving_to_page === null) {
			this.showPreventLeaveModal = true
			this.leaving_to_page = to
			return false
		}
	}
}
</script>

<style scoped>
.n-input {
	min-width: 25em;
}

.n-card .n-image {
	margin-right: 2em;
}

.add-slide-between-button, .add-slide-between-button * {
	margin: 0;
	padding: 0;
}

.add-slide-between-button {
	cursor: pointer;
	height: 1.5em;
	background-color: #addeff;
	overflow: hidden;
	opacity: 30%;
	transition: all 0.25s;
}

.add-slide-between-button:hover {
	height: 5em;
	opacity: 90%;
	cursor: pointer;
	background-color: #addeff;
}

.slide-cards-enter-active,
.slide-cards-leave-active {
	transition: all 0.25s ease;
}

.slide-cards-enter-from,
.slide-cards-leave-to {
	opacity: 0;
	transform: translateY(30px);
}

.slide-cards-move {
	transition: transform 0.25s ease;
}
</style>