import RoutingSystem from './RoutingSystem.js';
import ViewSystem, { View } from './ViewSystem.js';
import ModuleSystem from './ModuleSystem.js';
import Modules from '../../modules';
import EventSystem from './EventSystem';


export default class CoreSystem {
	constructor() {
		// TODO -- Make correct Initialization
		this.Routing = new RoutingSystem();
		this.ModuleSystem = new ModuleSystem();
		this.EventSystem = new EventSystem();
		this.ViewSystem    = new ViewSystem(this.ModuleSystem, this.EventSystem);
		this.__loadModules(Modules);
	}

	getCurrentView() {
		return this.ViewSystem.getView(this.Routing.getCurrentView());
	}

	setHome( route , View ) {
		this.Routing.setHome(route);
		return this;
	}

	goto( route ) {
		return this.Routing.goTo(route);
	}

	addPage( route , View, ViewID = Math.random()) {
		this.Routing.addRoute(route,route);
		this.Routing.setView(route,ViewID);
		this.ViewSystem.addView(ViewID, View);
		return this;
	}

	goBack() {

	}

	__loadModules() {
		this.ModuleSystem.load(Modules);
	}

	addModule(mod, namespace) {
		this.ModuleSystem.loadModule(mod.name, mod, namespace);
		return this;
	}

	render() {
		let ViewID = this.Routing.getCurrentView();
		return this.ViewSystem.render(ViewID);
	}

	import(data) {

		// Perform dependency injection here! 
		// must Convert Data to Structures before importing 
		// Import Systems Seperately from leaf to root
		let {
			Routing,
			Views
		} = data;

		try {
			this.Routing.import(Routing);
			this.ViewSystem.import(Views);
		} catch(e) {
			throw new Error("CoreSystem cannot import data : ", e);
		}
		console.log("Successful import");
	}

	export() {
		let RS = this.Routing.export();
		let VS = this.ViewSystem.export();
		return {
			Routing: RS,
			Views: VS
		};
	}




	ray(data) {
		let {
			event
		} = data;
		let targets = event.path.map(item => findReactElement(item));
		let resViewNode = null;
		for (var i in targets) {
			if(targets[i] !== null){
				if(targets[i].props && targets[i].props.ID) {
					resViewNode = targets[i].props.ID;
					break;
				}
			}
			
		}
		let ViewID = this.Routing.getCurrentView();
		return this.ViewSystem.getNode(ViewID, resViewNode);
	}






}

const findReactElement = (node) => {
    for (var key in node) {
        if (key.startsWith("__reactInternalInstance$")) {
            return node[key]._debugOwner.stateNode;
        }
    }
    return null;
};