import {LitElement, html} from './lit-core.min.js';
import * as tfrpc from '/static/tfrpc.js';

class TodosElement extends LitElement {
	static get properties() {
		return {
			lists: {type: Array}
		};
	}

	constructor() {
		super();
		this.lists = [];
		let self = this;
		tfrpc.rpc.todo_get_all().then(function(lists) {
			self.lists = lists;
		}).catch(function(error) {
			console.log(error);
		});
	}

	async new_list() {
		await tfrpc.rpc.todo_add('new list');
		await this.refresh();
	}

	async refresh() {
		this.lists = await tfrpc.rpc.todo_get_all();
	}

	render() {
		return html`
			<div>
				<div style="display: flex">
					${this.lists.map(x => html`
						<tf-todo-list name=${x.name} .items=${x.items} @change=${this.refresh}></tf-todo-list>
					`)}
				</div>
				<input type="button" @click=${this.new_list} value="+ List"></input>
			</div>`;
	}
}

class TodoListElement extends LitElement {
	static get properties() {
		return {
			name: {type: String},
			items: {type: Array},
			editing: {type: Number},
			editing_name: {type: Boolean},
		};
	}

	constructor() {
		super();
		this.items = [];
	}

	save() {
		let self = this;
		console.log('saving', self.name, self.items);
		tfrpc.rpc.todo_set(self.name, self.items).then(function() {
			console.log('saved', self.name, self.items);
		}).catch(function(error) {
			console.log(error);
		});
	}

	remove_item(item) {
		let index = this.items.indexOf(item);
		this.items = [].concat(this.items.slice(0, index), this.items.slice(index + 1));
		this.save();
	}

	handle_check(event, item) {
		item.x = event.srcElement.checked;
		this.save();
	}

	input_blur(item) {
		this.save();
		this.editing = undefined;
	}

	input_change(event, item) {
		item.text = event.srcElement.value;
	}

	input_keydown(event, item) {
		if (event.key === 'Enter' || event.key === 'Escape') {
			item.text = event.srcElement.value;
			this.editing = undefined;
			this.save();
		}
	}

	updated() {
		let edit = this.renderRoot.getElementById('edit');
		if (edit) {
			edit.select();
		}
	}

	render_item(item) {
		let index = this.items.indexOf(item);
		let self = this;
		if (index === this.editing) {
			return html`
				<div><input type="checkbox" ?checked=${item.x} @change=${x => self.handle_check(x, item)}></input>
				<input
					id="edit"
					type="text"
					value=${item.text}
					@change=${event => self.input_change(event, item)}
					@keydown=${event => self.input_keydown(event, item)}
					@blur=${x => self.input_blur(item)}></input>
				<span @click=${x => self.remove_item(item)} style="cursor: pointer">❎</span></div>
			`;
		} else {
			return html`
				<div><input type="checkbox" ?checked=${item.x} @change=${x => self.handle_check(x, item)}></input>
				<span @click=${x => self.editing = index}>${item.text || '(empty)'}</span>
			`;
		}
	}

	add_item() {
		this.items = [].concat(this.items || [], [{text: 'new item'}]);
		this.editing = this.items.length - 1;
		this.save();
	}

	async remove_list() {
		if (confirm(`Are you sure you want to remove "${this.name}"?`)) {
			await tfrpc.rpc.todo_remove(this.name);
			this.dispatchEvent(new Event('change'));
		}
	}

	rename(new_name) {
		let self = this;
		return tfrpc.rpc.todo_rename(this.name, new_name).then(function() {
			self.dispatchEvent(new Event('change'));
			self.editing_name = false;
		}).catch(function(error) {
			console.log(error);
			alert(error.message);
			self.editing_name = false;
		});
	}

	name_blur(new_name) {
		this.rename(new_name);
	}

	name_keydown(event, item) {
		let self = this;
		if (event.key == 'Enter' || event.key === 'Escape') {
			let new_name = event.srcElement.value;
			this.rename(new_name);
		}
	}

	render() {
		let self = this;
		let name = this.editing_name ?
			html`<input
				type="text"
				id="edit"
				@keydown=${event => self.name_keydown(event)}
				@blur=${event => self.name_blur(event.srcElement.value)}
				value=${this.name}></input>` :
			html`<h2 @click=${x => this.editing_name = true}>${this.name}</h2>`;
		return html`
			<div style="border: 3px solid black; padding: 8px; margin: 8px; border-radius: 8px; background-color: #444">
				${name}
				${(this.items || []).filter(item => !item.x).map(x => self.render_item(x))}
				${(this.items || []).filter(item => item.x).map(x => self.render_item(x))}
				<button @click=${self.add_item}>+ Item</button>
				<button @click=${self.remove_list}>- List</button>
			</div>
		`;
	}
}

customElements.define('tf-todo-list', TodoListElement);
customElements.define('tf-todos', TodosElement);