<script>
import { markRaw } from 'vue';
import Uppy from '@uppy/core';
import XHRUpload from '@uppy/xhr-upload';
import '@uppy/core/css/style.min.css';

import SpotIcon from '@components/spotIcon';
import SpotButton from '@components/spotButton';

export default {
	name: 'upload',
	components: { SpotButton, SpotIcon },
	inject: ['api', 'lang', 'projects', 'consts', 'user', 'getPrevAnchor'],
	data() {
		return {
			project: this.projects.getDefaultProject(),
			files: [],
			logs: [],
			progress: 0,
			uppy: null
		};
	},
	mounted() {
		if(!this.project.editable) {
			this.logs = [this.lang.get('upload.mode_archived', [this.project.name])];
			return;
		}

		this.initUploader();
	},
	beforeUnmount() {
		if(this.uppy) {
			this.uppy.destroy();
			this.uppy = null;
		}
	},
	methods: {
		initUploader() {
			const endpoint = `${this.consts.process_page}?a=upload`;

			this.uppy = markRaw(new Uppy({
				autoProceed: true,
				restrictions: {
					allowedFileTypes: ['.gif', '.jpg', '.jpeg', '.png', '.mov', '.mp4']
				}
			}));

			this.uppy.setMeta({t: this.user.timezone});

			this.uppy.use(XHRUpload, {
				endpoint,
				fieldName: 'files[]',
				formData: true,
				headers: {'X-CSRF-Token': this.consts.csrf_token},
				allowedMetaFields: ['t', 'name', 'type'],
				getResponseData(xhr) {
					return JSON.parse(xhr.responseText || '{}');
				}
			});

			this.uppy.on('progress', (progress) => {
				this.progress = progress;
			});

			this.uppy.on('upload-success', (file, response) => {
				const uploadedFiles = response?.body?.files || [];
				uploadedFiles.forEach((uploadedFile) => {
					const hasError = Object.prototype.hasOwnProperty.call(uploadedFile, 'error');
					this.logs.push(hasError ? uploadedFile.error : this.lang.get('upload.success', [uploadedFile.original_name || uploadedFile.name]));
					if(!hasError) this.files.push({...uploadedFile, content: ''});
				});
			});

			this.uppy.on('upload-error', (file, error, response) => {
				const message = response?.body?.error || error?.message || this.lang.get('upload.error');
				this.logs.push(message);
			});

			this.uppy.on('complete', () => {
				this.progress = 0;
			});
		},
		onFileChange(event) {
			const files = Array.from(event.target.files || []);
			if(files.length > 0 && this.uppy) this.uppy.addFiles(files.map((file) => ({source: 'local', name: file.name, type: file.type, data: file})));
			event.target.value = '';
		},
		addComment(oFile) {
			this.api.post('add_comment', {
					id: oFile.id,
					content: oFile.content
				})
				.then((asData) => {this.logs.push(this.lang.get('media.comment_update', asData.filename));})
				.catch((sMsgId) => {this.logs.push(this.lang.get(sMsgId));});
		},
		addPosition() {
			if(navigator.geolocation) {
				this.logs.push('Determining position...');
				navigator.geolocation.getCurrentPosition(
					(position) => {
						this.logs.push('Sending position...');
						this.api.post('add_position', {
								'latitude': position.coords.latitude,
								'longitude': position.coords.longitude,
								'timestamp': Math.round(position.timestamp / 1000)
							})
							.then((asData) => {this.logs.push(this.lang.get('upload.success', [this.lang.get('upload.position.new')]));})
							.catch((sMsgId) => {this.logs.push(this.lang.get(sMsgId));});
					},
					(error) => {
						this.logs.push(error.message);
					}
				);
			} 
			else this.logs.push('This browser does not support geolocation');
		}
	}
}
</script>
<template>
	<div id="upload">
		<div class="section header">
			<a name="back" class="button" :href="getPrevAnchor()"><SpotIcon :icon="'back'" :text="lang.get('action.back')" /></a>
			<h1>{{ this.project.name }}</h1>
		</div>
		<div class="section" v-if="project.editable">
			<h2>{{ lang.get('upload.media.title') }}</h2>
			<input id="fileupload" type="file" name="files[]" multiple accept=".gif,.jpg,.jpeg,.png,.mov,.mp4" @change="onFileChange" />
		</div>
		<div class="section progress" v-if="progress > 0">
			<div class="total"></div>
			<div class="bar" :style="{width:progress+'%'}"></div>
		</div>
		<div class="section comment" v-for="file in files" :key="file.id">
			<img class="thumb" :src="file.thumbnail" />
			<div class="form">
				<input class="content" name="content" type="text" v-model="file.content" />
				<input class="id" name="id" type="hidden" :value="file.id" />
				<SpotButton :classes="'save'" :icon="'save'" :text="lang.get('action.save')" @click="addComment(file)" />
			</div>
		</div>
		<div class="section location" v-if="project.editable">
			<h2>{{ lang.get('upload.position.title') }}</h2>
			<SpotButton :icon="'marker'" :text="lang.get('upload.position.new')" @click="addPosition()" />
		</div>
		<div class="section logs" v-if="logs.length > 0">
			<p class="log" v-for="log in logs">{{ log }}.</p>
		</div>
	</div>
</template>
