import React from 'react';
import Module from '../Module';
import { Resolver } from '../Types';
export default class ModuleSystem {
	constructor() {
		this.constructors = {};
		this.refs = {};
	}

	loadModule(name, ctor, namespace = "default") {
		// Load a Module constructor
		if(! ctor instanceof Module ){
			throw new Error("This is not a module: ", ctor);
		}
		if(!this.constructors[namespace]) 
			this.constructors[namespace] = {};
		
		if(this.constructors[namespace][name]) {
			log("Duplicate module: ", ctor);
			return true;
		}
		this.constructors[namespace][name] = ctor;
	}

	load(Dictionary, Namespace = "default") {
		for(var i in Dictionary) {
			this.loadModule(i, Dictionary[i], Namespace);
		}
	}

	list() {
		return this.constructors;
	}

	get(modName, namespace = "default") {
		return this.constructors[namespace][modName];
	}

	fromViewNode(vn) {
		return this.get(vn.value, vn.namespace);
	}

	createRef(id) {
		!this.refs[id] && (this.refs[id] = React.createRef());
		return this.refs[id];
	}
	getRef(id) {
		return this.refs[id];
	}

	createElement(name, props, children, namespace = "default", ref) {
		let ctor = this.get(name, namespace);
		return this.createElementCtor(ctor, props, children, ref);
	}
	createElementCtor(ctor, props, children, ref) {
		let validatedProps = this.validateProps(ctor, props);
		if (ref) {
			validatedProps = {
				...validatedProps,
				ref: this.refs[ref]
			}	
		}
		return React.createElement(ctor, validatedProps, children);
	}

	validateProps(ctor, props = {}) {
		let res = {};
		if(ctor && ctor.Inputs) {
			res = Resolver(ctor.Inputs, props);
		}
		return {
			...props,
			...res
		}
	}
}