import React from 'react';
import {StyleSheet, View, Text} from 'react-native';
import Library from 'trapilib/dist/lib';
import { TextInput, Image, Button } from 'react-native';

import TextEditor from '../Components/TextEditor';
import Alignment from '../Components/Alignment';
import ContainerEditor from '../Components/ContainerEditor';

// import Numbers from '../Components/Numbers';
// import ColorEditor from '../Components/ColorEditor';
import TypeHandler from '../Components/TypeHandler.js';

import BaseSystem from './System';




let {
	CoreSystem,
	ViewSystem,
	ViewNode,
	DataTypes
} = Library; 
function download(filename, text) {
  var element = document.createElement('a');
  element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
  element.setAttribute('download', filename);

  element.style.display = 'none';
  document.body.appendChild(element);

  element.click();

  document.body.removeChild(element);
}
export default class SideBar extends BaseSystem {
	constructor(CoreSystem, ToolBox){
		super();
		this.CoreSystem = CoreSystem;
		this.ToolBox = ToolBox;
		this.showAllData = false;
	}
	toggleAll() {
		this.showAllData = !this.showAllData;
		this.forceUpdate();
	}
	import() {
		let CurrentView = this.CoreSystem.getCurrentView();
		let text = window.prompt("Feed me plz");
		if(text) {
			CurrentView.import(JSON.parse(text), this.ContainerNode.id);
		}
	}
	export() {
		let CurrentView = this.CoreSystem.getCurrentView();
		let data = CurrentView.export();
		download("Export_" + new Date().toISOString()+".txt", JSON.stringify(data));
	}

	removeNode(node) {
		let CurrentView = this.CoreSystem.getCurrentView();
		console.log(node)
		if (CurrentView.has(node)) {
			CurrentView.remove(node);
		}
		this.forceUpdate();
	}

    editNode(node, text, key){
		node.props[key] = text;
		this.forceUpdate();
    }
    editNodeStyle(node, style) {
    	node.props = {
    		...node.props,
    		...style
    	}
    	this.forceUpdate();
    }

    createHandler(Structure, viewNodeProps, key, onChange) {
    	let Editor = TypeHandler(Structure);
		let editorProps = {
			title: key,
			onChange: (value) => {
				onChange && onChange(value, key)
			}
		};
		let val = viewNodeProps[key];

		switch(Structure.type){
			case DataTypes.Types.Integer:
			case DataTypes.Types.Real:
			case DataTypes.Types.Text:
			case DataTypes.Types.Action:
			case DataTypes.Types.Module:
				editorProps.value = val;
				break;
			case DataTypes.Types.Boolean:
				editorProps.value = val === 'true' || val == true;
				break;
			case DataTypes.Types.Array:
				editorProps.value = val;
				editorProps.template = Structure.Template;
				break;
			default:
				//Must create a generic Vuiew Component
				return (<View></View>)
		}

		return <Editor {...editorProps} key={key}/>
    }

	render(){
		let ModuleSystem = this.CoreSystem.ModuleSystem;
		let CurrentView = this.CoreSystem.getCurrentView();
		
		let selectedNode = this.ToolBox.selectedNode;
		
		let Structure = {},
			styles = {},
			nodeStructure = {};
		let viewNodeProps = {},
			nodeProps = {};

		if (selectedNode && CurrentView.has(selectedNode)) {
			this.ContainerNode = selectedNode;
			if(selectedNode.content && selectedNode.content.value) {
				let ctor = ModuleSystem.fromViewNode(selectedNode.content);
				styles = ctor.Styles;
				viewNodeProps = ModuleSystem.validateProps(ctor, selectedNode.content.props);
				Structure = ctor.Inputs;
			}
			nodeProps = ModuleSystem.validateProps(selectedNode.ctor, selectedNode.props);
			nodeStructure = selectedNode.ctor.Inputs;
		} else {
			this.ContainerNode = null;
		}

		let StyleData = Object.keys(styles || {}).map((key,index) => 
			<option key={selectedNode.id + key}  value = {key} selected={this._selectedStyle === key}>
				{key}	
			</option>

		)
		let contentData = Object.keys(Structure || {}).map((key,index) => 
			<View key={selectedNode.id + key} style={{padding:8}}>
			{this.createHandler(Structure[key], viewNodeProps, key, (v, f) => 
				this.editNode(selectedNode.content, v,f))}
			</View>
		)
		let containerData =Object.keys(nodeStructure || {}).map((key, index) => 
			<View key={selectedNode.id + key} >
			{this.createHandler(nodeStructure[key], nodeProps, key, (v,f) => 
				this.editNode(selectedNode, v, f))}
			</View>
		);



		return (
  			<View>
  				{this.ContainerNode ? 
  				[
  				<Alignment key={'Alignment'} onSelect={(style) => this.editNodeStyle(selectedNode, style)} />,
  				<ContainerEditor key={'ContainerEditor'} structure={Structure} 
  					nodeProps={nodeProps} 
  					key={this.ContainerNode.id}
  					onChange={(k,v) => this.editNode(selectedNode, v, k)}/>,

  				<View style={PropertiesContainer.container} key={'ContentData'}>
  			 		{contentData}
  			 	</View>,

  				<View key={'ShowAll'}>
  					<Text style={SideBarStyle.title} onClick={() => this.toggleAll()}>Show All</Text>
  				</View>
  				]
  				: <Text style={{padding: 24}}>Click on elements</Text>}

  				{this.showAllData ?
  				<View>
  				{StyleData.length > 0 ? (
  				<View key={Math.random()}>
  					<select onChange={(event) => {
  						this._selectedStyle = event.target.value;
  						this.ContainerNode.content.props = {...this.ContainerNode.content.props, ...styles[event.target.value]};
  						this.forceUpdate();
  					}}>
  						{StyleData}
  					</select>
  				</View>):(null)}
  				<View>
  					{this.ContainerNode && <View key={this.ContainerNode.id}>
  						<Text>Container</Text>
  						<Button onPress={() => this.import()} title={'Import'}/>
  						<Button onPress={() => this.export()} title={'Export'}/>
  						
  						<Image  name='near me'
		  				style={{width: 20, height: 20}}
		  				source= {require('../assets/icon.png')}
		  				containerStyle={{}}
		  				onClick={() => this.removeNode(this.ContainerNode)}
		  				/>
  					</View>}
  					{containerData}
  				</View>


  				<View style={PropertiesContainer.container}>
  			 		{contentData}
  			 	</View>
  			 	</View>
  			 	: null}
  			 	
  			</View>
  			)
	}
}




const SelectedStyle = StyleSheet.create({
	container:{
		padding:5,
		borderWidth:2,
		borderColor:'green'
	}
})


const PropertiesContainer = StyleSheet.create({
	container:{
		marginTop:20,
		borderColor:'#D0D0D0'
	},
	child:{
		padding:10
	}
})

const SideBarStyle = StyleSheet.create({
	container:{
		padding:1,
		flex:1,
		flexDirection:'row',
	},
	title: {
		padding: 24,
		fontSize: 12,
		letterSpacing: 0.5,
		color: "#BFBFBF",
		opacity: 1,
		cursor: 'pointer'
	},
	body:{
		paddingLeft:5,
		paddingRight:5
	}
})