<template>
	<div id="attachments">
		<input ref="localAttachments"
			class="attachments-input"
			type="file"
			multiple
			@change="onLocalAttachmentSelected">
		<div class="attachments-summary">
			<div class="attachments-summary-inner">
				<Paperclip :size="20" />
				<div v-if="attachments.length > 0" class="attachments-summary-inner-label">
					{{ n('calendar', '{count} attachment', '{count} attachments', attachments.length, { count: attachments.length }) }}
				</div>
				<div v-else class="attachments-summary-inner-label">
					{{ t('calendar', 'No attachments') }}
				</div>
			</div>

			<NcActions v-if="!isReadOnly">
				<template #icon>
					<Plus :size="20" />
				</template>
				<NcActionButton @click="openFilesModal()">
					<template #icon>
						<Folder :size="20" />
					</template>
					{{ t('calendar', 'Add from Files') }}
				</NcActionButton>
				<NcActionButton @click="clickOnUploadButton">
					<template #icon>
						<Upload :size="20" />
					</template>
					{{ t('calendar', 'Upload from device') }}
				</NcActionButton>
				<NcActionButton @click="openEmailBoxModal">
					<template #icon>
						<Email :size="20" />
					</template>
					{{ t('calendar', 'Depuis un email') }}
				</NcActionButton>
			</NcActions>
		</div>
		<div v-if="attachments.length > 0">
			<ul class="attachments-list">
				<NcListItem v-for="attachment in attachments"
					:key="attachment.path"
					class="attachments-list-item"
					:force-display-actions="true"
					:name="getBaseName(attachment.fileName)"
					@click="openFile(attachment.uri)">
					<template #icon>
						<img :src="getPreview(attachment)" class="attachment-icon">
					</template>
					<template #actions>
						<NcActionButton v-if="!isReadOnly"
							@click="deleteAttachmentFromEvent(attachment)">
							<template #icon>
								<Close :size="20" />
							</template>
							{{ t('calendar', 'Delete file') }}
						</NcActionButton>
					</template>
				</NcListItem>
			</ul>
		</div>

		<NcDialog :open.sync="showOpenConfirmation" 
			:name="t('calendar', 'Confirmation')"
			:buttons="openConfirmationButtons">
			<p class="external-link-message">
				{{ openConfirmationMessage }}
			</p>
		</NcDialog>
		<NcModal v-if="showModal" name="" size='large' @close="resetMailBoxModal">

			<div class="modal__content" v-if="!showAttachmentsSection && !showAttachmentsSection">
				<NcButton style="text-align: center;" @click="syncEmailBox()" v-if="!loadingDataEmailBox">
					<template #icon>
						<Reload :size="20" />
					</template>
					Actualiser 
				</NcButton>
				<template v-if="mailBoxData.length > 0" v-for="mail in mailBoxData">
					<ul>
						<NcListItem 
							@click="getAttachments(mail)"
							:name="getLabelEmailBox(mail.from) + ' : ' + mail.subject" 
							:bold="false"
							counterType="outlined">
							<template #subname>
									{{ getSubstringText(mail.previewText ,50) }} 
							</template>
							<template v-if="hasAttachements(mail)" #icon>
								<Paperclip :size="20"   />
							</template>
						</NcListItem>
					</ul>
				</template>
			</div>
			<div class="modal__content__attachments" v-if="showAttachmentsSection">
				<ul class="attachments-list">
					<NcActionButton @click="displayAttachmentsSection()">
						<template #icon>
							<ArrowLeft :size="20" />
						</template>
						Revenir dans la listes des emails
					</NcActionButton>
						<div v-if="selectedMail" >
							<div class="mailHeader">
								{{ getLabelEmailBox(selectedMail.from) + ' : ' + selectedMail.subject  }}
							</div>
							<div class="mailContent">
								{{ selectedMail.previewText }}
							</div>
						</div>

						<div class="mailHeader">
							Pièces jointes : 
						</div>
						<div class="image-list-attachement " v-if="!loadingDataEmailBox  && mailAttachmentData.length > 0" v-for="attachment in mailAttachmentData">  
							<div v-if="attachment.isImage" class="image-item-attachement " @click="selectAttachement(attachment.id)">  
								<img :src="attachment.downloadUrl" :alt="attachment.fileName ">  
								<label>{{ attachment.fileName }} 	<span v-if="isInSelectedAttachment(attachment.id)"> ✔</span>  </label> 
							</div>  
							<div v-else-if="! attachment.isImage &&  !attachment.isCalendarEvent" class="image-item-attachement " @click="selectAttachement(attachment.id)">  
								<label>{{ attachment.fileName }}
									<span v-if="isInSelectedAttachment(attachment.id)"> ✔</span> 
								</label>  
							</div>  
							<div v-else-if="attachment.isCalendarEvent" class="image-item-attachement " >  
								<label>{{  attachment.fileName }} ( Non allouée)</label>  
							</div>  
						</div>
					<template v-if="!mailAttachmentData.length && !loadingDataEmailBox" >
						<p> Pas d'attachements</p>
					</template>
					
				</ul>
				

			</div>
			<div class="modal__content" v-if="selectedAttachements.length && !loadingDataEmailBox" >
				<NcButton style="text-align: center;" @click="pickEmailAttachement()" >
					 Ajouter ({{ selectedAttachements.length }}) 
				</NcButton>
			</div>
			<div class="modal__content" v-if="loadingDataEmailBox" >
				<div >
					<NcLoadingIcon :size="40" appearance="light" :name="loadingText" />
				</div>
				<p style="text-align: center;"> {{ loadingText }}</p>
			</div>
		</NcModal>
	</div>
