import { Utils } from './lib/Utils';
import html2canvas from 'html2canvas';
import { c } from './lib/Log';
import { Api } from './Api';

abstract class Modal {
	protected div:     HTMLDivElement;
	protected doneBtn: HTMLAnchorElement | null;
	protected loader:  HTMLImageElement;
	constructor(className: string) {
		this.div     = document.querySelector(`div.modal.${className}`) as HTMLDivElement;
	 	this.doneBtn = this.div.querySelector<HTMLAnchorElement>('.js-close');
		this.loader  = this.div.querySelector('.js-loader') as HTMLImageElement;
		
		this.doneBtn?.addEventListener('click', (e) => {
			e.preventDefault();
			this.hide();
		});
		this.div.addEventListener('click', (e) => {
			if (e.target === this.div) {
				c.debug(`modal:background.click`);
				this.hide();
			}
		});
	}
	/**
	 * Hooks: Implement those to perform the actual work done on show and hide.
	 */
	abstract performBeforeShow(): Promise<void>;
	abstract performShow():       Promise<void>;
	abstract performHide():       Promise<void>;
	async show() {
		await this.performBeforeShow();
		this.div.classList.add('fadeout');
		this.div.classList.remove('hide');
		await Utils.delay(100);
		this.div.classList.remove('fadeout');
		await this.performShow();
		this.loader.classList.add('hide');
	}
	async hide() {
		this.div.classList.add('fadeout');
		await Utils.delay(200);
		this.div.classList.add('hide');
		this.div.classList.remove('fadeout');
		await this.performHide();
	}
}

export class ShareScreenshotModal extends Modal {
	private imResult = this.div.querySelector('.js-result') as HTMLImageElement;
	
	constructor() {
		super(`share-screenshot`);
	}
	async performBeforeShow() {
		this.loader.classList.remove('hide');
	}
	async performShow() {
		await Utils.delay(800); /// <- for good ux
		const el = document.querySelector('div.page-inner') as HTMLDivElement;
		const canvas = await html2canvas(el, {
			logging: false, /// <- inoperant in our version of html2canvas.
			onclone: (doc) => {
				const clonedEl = doc.querySelector('div.page-inner') as HTMLDivElement;
				clonedEl.classList.add('html2canvas');
				const watermark = doc.querySelector('div.watermark') as HTMLDivElement;
				watermark.style.visibility = `visible`;
			}
		});
		this.imResult.src = canvas.toDataURL();
	}
	async performHide() {
		this.imResult.src = "";
	}
}

export class SavePublishModal extends Modal {
	private saveBtn = this.div.querySelector('.js-save') as HTMLAnchorElement;
	private form    = this.div.querySelector('form') as HTMLFormElement;
	constructor(
		private quill: Quill
	) {
		super(`save-publish`);
		
		/// vv Url fields auto-select.
		const urlInputs = Array.from(
			this.div.querySelectorAll('.doc-url')
		) as HTMLInputElement[];
		for (const x of urlInputs) {
			x.addEventListener('focus', () => {
				x.select();
			});
		}
		
		this.saveBtn.addEventListener('click', (e) => {
			e.preventDefault();
			if (! this.form.reportValidity()) {
				/// Form is invalid.
				return ;
			}
			this.save();
		});
		this.form.addEventListener('submit', (e) => {
			e.preventDefault();
			this.saveBtn.click();
		});
	}
	async performBeforeShow() {}
	async performShow() {}
	async performHide() {}
	async save() {
		this.loader.classList.remove('hide');
		
		const inputTitle = this.div.querySelector('.doc-title') as HTMLInputElement;
		const title = inputTitle.value;
		const contents = this.quill.getContents();
		c.log(JSON.stringify({ title, contents }));
		
		const success = await Api.shared.postEdit({ title, contents });
		await Utils.delay(800); /// <- for good ux
		
		if (success) {
			this.loader.classList.add('hide');
			this.hide();
			/// For now we always redirect to the edit url here:
			/// vv
			const inputEditUrl = this.div.querySelector('.doc-edit-url') as HTMLInputElement;
			window.location.href = inputEditUrl.value;
		} else {
			window.alert(`did not manage to save`);
		}
	}
}