const rce = React.createElement

function callApi (msg) {
  fetch('./' + msg.join('/')) // TODO: what about the timeout?
}

// TODO: cut-n-pasted from script.js - unite
// hyperscript helper - stupid version
// TODO: add support for id (div.class#id)
// TODO: add support for component (non-string) as first arg
const h = (tag, props, children) => {
  if (tag.indexOf('.') < 0) { // TODO: does this really make it faster?
    return rce(tag || 'div', props, React.Children.toArray(children))
  }
  const parts = tag.split('.')
  const tag_ = parts[0]
  const classes = parts.slice(1)
  const props_ = props || {}
  if (classes) {
    props_.className = (props_.className ? props_.className + ' ' : '') + classes.join(' ')
  }
  return rce(tag_ || 'div', props_, React.Children.toArray(children))
}

const expandAll = () => {
	const details = document.querySelectorAll("details");
	details.forEach((detail) => {detail.setAttribute("open", "true")})
}

const collapseAll = () => {
	const details = document.querySelectorAll("details");
	details.forEach((detail) => {detail.removeAttribute("open")})
}

class ExpandAllButton extends React.Component {
	render() {
		return h('button', { onClick: _e => expandAll() }, 'expand all');
	}
};

class CollapseAllButton extends React.Component {
	render() {
		return h('button', { onClick: _e => collapseAll()}, 'collapse all');
	}
};

class Main extends React.Component {
	render() {
		const keys = Object.keys(this.props.nodes).sort();
		let nodes = [];
		for (let k of keys) {
			const v = this.props.nodes[k];
			//console.log(v);
			if (v._type == 'Blind') {
				nodes.push(rce(Blind, {url: '/' + k, key: k, k, data: v}));
			} else if (v._type == 'Bulb') {
				nodes.push(rce(Bulb, {url: '/' + k, key: k, k, data: v}));
			} else {
				nodes.push(rce(Node, {url: '/' + k, key: k, k, data: v}));
			}
		}
		return h('', {}, [
			h('h1', {}, 'control'),
			rce(ExpandAllButton),
			rce(CollapseAllButton),
			h('.main', {}, nodes)
		])
	}
};

class Node extends React.Component {
	render() {
		const info_str = JSON.stringify(this.props.data, null, 2);
		let overrides = [];
		for (const k in this.props.data['_overrides']) {
			const v = this.props.data['_overrides'][k];
			overrides.push(h('', {key: this.props.url + '/override/' + k}, [
				k,
				':',
				JSON.stringify(v, null, 2),
				//h('input', { - TODO: does not work - wtf? WHY?
				rce('input', {
					size: 1,
					onKeyDown: e => {
						if (e.which != 13) return;
						const val = e.target.value;
						callApi([this.props.k, 'set_override', k, val]);
					}
				})
			]));
		}
		let messages = [];
		for (const k in this.props.data['_messages']) {
			const v = this.props.data['_messages'][k];
			let buts = [];
			if (v.options) {
				for (let i of v['options']) {
					buts.push(h('button', {
						key: this.props.url + '/message/' + k + '/' + i.id,
						onClick: _e => callApi([this.props.k, 'set_message_answer', k, i.id])
					}, i.text))
				}
			}
			messages.push(h('', {key: this.props.url + '/message'/ + k}, [
				k,
				':',
				v.text,
				buts
			]));
		}
		return h('.node', {}, [
			this.props.url,
			':',
			h('details', {}, [
				h('summary', {}, '...'),
				h('pre', {}, info_str),
				h('.overrides', {}, overrides),
				h('.messages', {}, messages),
			])
		])
	}
};

class Blind extends React.Component {
	on_click(e) {
		const k = this.props.k;
		console.log('on_click', k);
		const name = e.target.getAttribute('data-action-name');
		callApi([k, name]);
	}

	render() {
		const info_str = JSON.stringify(this.props.data, null, 2);
		return h('.node', {}, [
			this.props.url,
			':',
			h('pre', { style: {display: "none"} }, info_str),
			h('img', {
				src: "./static/blind_open.png",
				width: 64,
				onClick: _e => callApi([this.props.k, 'go_up'])
			}),
			h('img', {
				src: "./static/blind_semi.png",
				width: 64,
				onClick: _e => callApi([this.props.k, 'go_down_and_open'])
			}),
			h('img', {
				src: "./static/blind_closed.png",
				width: 64,
				onClick: _e => callApi([this.props.k, 'go_down'])
			}),
			h('img', {
				src: "./static/stop.png",
				width: 64,
				onClick: _e => callApi([this.props.k, 'stop'])
			})
		])
	}
};

class Bulb extends React.Component {
	on_click(e) {
		const k = this.props.k;
		console.log('on_click', k);
		const name = e.target.getAttribute('data-action-name');
		callApi([k, name]);
	}

	render() {
		const info_str = JSON.stringify(this.props.data, null, 2);
		const on_off = this.props.data['is_on'];
		const img_src = "./static/bulb_" + (on_off ? "on" : "off") + ".png";
		return h('.node', {}, [
			this.props.url,
			':',
			h('pre', {style: {display: "none"}}, info_str),
			h('img', {
				src: img_src,
				width: 64,
				onClick: _e => callApi([this.props.k, 'toggle'])
			})
		])
	}
};

//ReactDOM.render(<Main />, document.getElementById('content'));

var source = new EventSource('/stream_full');
source.onmessage = e => {
	const data = JSON.parse(e.data);
	ReactDOM.render(rce(Main, {nodes: data}), document.getElementById('content'));
};
