import {LitElement, html, css, guard, map, until} from './lit-all.min.js';
import * as tfrpc from '/static/tfrpc.js';

class TfAppContextMenuElement extends LitElement {
	static k_limit = 20;
	static get properties() {
		return {
			app: {type: Object},
			user: {type: String},
			whoami: {type: String},
			publishing: {type: Boolean},
			revisions: {type: Array},
			is_admin: {type: Boolean},
		};
	}

	constructor() {
		super();
		let self = this;
		tfrpc.rpc.isAdministrator().then((x) => (self.is_admin = x));
	}

	close() {
		this.app = undefined;
	}

	href() {
		if (this.app.package_owner && this.app.package_name) {
			return `/~${this.app.package_owner}/${this.app.package_name}/`;
		} else if (this.app.message_id) {
			return `/${this.app.message_id}/`;
		} else {
			return `/${this.app.blob_id}/`;
		}
	}

	async set_index() {
		try {
			await tfrpc.rpc.globalSettingsSet('index', this.href());
		} finally {
			this.refresh();
		}
	}

	async render_administrator() {
		if (!this.is_admin) {
			return;
		}
		let current_index = await tfrpc.rpc.globalSettingsGet('index');
		if (current_index === this.href()) {
			return html`<p>This is currently set as the default app (index).</p>`;
		} else {
			return html`<p>
				<button class="w3-button w3-blue" @click=${this.set_index}>
					🏠 Set as Default App
				</button>
			</p>`;
		}
	}

	async publish() {
		let message = {
			type: this.app.message_id ? 'tildefriends-app-edit' : 'tildefriends-app',
			name: this.app.message_id ? undefined : this.app.package_name,
			app: this.app.blob_id,
			updates: this.app.message_id,
			description:
				this.description?.length && this.description !== this.app.description
					? this.description
					: undefined,
			change: this.change?.length ? this.change : undefined,
		};
		console.log(message);
		await tfrpc.rpc.appendMessage(this.whoami, message);
		this.dispatchEvent(
			new CustomEvent('app-publish', {
				bubbles: true,
				composed: true,
			})
		);
		this.app = undefined;
	}

	refresh() {
		this.dispatchEvent(
			new CustomEvent('app-publish', {
				bubbles: true,
				composed: true,
			})
		);
		this.app = undefined;
	}

	async tombstone(value) {
		let message = {
			type: 'tildefriends-app-edit',
			updates: this.app.message_id,
			tombstone: value,
		};
		console.log(message);
		await tfrpc.rpc.appendMessage(this.whoami, message);
		this.refresh();
	}

	async install() {
		console.log(this.app.message_id);
		await tfrpc.rpc.saveApp(
			this.user,
			this.app.package_name,
			this.app.message_id
		);
		this.refresh();
	}

	async delete() {
		await tfrpc.rpc.saveApp(
			this.app.package_owner,
			this.app.package_name,
			null
		);
		this.refresh();
	}

	set_description(event) {
		this.description = event.srcElement.value;
	}

	set_change(event) {
		this.change = event.srcElement.value;
	}