</template>

<script>
import {
	NcListItem,
	NcActions,
	NcActionButton,
	NcDialog,
	NcModal,
	NcButton,
	NcAvatar,
	NcLoadingIcon,
	NcCheckboxRadioSwitch
} from '@nextcloud/vue'

import axios from "@nextcloud/axios";

import Upload from 'vue-material-design-icons/Upload.vue'
import Close from 'vue-material-design-icons/Close.vue'
import Folder from 'vue-material-design-icons/Folder.vue'
import Paperclip from 'vue-material-design-icons/Paperclip.vue'
import Plus from 'vue-material-design-icons/Plus.vue'
import Email from 'vue-material-design-icons/Email.vue'
import ArrowLeft from 'vue-material-design-icons/ArrowLeft.vue'
import Reload from 'vue-material-design-icons/Reload.vue'

import { generateUrl, getBaseUrl } from '@nextcloud/router'
import { getFilePickerBuilder, showError } from '@nextcloud/dialogs'
import logger from '../../../utils/logger.js'
import {
	uploadLocalAttachment,
	getFileInfo,
	uploadRemoteFile
} from '../../../services/attachmentService.js'
import { parseXML } from 'webdav'
import { size } from 'lodash';

export default {
	name: 'AttachmentsList',
	components: {
		NcListItem,
		NcActions,
		NcActionButton,
		Upload,
		Close,
		Folder,
		Paperclip,
		Plus,
		NcDialog,
		NcModal,
		NcButton,
		Email,
		ArrowLeft,
		Reload,
		NcAvatar,
		NcLoadingIcon,
		NcCheckboxRadioSwitch
	},
	props: {
		calendarObjectInstance: {
			type: Object,
			required: true,
		},
		isReadOnly: {
			type: Boolean,
			default: true,
		},
	},
	data() {
		return {
			uploading: false,
			showOpenConfirmation: false,
			openConfirmationMessage: '',
			openConfirmationButtons: [],
			showModal: false,
			showAttachmentsSection: false,
			loadingDataEmailBox: false,
			mailBoxData: [],
			mailAttachmentData: [],
			selectedAttachements: [],
			loadingText: 'Chargement ...',
			selectedMail: null
		}
	},
	computed: {
		currentUser() {
			return this.$store.getters.getCurrentUserPrincipal
		},
		attachments() {
			return this.calendarObjectInstance.attachments
		},
	},
	methods: {
		addAttachmentWithProperty(calendarObjectInstance, sharedData) {
			this.$store.commit('addAttachmentWithProperty', {
				calendarObjectInstance,
				sharedData,
			})
		},
		deleteAttachmentFromEvent(attachment) {
			this.$store.commit('deleteAttachment', {
				calendarObjectInstance: this.calendarObjectInstance,
				attachment,
			})
		},
		async openFilesModal() {
			const picker = getFilePickerBuilder(t('calendar', 'Choose a file to add as attachment'))
				.setMultiSelect(false)
				.allowDirectories(true)
				.addButton({
					label: t('calendar', 'Pick'),
					type: 'primary',
					callback: (nodes) => logger.debug('Picked attachment', { nodes }),
				})
				.build()
			try {
				const filename = await picker.pick(t('calendar', 'Choose a file to share as a link'))
				if (!this.isDuplicateAttachment(filename)) {
					// TODO do not share Move this to PHP
					const data = await getFileInfo(filename, this.currentUser.dav.userId)
					const davRes = await parseXML(data)
					const davRespObj = davRes?.multistatus?.response[0]?.propstat?.prop
					davRespObj.fileName = filename
					davRespObj.url = generateUrl(`/f/${davRespObj.fileid}`)
					davRespObj.value = davRespObj.url
					this.addAttachmentWithProperty(this.calendarObjectInstance, davRespObj)
				}

			} catch (error) {

			}
		},
		isDuplicateAttachment(path) {
			return this.attachments.find(attachment => {
				if (attachment.fileName === path) {
					showError(t('calendar', 'Attachment {name} already exist!', { name: this.getBaseName(path) }))
					return true
				}
				return false
			})
		},
		clickOnUploadButton() {
			this.$refs.localAttachments.click()
		},
		async onLocalAttachmentSelected(e) {
			try {
				const attachmentsFolder = await this.$store.dispatch('createAttachmentsFolder')
				const attachments = await uploadLocalAttachment(attachmentsFolder, Array.from(e.target.files), this.currentUser.dav, this.attachments)
				// TODO do not share file, move to PHP
				attachments.map(async attachment => {
					const data = await getFileInfo(`${attachmentsFolder}/${attachment.path}`, this.currentUser.dav.userId)
					const davRes = await parseXML(data)
					const davRespObj = davRes?.multistatus?.response[0]?.propstat?.prop
					davRespObj.fileName = attachment.path
					davRespObj.url = generateUrl(`/f/${davRespObj.fileid}`)
					davRespObj.value = davRespObj.url
					this.addAttachmentWithProperty(this.calendarObjectInstance, davRespObj)
				})

				e.target.value = ''
			} catch (error) {
				logger.error('Could not upload attachment(s)', { error })
				showError(t('calendar', 'Could not upload attachment(s)'))
			}
		},
		getIcon(mime) {
			return OC.MimeType.getIconUrl(mime)
		},
		getPreview(attachment) {
			if (attachment.xNcHasPreview) {
				return generateUrl(`/core/preview?fileId=${attachment.xNcFileId}&x=100&y=100&a=0`)
			}
			return attachment.formatType
				? OC.MimeType.getIconUrl(attachment.formatType)
				: OC.MimeType.getIconUrl('folder')
		},
		getBaseName(name) {
			return name.split('/').pop()
		},
		openFile(rawUrl) {
			let url
			try {
				url = new URL(rawUrl, getBaseUrl())
			} catch (error) {
				logger.error(`Refusing to open invalid URL: ${rawUrl}`, { error })
				return
			}

			const baseUrl = new URL(getBaseUrl())
			if (url.href.startsWith(baseUrl.href)) {
				// URL belongs to this instance and is safe
				window.open(url.href, '_blank', 'noopener noreferrer')
				return
			}

			// Otherwise, show a confirmation dialog
			this.openConfirmationMessage = t('calendar', 'You are about to navigate to {host}. Are you sure to proceed? Link: {link}', {
				host: url.host,
				link: url.href,
			})
			this.openConfirmationButtons = [
				{
					label: t('calendar', 'Cancel'),
					callback: () => {
						this.showOpenConfirmation = false
					},
				},
				{
					label: t('calendar', 'Proceed'),
					type: 'primary',
					callback: () => {
						window.open(url.href, '_blank', 'noopener noreferrer')
					}
				},
			]
			this.showOpenConfirmation = true
		},
		async syncEmailBox(){
			this.loadingText = 'Synchronisation encours ...'	
			this.loadingDataEmailBox = true
			this.mailBoxData = [];
			await this.loadEmailsBox(true)
			this.loadingDataEmailBox = false
		},
		async openEmailBoxModal(){
			this.loadingText = 'Chargement des emails ...'	
			this.showModal = true
			this.loadingDataEmailBox = true
			await this.loadEmailsBox()
			this.loadingDataEmailBox = false
		},
		async getAttachments(mail){
			this.loadingText = 'Récupération des piecs jointes ...'	
			this.selectedMail = mail
			this.loadingDataEmailBox = true
			this.showAttachmentsSection = true
			this.mailAttachmentData  = [] ;
			await this.loadAttachments(mail)
			this.loadingDataEmailBox = false
		},
		selectAttachement(attachementId){
			if(this.isInSelectedAttachment(attachementId)){
				console.log("remove")
				this.selectedAttachements = this.selectedAttachements.filter(id => id !== attachementId)
			}else{
				console.log("add")
				this.selectedAttachements.push(attachementId)
			}
			
		},
		isInSelectedAttachment(attachementId){
			return this.selectedAttachements.find(id => id === attachementId)
		},
		async pickEmailAttachement(){
			this.loadingText = 'Ajout de l\'attachement encours ...'	
			this.loadingDataEmailBox = true
			//upload only attachmen if id is in selectedAttachements
			const selectedAttachements = this.selectedAttachements.map(id => this.mailAttachmentData.find(attachement => attachement.id === id))
			await this.uploadAttachment(selectedAttachements)

			this.closeMailBoxModal()
			this.resetMailBoxModal()
		},
		async uploadAttachment(attachements = []){
			await Promise.all(attachements.map(async attachement => {
				await this.uploadEmailAttachementTodavFile(attachement)
			}))
		},
		 resetMailBoxModal() {
			this.mailBoxData = []
			this.mailAttachmentData = []
			this.showModal = false
			this.showAttachmentsSection = false
			this.loadingDataEmailBox = false
			this.loadingText = 'Chargement ...'
			this.selectedAttachements = []
		},
		displayAttachmentsSection() {
			this.showAttachmentsSection = false
			this.loadingDataEmailBox = false
		},
		 closeMailBoxModal() {
			this.showModal = false
			this.showAttachmentsSection = false
			this.loadingDataEmailBox = false
			this.loadingText = 'Chargement ...'
		},
		async loadEmailsBox(withSync = false) {
			const ajaxUrl = generateUrl('/apps/calendar/load-email-box')
			await axios.get(ajaxUrl , { params: { withSync } })
				.then(response => {
					console.log(response.data.success);
					if (!response.data.success && response.data.message == "MAILBOX_NOT_FOUND") {
						this.closeMailBoxModal();
						showError(t('calendar', 'Veuillez configurer le compte apps email pour pouvoir utiliser cette fonctionnalité.' , {
							timeout : 7000,
						}))
						return;
					}
					this.mailBoxData = response.data;

				})
				.catch(error => {
					console.log(error)
				})
		},
		async loadAttachments(mail) {
			// if (!this.hasAttachements(mail)) {
			// 	this.mailAttachmentData  = [] ;
			// 	this.loadingDataEmailBox = false
			// 	return;
			// }
			const ajaxUrl = generateUrl('/apps/calendar/load-email-attachement/' + mail.databaseId)
		
			await axios.get(ajaxUrl)
				.then(response => {
					
					// response.data.attachments.forEach(attachement => {
					// 	this.mailAttachmentData.push({
					// 		id : attachement.id,
					// 		fileName : attachement.fileName,
					// 		downloadUrl : attachement.downloadUrl,
					// 		id : attachement.id,
					// 		isImage : attachement.isImage,
					// 		isCalendarEvent : attachement.isCalendarEvent,
					// 		size : attachement.size,
					// 	})
					// })
					this.mailAttachmentData  = response.data.attachments
				})
				.catch(error => {
					console.log(error)
				})
		},
		async uploadEmailAttachementTodavFile(attachement) {
			const attachmentsFolder = await this.$store.dispatch('createAttachmentsFolder')
			const attachment = await uploadRemoteFile(attachmentsFolder, attachement.downloadUrl, attachement.fileName ,this.currentUser.dav)
			// TODO do not share file, move to PHP
			const data = await getFileInfo(`${attachmentsFolder}/${attachment.path}`, this.currentUser.dav.userId)
			const davRes = await parseXML(data)
			const davRespObj = davRes?.multistatus?.response[0]?.propstat?.prop
			davRespObj.fileName = attachment.path
			davRespObj.url = generateUrl(`/f/${davRespObj.fileid}`)
			davRespObj.value = davRespObj.url
			this.addAttachmentWithProperty(this.calendarObjectInstance, davRespObj)
		},
		getLabelEmailBox(from = []) {
			if (from.length) {
				return from[0].label ?? from[0].email
			}
			return ''
		},
		getSubstringText(text = '' , length = 20) {
			if (text.length < length) {
				return text;
			}
			return text.substring(0, length) + '...'
		},
		hasAttachements(mail) {
			return mail.flags.hasAttachments;
		}
	},
}
</script>

