import {LitElement, html, unsafeHTML} from './lit-all.min.js';
import * as tfrpc from '/static/tfrpc.js';
import {styles} from './tf-styles.js';

class TfTabQueryElement extends LitElement {
	static get properties() {
		return {
			whoami: {type: String},
			users: {type: Object},
			following: {type: Array},
			query: {type: String},
			expanded: {type: Object},
			results: {type: Array},
			error: {type: Object},
			duration: {type: Number},
		};
	}

	static styles = styles;

	constructor() {
		super();
		let self = this;
		this.whoami = null;
		this.users = {};
		this.following = [];
		this.expanded = {};
		this.duration = undefined;
	}

	async search(query) {
		console.log('Searching...', this.whoami, query);
		this.results = [];
		this.error = undefined;
		this.duration = undefined;
		let search = this.renderRoot.getElementById('search');
		if (search) {
			search.value = query;
			search.focus();
		}
		await tfrpc.rpc.setHash('#sql=' + encodeURIComponent(query));
		let start_time = new Date();
		try {
			this.results = await tfrpc.rpc.query(query, []);
		} catch (error) {
			this.error = error;
		}
		let end_time = new Date();
		this.duration = (end_time - start_time).valueOf();
		console.log('Done.');
		search = this.renderRoot.getElementById('search');
		if (search) {
			search.value = query;
			search.focus();
		}
	}

	search_keydown(event) {
		if (event.keyCode == 13 && event.ctrlKey) {
			this.query = this.renderRoot.getElementById('search').value;
			event.preventDefault();
		}
	}

	on_expand(event) {
		if (event.detail.expanded) {
			let expand = {};
			expand[event.detail.id] = true;
			this.expanded = Object.assign({}, this.expanded, expand);
		} else {
			delete this.expanded[event.detail.id];
			this.expanded = Object.assign({}, this.expanded);
		}
	}

	render_results() {
		if (!this.results?.length) {
			return html`<div>No results.</div>`;
		} else {
			let keys = Object.keys(this.results[0]).sort();
			return html`<table style="width: 100%; max-width: 100%">
				<tr>
					${keys.map((key) => html`<th>${key}</th>`)}
				</tr>
				${this.results.map(
					(row) =>
						html`<tr>
							${keys.map((key) => html`<td>${row[key]}</td>`)}
						</tr>`
				)}
			</table>`;
		}
	}

	render_error() {
		if (this.error) {
			return html`<h2 style="color: red">${this.error.message}</h2>
				<pre style="color: red">${this.error.stack}</pre>`;
		}
	}

	render() {
		if (this.query !== this.last_query) {
			this.last_query = this.query;
			this.search(this.query);
		}
		let self = this;
		return html`
			<div style="display: flex; flex-direction: row; gap: 4px">
				<textarea
					id="search"
					rows="8"
					class="w3-input w3-theme-d1"
					style="flex: 1; resize: vertical"
					@keydown=${this.search_keydown}
				>
${this.query}</textarea
				>
				<button
					class="w3-button w3-theme-d1"
					@click=${(event) =>
						self.search(self.renderRoot.getElementById('search').value)}
				>
					Execute
				</button>
			</div>
			<div ?hidden=${this.duration === undefined}>
				Took ${this.duration / 1000.0} seconds.
			</div>
			<div ?hidden=${this.duration !== undefined}>Executing...</div>
			${this.render_error()} ${this.render_results()}
		`;
	}
}

customElements.define('tf-tab-query', TfTabQueryElement);