const config=require('config');
const assets=require('assets');
const Popup=require('popup');

let lastCEId=0;
class ConfigEditor extends Popup {
	constructor() {
		super("Config editor", [], {ok: "OK"});

		const metaConfig=assets.get('metaConfig');

		this.watchers=[];

		for(let key in metaConfig) {
			const level=Array.from(key).reduce((a, c) => a+c=='.', 0)+2;
			const data=metaConfig[key];

			if(!data.type) {
				this.addHeading(data.name);
			} else {
				let span=document.createElement('span');
				let id='cfgInput-'+(lastCEId++)+'-'+key.replace(/\./g, '-');
				let label=span.appendChild(document.createElement('label'));
				label.innerText=data.name;
				if(config.getB('debug')) label.title=key;

				let input;
				if(data.type=='boolean') {
					input=document.createElement('input');
					input.type='checkbox';
					input.checked=config.getB(key);
					input.addEventListener('change', () => config.set(key, input.checked));
				} else if(data.type=='choice') {
					input=document.createElement('select');
					data.bounds.choices.forEach(choice => {
						let option=document.createElement('option');
						option.value=choice;
						option.innerText=choice;
						input.appendChild(option);
					});
					input.value=config.getS(key);
					input.addEventListener('change', () => config.set(key, input.value));
				} else if(data.type=='number') {
					input=document.createElement('input');
					input.type='number';
					if(data.bounds) {
						input.setAttribute('min', data.bounds.min);
						input.setAttribute('max', data.bounds.max);
						input.setAttribute('step', data.bounds.inc);
					}
					input.value=config.getN(key);
					input.addEventListener('change', () => config.set(key, input.value));
				} else if(data.type=='string') {
					input=document.createElement('input');
					input.type='text';
					input.value=config.getS(key);
					input.addEventListener('change', () => config.set(key, input.value));
				}

				input.setAttribute('id', id);
				span.appendChild(input);
				label.setAttribute('for', id);
				this.addContent(span);

				if(data.excludes) {
					const setEnabled=() => {
						input.disabled=
							data.excludes
								.some(key => config.getB(key));
						input.title=input.disabled?`Disable '${data.excludes.map(k => metaConfig[k].name).join('\', \'')}' to enable`:'';
					};

					setEnabled();
					data.excludes.forEach(key => {
						let c=config.watchB(key, setEnabled);
						this.watchers.push([key, c]);
					});
				} else if(data.parent) {
					const setEnabled=() => {
						input.disabled=!config.getB(data.parent);
						input.title=input.disabled?`Enable '${metaConfig[data.parent].name}' to enable`:'';
					};

					setEnabled();
					let c=config.watchB(data.parent, setEnabled);
					this.watchers.push([data.parent, c]);
				}
				if(data.needsBackend) {
					if(window.serverless) {
						input.disabled=true;
						input.title="Needs backend";
					}
				}
			}
		}

		this.large=true;
	}

	discard() {
		this.watchers.forEach(([k, c]) => config.unwatch(k, c));
	}
};

return module.exports={
	show: async () => {
		let editor=new ConfigEditor();
		await editor.display();
		editor.discard();
	}
};