<style lang="scss" scoped>
.attachments-input {
	display: none;
}
.attachments-summary {
	display:flex;
	align-items: center;
	justify-content: space-between;
	padding-left: 6px;

	.attachments-summary-inner {
		display:flex;
		align-items: center;

		span {
			width: 34px;
			height: 34px;
			margin-left: -10px;
			margin-right: 5px;
		}

		.attachments-summary-inner-label {
			padding: 0 7px;
			font-weight: bold;
		}
	}
}

.attachments-list {
	margin: 0 -8px;

	.attachments-list-item {
		// Reduce height to 44px
		:deep(.list-item) {
			padding: 0 8px;
		}
		:deep(.list-item-content__wrapper) {
			height: 44px;
		}

		:deep(.list-item-content) {
			// Align text with other properties
			padding-left: 18px;
		}

		:deep(.line-one__title) {
			font-weight: unset;
		}
	}
}

#attachments .empty-content {
	margin-top: 1rem;
	text-align: center;
}
.button-group {
	display: flex;
	align-content: center;
	justify-content: center;

	button:first-child {
		margin-right: 6px;
	}
}
.attachment-icon {
	width: 24px;
	height: 24px;
	border-radius: var(--border-radius);
}

.external-link-message {
	overflow-wrap: break-word;
}
.modal__content {
	margin: 10px;
}
.modal__content__attachments {
	margin: 10px;
	 text-align: center;
}
.attachments-list{
	margin-top: 20px;
}

.image-list-attachement {  
    display: flex;  
    flex-direction: column;  
    align-items: flex-start;  
	padding: 10px;
}  

.image-item-attachement {  
    display: flex;  
    align-items: center;  
    margin: 10px 0;  
}  

.image-item-attachement img {  
    width: 100px; /* Largeur de l'image */  
    height: auto; /* Hauteur automatique pour garder le ratio */  
    margin-right: 10px; /* Espace entre l'image et la légende */  
}  

label {  
    font-size: 16px; /* Taille de police pour la légende */  
}

.mailHeader{
	text-align: left;
	display: flex;  
    flex-direction: column;  
    align-items: flex-start;  
	padding: 10px;
	font-weight: bold;
}

.mailContent{
	text-align: left;
	display: flex;  
	flex-direction: column;  
	align-items: flex-start;  
	padding: 10px;
}

</style>
