// 'use strict'
/* global React, ReactDOM */

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()
    const nodes = []
    for (const 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 infoStr = JSON.stringify(this.props.data, null, 2)
    const 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])
          }
        })
      ]))
    }
    const messages = []
    for (const k in this.props.data._messages) {
      const v = this.props.data._messages[k]
      const buts = []
      if (v.options) {
        for (const 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', {}, infoStr),
        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 infoStr = JSON.stringify(this.props.data, null, 2)
    return h('.node', {}, [
      this.props.url,
      ':',
      h('pre', { style: { display: 'none' } }, infoStr),
      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 infoStr = JSON.stringify(this.props.data, null, 2)
    const onOff = this.props.data.is_on
    const imgSrc = './static/bulb_' + (onOff ? 'on' : 'off') + '.png'
    return h('.node', {}, [
      this.props.url,
      ':',
      h('pre', { style: { display: 'none' } }, infoStr),
      h('img', {
        src: imgSrc,
        width: 64,
        onClick: _e => callApi([this.props.k, 'toggle'])
      })
    ])
  }
};

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

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