	render_revision(revision) {
		return html`
			<tr>
				<td>
					${revision?.previous
						? html`<a
								target="_top"
								href="/~core/diff/#${encodeURIComponent(
									revision?.previous?.app
								)}:${encodeURIComponent(revision?.app)}"
								>Diff</a
							>`
						: undefined}
				</td>
				<td title=${new Date(revision.timestamp)}>
					<a href="/~core/ssb/#${encodeURIComponent(revision.id)}">
						${new Date(revision.timestamp).toLocaleDateString()}
					</a>
				</td>
				<td>
					${revision.tombstone !== null
						? revision.tombstone
							? html`🪦 Tombstoned`
							: html`🧟 Resurrected.`
						: undefined}
				</td>
				<td>${revision.change}</td>
			</tr>
		`;
	}

	async render_revisions() {
		let revisions = await this.revisions;
		if (!revisions?.length || !this.app?.message_id) {
			return;
		}
		for (let i = 0; i < revisions.length - 1; i++) {
			revisions[i].previous = revisions[i + 1];
		}
		return html`
			<h3>Revision History</h3>
			<table class="w3-table w3-striped">
				${map(
					revisions.slice(0, TfAppContextMenuElement.k_limit),
					this.render_revision
				)}
				<tr>
					<td colspan="3">
						${revisions.length > TfAppContextMenuElement.k_limit
							? html`<div class="w3-bar">
									<div class="w3-bar-item">...</div>
								</div>`
							: undefined}
					</td>
				</tr>
			</table>
		`;
	}

	render_context_menu() {
		if (!this.app) {
			return undefined;
		}
		let self = this;
		return html`
			<link type="text/css" rel="stylesheet" href="w3.css" />
			<div class="w3-modal" style="display: block" @click=${this.close}>
				<div
					class="w3-modal-content w3-animate-top"
					@click=${(event) => event.stopPropagation()}
				>
					<header class="w3-bar w3-blue">
						<h1 class="w3-container w3-bar-item">
							${this.app.emoji ?? '📦'} ${this.app.package_name}
						</h1>
						<button
							class="w3-button w3-bar-item w3-right w3-blue"
							@click=${this.close}
						>
							×
						</button>
					</header>
					<div class="w3-container w3-paper">
						<p>
							${this.app.author
								? html`Published by
										<a href="/~core/ssb/#${encodeURIComponent(this.app.author)}"
											>${this.app.author_name}</a
										>
										on
										<a
											href="/~core/ssb/#${encodeURIComponent(
												this.app.message_id
											)}"
											>${new Date(this.app.timestamp)}</a
										>.`
								: html`Installed at
										<a
											href="/~${this.app.package_owner}/${this.app
												.package_name}/"
											>/~${this.app.package_owner}/${this.app.package_name}/</a
										>.`}
							${until(this.render_administrator(), 'Loading...')}
						</p>
						${this.app.description !== undefined
							? html`
									<h3>Description</h3>
									<p>${this.app.description}</p>
								`
							: undefined}
						${this.app.change !== undefined
							? html`
									<h3>Latest Update</h3>
									<p>${this.app.change}</p>
								`
							: undefined}
						${until(this.render_revisions(), html`<p>Loading...</p>`)}
						${this.app.author === undefined
							? html`
								${this.app.shared ? html`<p>🏷️ This app has been <a href="/~core/ssb/#${encodeURIComponent(this.app.message_id)}">published</a>.</p>` : undefined}
								${this.app.modified ? html`<p>📝 There are unpublished changes to this app.</p>` : undefined}
							</p>
						`
							: undefined}
						${this.app.package_owner === this.user &&
						(!this.app.shared || this.app.modified)
							? this.publishing
								? html`
									<div>
										<header class="w3-container w3-red">
											<h2>Publish</h2>
										</header>
										<div class="w3-container w3-padding w3-pale-red">
											<label for="description">App Description</label>
											<textarea class="w3-input w3-paper" style="resize: vertical" placeholder="Purpose of the app." @change=${this.set_description}>${this.app.description}</textarea>
											<label for="change">Change description</label>
											<input type="text" class="w3-input w3-paper" placeholder="Summary of what changed." id="change" @change=${this.set_change}></input>
										</div>
										<footer class="w3-container w3-red w3-padding">
											<button class="w3-button" @click=${() => (this.publishing = false)}>Discard</button>
											<button class="w3-button" @click=${this.publish}>Publish App</button>
										</footer>
									</div>
								`
								: html`
										<button
											class="w3-button w3-blue"
											@click=${() => (self.publishing = true)}
										>
											Publish...
										</button>
									`
							: undefined}
						${this.app.shared && this.app.message_id
							? this.app.tombstone
								? html`
										<button
											class="w3-button w3-blue"
											@click=${() => self.tombstone(false)}
										>
											Restore
										</button>
									`
								: html`
										<button
											class="w3-button w3-blue"
											@click=${() => self.tombstone(true)}
										>
											Tombstone
										</button>
									`
							: undefined}
						<p>
							<a class="w3-button w3-blue" href=${this.href()}> Open </a>
							<a class="w3-button w3-blue" href="${this.href()}?edit=1">
								Edit
							</a>
							${(!this.app?.message_id &&
								(this.app.package_owner == this.user || this.is_admin)) ||
							this.app.installed
								? html`
										<button class="w3-button w3-blue" @click=${this.delete}>
											Delete
										</button>
									`
								: undefined}
							${this.app?.message_id && !this.app.installed
								? html`
										<button class="w3-button w3-blue" @click=${this.install}>
											Install
										</button>
									`
								: undefined}
						</p>
					</div>
				</div>
			</div>
		`;
	}

	render() {
		if (this.app?.message_id && this._revisions_id !== this.app.message_id) {
			this.revisions = tfrpc.rpc.get_revisions(
				this.app.message_id,
				TfAppContextMenuElement.k_limit + 1
			);
			this._revisions_id = this.app.message_id;
		}
		return html`
			<link type="text/css" rel="stylesheet" href="w3.css" />
			${this.render_context_menu()}
		`;
	}
}

customElements.define('tf-app-context-menu', TfAppContextMenuElement);
