import type { DynamicComponentLazyLoadedModalArgs, IDynamicComponentContainer } from './dynamic-component-contracts';
import { toNative, Vue } from 'vue-facing-decorator';
import PowerduckState from '../../app/powerduck-state';
import { Component } from '../../app/vuetsx';
import { DialogUtils } from '../../common/dialog-utils';

@Component
class DynamicComponentContainerComponent extends Vue implements IDynamicComponentContainer {
	private vueTsxProps: Readonly<{ ref?: string }>;
	private instanceCache: { [uuid: string]: any } = {};

	created() {
		this.instanceCache = {};
	}

	getInstance<T>(uuid: string): T {
		return this.instanceCache[uuid] as T;
	}

	addInstance(uuid: string, componentConstructor: any) {
		// eslint-disable-next-line new-cap -- caller may pass a Vue ctor with lowercase identifier
		const instance = new componentConstructor();
		instance.$mount();
		(this.$refs.componentContainer as HTMLElement).appendChild(instance.$el);
		this.instanceCache[uuid] = instance;
	}

	async showLazyLoadedModal(args: DynamicComponentLazyLoadedModalArgs): Promise<any> {
		const dataArgs = args.args || {};
		let instance = PowerduckState.rootDynamicComponentContainer.getInstance(args.cacheId) as any;
		const onBeforeShown = dataArgs.onBeforeShown;
		const onShown = dataArgs.onShown;

		if (instance == null) {
			const dialog = await DialogUtils.showDialogEx({
				buttons: [],
				title: args.title,
				message: '',
				size: args.modalSize as any,
			});

			dialog.showLoading();

			setTimeout(async () => {
				dataArgs.onBeforeShown = (e) => {
					(e.instance.$refs.modalRoot as HTMLElement)?.classList.remove('fade');

					if (onBeforeShown != null) {
						onBeforeShown(e);
					}
				};

				dataArgs.onShown = (e) => {
					dialog.modalContext.style.visibility = 'hidden';
					const backdrops = document.querySelectorAll<HTMLElement>('.modal-backdrop.fade.show');
					const lastBackdrop = backdrops[backdrops.length - 1];
					if (lastBackdrop != null) {
						lastBackdrop.style.visibility = 'hidden';
					}

					setTimeout(() => {
						//
						dialog.hideModal();
						document.querySelectorAll('.modal-backdrop').forEach(el => el.classList.add('fade'));
						(e.instance.$refs.modalRoot as HTMLElement)?.classList.add('fade');
					}, 10);

					if (onShown != null) {
						onShown(e);
					}
				};

				const importResult = await args.moduleImport;
				PowerduckState.rootDynamicComponentContainer.addInstance(args.cacheId, importResult.default);
				instance = PowerduckState.rootDynamicComponentContainer.getInstance(args.cacheId);

				this.$nextTick(() => {
					instance.show(dataArgs);
				});
			}, 500);
		} else {
			instance.show(dataArgs);
		}
	}

	render(h) {
		return <div ref="componentContainer"></div>;
	}
}

const DynamicComponentContainer = toNative(DynamicComponentContainerComponent);
export default DynamicComponentContainer;
