<template>
<div class="mk-messaging-form"
	@dragover.stop="onDragover"
	@drop.stop="onDrop"
>
	<textarea
		v-model="text"
		ref="textarea"
		@keypress="onKeypress"
		@paste="onPaste"
		placeholder="%i18n:@input-message-here%"
		v-autocomplete="'text'"
	></textarea>
	<div class="file" @click="file = null" v-if="file">{{ file.name }}</div>
	<mk-uploader ref="uploader" @uploaded="onUploaded"/>
	<button class="send" @click="send" :disabled="!canSend || sending" title="%i18n:@send%">
		<template v-if="!sending">%fa:paper-plane%</template><template v-if="sending">%fa:spinner .spin%</template>
	</button>
	<button class="attach-from-local" @click="chooseFile" title="%i18n:@attach-from-local%">
		%fa:upload%
	</button>
	<button class="attach-from-drive" @click="chooseFileFromDrive" title="%i18n:@attach-from-drive%">
		%fa:R folder-open%
	</button>
	<input ref="file" type="file" @change="onChangeFile"/>
</div>
</template>

<script lang="ts">
import Vue from 'vue';
import * as autosize from 'autosize';

export default Vue.extend({
	props: ['user'],
	data() {
		return {
			text: null,
			file: null,
			sending: false
		};
	},
	computed: {
		draftId(): string {
			return this.user.id;
		},
		canSend(): boolean {
			return (this.text != null && this.text != '') || this.file != null;
		},
		room(): any {
			return this.$parent;
		}
	},
	watch: {
		text() {
			this.saveDraft();
		},
		file() {
			this.saveDraft();

			if (this.room.isBottom()) {
				this.room.scrollToBottom();
			}
		}
	},
	mounted() {
		autosize(this.$refs.textarea);

		// 書きかけの投稿を復元
		const draft = JSON.parse(localStorage.getItem('message_drafts') || '{}')[this.draftId];
		if (draft) {
			this.text = draft.data.text;
			this.file = draft.data.file;
		}
	},
	methods: {
		onPaste(e) {
			const data = e.clipboardData;
			const items = data.items;

			if (items.length == 1) {
				if (items[0].kind == 'file') {
					this.upload(items[0].getAsFile());
				}
			} else {
				if (items[0].kind == 'file') {
					alert('メッセージに添付できるのはひとつのファイルのみです');
				}
			}
		},

		onDragover(e) {
			const isFile = e.dataTransfer.items[0].kind == 'file';
			const isDriveFile = e.dataTransfer.types[0] == 'mk_drive_file';
			if (isFile || isDriveFile) {
				e.preventDefault();
				e.dataTransfer.dropEffect = e.dataTransfer.effectAllowed == 'all' ? 'copy' : 'move';
			}
		},

		onDrop(e): void {
			// ファイルだったら
			if (e.dataTransfer.files.length == 1) {
				e.preventDefault();
				this.upload(e.dataTransfer.files[0]);
				return;
			} else if (e.dataTransfer.files.length > 1) {
				e.preventDefault();
				alert('メッセージに添付できるのはひとつのファイルのみです');
				return;
			}

			//#region ドライブのファイル
			const driveFile = e.dataTransfer.getData('mk_drive_file');
			if (driveFile != null && driveFile != '') {
				this.file = JSON.parse(driveFile);
				e.preventDefault();
			}
			//#endregion
		},

		onKeypress(e) {
			if ((e.which == 10 || e.which == 13) && e.ctrlKey && this.canSend) {
				this.send();
			}
		},

		chooseFile() {
			(this.$refs.file as any).click();
		},

		chooseFileFromDrive() {
			(this as any).apis.chooseDriveFile({
				multiple: false
			}).then(file => {
				this.file = file;
			});
		},

		onChangeFile() {
			this.upload((this.$refs.file as any).files[0]);
		},

		upload(file) {
			(this.$refs.uploader as any).upload(file);
		},

		onUploaded(file) {
			this.file = file;
		},

		send() {
			this.sending = true;
			(this as any).api('messaging/messages/create', {
				userId: this.user.id,
				text: this.text ? this.text : undefined,
				fileId: this.file ? this.file.id : undefined
			}).then(message => {
				this.clear();
			}).catch(err => {
				console.error(err);
			}).then(() => {
				this.sending = false;
			});
		},

		clear() {
			this.text = '';
			this.file = null;
			this.deleteDraft();
		},

		saveDraft() {
			const data = JSON.parse(localStorage.getItem('message_drafts') || '{}');

			data[this.draftId] = {
				updatedAt: new Date(),
				data: {
					text: this.text,
					file: this.file
				}
			}

			localStorage.setItem('message_drafts', JSON.stringify(data));
		},

		deleteDraft() {
			const data = JSON.parse(localStorage.getItem('message_drafts') || '{}');

			delete data[this.draftId];

			localStorage.setItem('message_drafts', JSON.stringify(data));
		},
	}
});
</script>

<style lang="stylus" scoped>
@import '~const.styl'

root(isDark)
	> textarea
		cursor auto
		display block
		width 100%
		min-width 100%
		max-width 100%
		height 64px
		margin 0
		padding 8px
		resize none
		font-size 1em
		color isDark ? #fff : #000
		outline none
		border none
		border-top solid 1px isDark ? #4b5056 : #eee
		border-radius 0
		box-shadow none
		background transparent

	> .file
		padding 8px
		color #444
		background #eee
		cursor pointer

	> .send
		position absolute
		bottom 0
		right 0
		margin 0
		padding 10px 14px
		font-size 1em
		color #aaa
		transition color 0.1s ease

		&:hover
			color $theme-color

		&:active
			color darken($theme-color, 10%)
			transition color 0s ease

	.files
		display block
		margin 0
		padding 0 8px
		list-style none

		&:after
			content ''
			display block
			clear both

		> li
			display block
			float left
			margin 4px
			padding 0
			width 64px
			height 64px
			background-color #eee
			background-repeat no-repeat
			background-position center center
			background-size cover
			cursor move

			&:hover
				> .remove
					display block

			> .remove
				display none
				position absolute
				right -6px
				top -6px
				margin 0
				padding 0
				background transparent
				outline none
				border none
				border-radius 0
				box-shadow none
				cursor pointer

	.attach-from-local
	.attach-from-drive
		margin 0
		padding 10px 14px
		font-size 1em
		font-weight normal
		text-decoration none
		color #aaa
		transition color 0.1s ease

		&:hover
			color $theme-color

		&:active
			color darken($theme-color, 10%)
			transition color 0s ease

	input[type=file]
		display none

.mk-messaging-form[data-darkmode]
	root(true)

.mk-messaging-form:not([data-darkmode])
	root(false)

</style>
