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

class TfWikiDocElement extends LitElement {
	static get properties() {
		return {
			whoami: {type: String},
			wiki: {type: String},
			value: {type: Object},
			blob: {type: String},
			blob_original: {type: String},
			blob_for_value: {type: String},
			is_editing: {type: Boolean},
		};
	}

	constructor() {
		super();
	}

	markdown(md) {
		var reader = new commonmark.Parser({safe: true});
		var writer = new commonmark.HtmlRenderer();
		var parsed = reader.parse(md || '');
		let walker = parsed.walker();
		let event;
		while ((event = walker.next())) {
			let node = event.node;
			if (event.entering) {
				if (node.type === 'link') {
					if (node.destination.indexOf(':') == -1 &&
						node.destination.indexOf('/') == -1) {
						node.destination = `#${this.wiki?.name}/${node.destination}`;
					}
				}
			}
		}
		return writer.render(parsed);
	}

	async load_blob() {
		let blob = await tfrpc.rpc.get_blob(this.value?.blob);
		if (blob.endsWith('.box')) {
			let d = await tfrpc.rpc.try_decrypt(this.whoami, blob);
			if (d) {
				blob = d;
			}
		}
		this.blob = blob;
		this.blob_original = blob;
	}

	on_edit(event) {
		this.blob = event.srcElement.value;
	}

	on_discard(event) {
		this.blob = this.blob_original;
		this.is_editing = false;
	}

	async append_message(draft) {
		let blob = this.blob;
		if (draft) {
			blob = await tfrpc.rpc.encrypt(this.whoami, this.value.editors, blob);
		}
		let id = await tfrpc.rpc.store_blob(blob);
		let message = {
			type: 'wiki-doc',
			key: this.value.id,
			parent: this.value.parent,
			blob: id,
		};
		if (draft) {
			message.recps = this.value.editors;
			print(message);
			message = await tfrpc.rpc.encrypt(this.whoami, this.value.editors, JSON.stringify(message));
		}
		print(message);
		await tfrpc.rpc.appendMessage(this.whoami, message);
		this.is_editing = false;
	}

	async on_save_draft() {
		return this.append_message(true);
	}

	async on_publish() {
		return this.append_message(false);
	}

	render() {
		let value = JSON.stringify(this.value);
		if (this.blob_for_value != value) {
			this.blob_for_value = value;
			this.blob = undefined;
			this.blob_original = undefined;
			this.load_blob();
		}
		let self = this;
		return html`
			<div style="display: inline-flex; flex-direction: row">
				<button ?disabled=${!this.whoami || this.is_editing} @click=${() => self.is_editing = true}>Edit</button>
				<button ?disabled=${this.blob == this.blob_original} @click=${this.on_save_draft}>Save Draft</button>
				<button ?disabled=${this.blob == this.blob_original && !this.value?.draft} @click=${this.on_publish}>Publish</button>
				<button ?disabled=${!this.is_editing} @click=${this.on_discard}>Discard</button>
			</div>
			<div style="display: flex; flex-direction: row">
				<textarea
					?hidden=${!this.is_editing}
					style="flex: 1 1; min-height: 10em"
					@input=${this.on_edit} .value=${this.blob ?? ''}></textarea>
				<div style="flex: 1 1">${unsafeHTML(this.markdown(this.blob))}</div>
			</div>
		`;
	}
}

customElements.define('tf-wiki-doc', TfWikiDocElement);