<template>
	<div>
		<h3>
			<span class="icon is-grey">
				<icon icon="align-left"/>
			</span>
			{{ $t('task.attributes.description') }}
			<transition name="fade">
				<span class="is-small is-inline-flex" v-if="loading && saving">
					<span class="loader is-inline-block mr-2"></span>
					{{ $t('misc.saving') }}
				</span>
				<span class="is-small has-text-success" v-else-if="!loading && saved">
					<icon icon="check"/>
					{{ $t('misc.saved') }}
				</span>
			</transition>
		</h3>
		<editor
			:is-edit-enabled="canWrite"
			:upload-callback="attachmentUpload"
			:upload-enabled="true"
			@change="save"
			:placeholder="$t('task.description.placeholder')"
			:empty-text="$t('task.description.empty')"
			:show-save="true"
			v-model="task.description"
		/>
	</div>
</template>

<script lang="ts">
import AsyncEditor from '@/components/input/AsyncEditor'

import {LOADING} from '@/store/mutation-types'
import {mapState} from 'vuex'

export default {
	name: 'description',
	components: {
		Editor: AsyncEditor,
	},
	data() {
		return {
			task: {description: ''},
			saved: false,
			saving: false, // Since loading is global state, this variable ensures we're only showing the saving icon when saving the description.
		}
	},
	computed: mapState({
		loading: LOADING,
	}),
	props: {
		modelValue: {
			required: true,
		},
		attachmentUpload: {
			required: true,
		},
		canWrite: {
			required: true,
		},
	},
	emits: ['update:modelValue'],
	watch: {
		modelValue: {
			handler(value) {
				this.task = value
			},
			immediate: true,
		},
	},
	methods: {
		async save() {
			this.saving = true

			try {
				this.task = await this.$store.dispatch('tasks/update', this.task)
				this.$emit('update:modelValue', this.task)
				this.saved = true
				setTimeout(() => {
					this.saved = false
				}, 2000)
			} finally {
				this.saving = false
			}
		},
	},
}
</script>