<template>
	<div class="field is-grouped">
		<p
			:class="{ 'is-loading': taskService.loading }"
			class="control has-icons-left is-expanded"
		>
			<input
				:class="{ disabled: taskService.loading }"
				@keyup.enter="addTask()"
				class="input"
				placeholder="Add a new task..."
				type="text"
				v-focus
				v-model="newTaskText"
				ref="newTaskInput"
			/>
			<span class="icon is-small is-left">
				<icon icon="tasks" />
			</span>
		</p>
		<p class="control">
			<x-button
				:disabled="newTaskText.length === 0"
				@click="addTask()"
				icon="plus"
			>
				Add
			</x-button>
		</p>
	</div>
</template>

<script>
import LabelTask from '../../models/labelTask';
import LabelModel from '../../models/label';

import { HAS_TASKS } from '@/store/mutation-types';
// import Nothing from "@/components/misc/nothing";

import ListService from '../../services/list';
import TaskService from '../../services/task';
import TaskModel from '../../models/task';
import LabelService from '../../services/label';
import LabelTaskService from '../../services/labelTask';

export default {
	name: 'add-task',
	data() {
		return {
			newTaskText: '',
			listService: ListService,
			taskService: TaskService,
			labelService: LabelService,
			labelTaskService: LabelTaskService,
		};
	},
	components: {},
	props: {
		listId: {
			type: Number,
			required: false,
		},
	},
	created() {
		this.listService = new ListService();
		this.taskService = new TaskService();
		this.labelService = new LabelService();
		this.labelTaskService = new LabelTaskService();
	},
	methods: {
		addTask() {
			if (this.newTaskText === '') {
				this.showError = true;
				return;
			}
			this.showError = false;

			const task = new TaskModel({
				title: this.newTaskText,
				listId: this.listId,
			});

			if (this.listId === undefined) {
				// TODO: Have a default list in settings.
				task.listId = 1;
			}
			this.taskService
				.create(task)
				.then(task => {
					// this.tasks.push(task);
					// this.sortTasks();
					this.newTaskText = '';

					// Check if the task has words starting with ~ in the title and make them to labels
					const parts = task.title.split(' ~');
					// The first element will always contain the title, even if there is no occurrence of ~
					if (parts.length > 1) {
						// First, create an unresolved promise for each entry in the array to wait
						// until all labels are added to update the task title once again
						let labelAddings = [];
						let labelAddsToWaitFor = [];
						parts.forEach((p, index) => {
							if (index < 1) {
								return;
							}

							labelAddsToWaitFor.push(
								new Promise((resolve, reject) => {
									labelAddings.push({ resolve: resolve, reject: reject });
								}),
							);
						});

						// Then do everything that is involved in finding, creating and adding the label to the task
						parts.forEach((p, index) => {
							if (index < 1) {
								return;
							}

							// The part up until the next space
							const labelTitle = p.split(' ')[0];

							// Don't create an empty label
							if (labelTitle === '') {
								return;
							}

							// Check if the label exists
							this.labelService
								.getAll({}, { s: labelTitle })
								.then(res => {
									// Label found, use it
									if (res.length > 0 && res[0].title === labelTitle) {
										const labelTask = new LabelTask({
											taskId: task.id,
											labelId: res[0].id,
										});
										this.labelTaskService
											.create(labelTask)
											.then(result => {
												task.labels.push(res[0]);

												// Remove the label text from the task title
												task.title = task.title.replace(` ~${labelTitle}`, '');

												// Make the promise done (the one with the index 0 does not exist)
												labelAddings[index - 1].resolve(result);
											})
											.catch(e => {
												this.error(e, this);
											});
									} else {
										// label not found, create it
										const label = new LabelModel({ title: labelTitle });
										this.labelService
											.create(label)
											.then(res => {
												const labelTask = new LabelTask({
													taskId: task.id,
													labelId: res.id,
												});
												this.labelTaskService
													.create(labelTask)
													.then(result => {
														task.labels.push(res);

														// Remove the label text from the task title
														task.title = task.title.replace(
															` ~${labelTitle}`,
															'',
														);

														// Make the promise done (the one with the index 0 does not exist)
														labelAddings[index - 1].resolve(result);
													})
													.catch(e => {
														this.error(e, this);
													});
											})
											.catch(e => {
												this.error(e, this);
											});
									}
								})
								.catch(e => {
									this.error(e, this);
								});
						});

						// This waits to update the task until all labels have been added and the title has
						// been modified to remove each label text
						Promise.all(labelAddsToWaitFor).then(() => {
							this.taskService
								.update(task)
								// .then(updatedTask => {
								// 	this.updateTasks(updatedTask);
								// 	this.$store.commit(HAS_TASKS, true);
								// })
								.then(() => {
									this.$store.commit(HAS_TASKS, true);
								})
								.catch(e => {
									this.error(e, this);
								});
						});
					}
					this.$emit('taskAdded', task);
				})
				.catch(e => {
					this.error(e, this);
				});
		},
	},
};
</script>
