import ko from 'ko';

import { pString } from 'Common/Utils';
import { settings } from 'Common/Links';
import { createElement/*, elementById*/, fireEvent } from 'Common/Globals';

import { AbstractScreen } from 'Knoin/AbstractScreen';
import { i18nToNodes } from 'Common/Translator';

const VIEW_MODELS = [];

export class AbstractSettingsScreen extends AbstractScreen {
	/**
	 * @param {Array} viewModels
	 */
	constructor(viewModels) {
		super('settings', viewModels);

		this.menu = ko.observableArray();

		this.oCurrentSubScreen = null;
	}

	onRoute(subName) {
		let settingsScreen = null,
			viewModelDom = null,
			RoutedSettingsViewModel = VIEW_MODELS.find(
				SettingsViewModel => subName === SettingsViewModel.route
			);

		if (RoutedSettingsViewModel) {
//			const vmPlace = elementById('V-SettingsPane') || elementById('V-AdminPane);
			const vmPlace = this.viewModels[1].__vm.viewModelDom,
				SettingsViewModelClass = RoutedSettingsViewModel.vmc;
			if (SettingsViewModelClass.__vm) {
				settingsScreen = SettingsViewModelClass.__vm;
				viewModelDom = settingsScreen.viewModelDom;
			} else if (vmPlace) {
				viewModelDom = createElement('div',{
					id: 'V-Settings-' + SettingsViewModelClass.name.replace(/(User|Admin)Settings/,''),
					hidden: ''
				})
				vmPlace.append(viewModelDom);

				settingsScreen = new SettingsViewModelClass();
				settingsScreen.viewModelDom = viewModelDom;
				settingsScreen.viewModelTemplateID = RoutedSettingsViewModel.template;

				SettingsViewModelClass.__vm = settingsScreen;

				fireEvent('rl-view-model.create', settingsScreen);

				ko.applyBindingAccessorsToNode(
					viewModelDom,
					{
						template: () => ({ name: RoutedSettingsViewModel.template })
					},
					settingsScreen
				);

				settingsScreen.onBuild?.(viewModelDom);

				fireEvent('rl-view-model', settingsScreen);
			} else {
				console.log('Cannot find sub settings view model position: SettingsSubScreen');
			}

			if (settingsScreen) {
				setTimeout(() => {
					// hide
					this.onHide();
					// --

					this.oCurrentSubScreen = settingsScreen;

					// show
					settingsScreen.beforeShow?.();
					i18nToNodes(viewModelDom);
					viewModelDom.hidden = false;
					settingsScreen.onShow?.();

					this.menu.forEach(item => {
						item.selected(
							item.route === RoutedSettingsViewModel.route
						);
					});

					(vmPlace || {}).scrollTop = 0;
					// --
				}, 1);
			}
		} else {
			hasher.replaceHash(settings());
		}
	}

	onHide() {
		let subScreen = this.oCurrentSubScreen;
		if (subScreen) {
			subScreen.onHide?.();
			subScreen.viewModelDom.hidden = true;
		}
	}

	onBuild() {
		// TODO: issue on account switch
		// When current domain has sieve but the new has not, or current has not and the new has
		// SettingsViewModel.disabled() || this.menu.push()
		VIEW_MODELS.forEach(SettingsViewModel => this.menu.push(SettingsViewModel));
	}

	routes() {
		const DefaultViewModel = VIEW_MODELS.find(
				SettingsViewModel => SettingsViewModel.isDefault
			),
			defaultRoute = DefaultViewModel?.route || 'general',
			rules = {
				subname: /^(.*)$/,
				normalize_: (rquest, vals) => {
					vals.subname = pString(vals.subname ?? defaultRoute);
					return [vals.subname];
				}
			};

		return [
			['{subname}/', rules],
			['{subname}', rules],
			['', rules]
		];
	}
}

/**
 * @param {Function} SettingsViewModelClass
 * @param {string} template
 * @param {string} labelName
 * @param {string} route
 * @param {boolean=} isDefault = false
 * @returns {void}
 */
export function settingsAddViewModel(SettingsViewModelClass, template, labelName, route, isDefault = false) {
	let name = SettingsViewModelClass.name.replace(/(User|Admin)Settings/, '');
	VIEW_MODELS.push({
		vmc: SettingsViewModelClass,
		label: labelName || 'SETTINGS_LABELS/' + name.toUpperCase(),
		route: route || name.toLowerCase(),
		selected: ko.observable(false),
		template: template || SettingsViewModelClass.name,
		isDefault: !!isDefault
	});
}
