import React from 'react'
import _ from 'lodash/fp'
// import {CheckBoxGroup, FlexWrapper, Text, CheckBox, RadioButtonGroup} from 'ui'

const FlexWrapper = ({children}) => (<div>{children}</div>)
const Text = ({children}) => (<div>{children}</div>)

const CheckBox = ({onChange, id, checked, disabled, label}) => {

  const onInputChange = (event) => {
    onChange(!checked)
  }
  return (
    <div>
      <input
        onChange={onInputChange}
        type="checkbox"
        id={id}
        checked={checked}
        disabled={disabled}
        />
      <label htmlFor={id}>
        {label}
      </label>
    </div>
  )
}

const CheckBoxGroup = ({items, title, bulkSave}) => {
  const allChecked = _.every((item) => item.checked)(items)
  const toggleAll = () => {
    const toSave = items.reduce((acc, {path}) => ({...acc, [path] : !allChecked}), {})
    bulkSave(toSave)
  }
  return (
    <div className={`check-group__list`}>
      {title}
      <CheckBox id="main" checked={allChecked} onChange={toggleAll}/>
      {items.map(({id, label, onChange, checked}) => (
        <CheckBox
          id={id}
          key={id}
          label={label}
          onChange={onChange}
          checked={checked}
          />
      ))}
    </div>
  )
}

const componentsMap = {
  'checkbox-group': ({values, save, modifier, bulkSave}) => {
    const items = modifier.children.map((child) => {
      const path = modifier.path + '.' + child.id
      const checked = values[path]
      return {...child, checked, onChange: save(path), path}
    })

    return <CheckBoxGroup id={modifier.id} items={items} title={modifier.title} bulkSave={bulkSave}/>
  },
  checkbox: ({values, save, modifier}) => (
    <FlexWrapper className="justify-between align-center">
      {modifier.style === 'toggle' && <Text>{modifier.label}</Text>}
      <CheckBox
        id={modifier.id}
        className={modifier.style}
        label={modifier.style === 'toggle' ? '' : modifier.label}
        onChange={save(modifier.path)}
        checked={values[modifier.path]}
      />
    </FlexWrapper>
  ),
  'radio-button-group': ({values, save, modifier}) => {
    const currentValue = values[modifier.path]
    const onChange = save(modifier.path)
    return (
      <div>
        <Text mixClassName="mb-8">{modifier.name}</Text>
        <fieldset>
          {modifier.children.map((child) => {
            const {id, label} = child
            const checked = id === currentValue
            const handleChange = () => onChange(id)
            return (
              <label id={id} key={id}>
                <input type="radio" name={modifier.path} onChange={handleChange} checked={checked} id={id}/>
                {label}
              </label>
            )
          })}
        </fieldset>
      </div>
    )
  },
  swap: ({values, save, modifier}) => {
    const {path} = modifier
    const value = values[path]
    const handleSwap = (event) => save(path)(!value)
    return <div onClick={handleSwap}>Swap elements</div>
  },
  separator: () => (
    <div className="py-24">
      <div className="separator" />
    </div>
  ),
}

export default class Modifiers extends React.Component {
  state = {}

  componentDidCatch(error) {
    this.setState({error})
  }

  toggleOverlay = () => this.setState(({overlay}) => ({overlay: !overlay}))

  saveModifier = (modifierKey) => (modifierValue) => {
    const {uiModifiers} = this.props
    const modifiers = {...uiModifiers, [modifierKey]: modifierValue}
    this.props.saveModifier(modifiers)
  }

  bulkSave = (toSave) => {
    const {uiModifiers} = this.props
    const modifiers = {...uiModifiers, ...toSave}
    this.props.saveModifier(modifiers)
  }

  getDefaultValues = _.flow(
    _.entries,
    _.reduce((acc, [modifierKey, value]) => {
      const {defaultValue, type} = value
      if (type === 'checkbox-group') {
        return defaultValue
      }
      return {...acc, [modifierKey]: defaultValue}
    }, {}),
  )

  getModifiers = () => {
    const {modifierScheme} = require('block').default
    const {uiModifiers} = this.props

    const defaultValues = this.getDefaultValues(modifierScheme)
    const values = {
      ...defaultValues,
      ...uiModifiers,
    }

    return _.flow(
      _.entries,
      _.map(([modifierKey, value]) => {
        let {type, label} = value
        if (type === 'hidden') {
          type = 'checkbox'
          label = label + '(*)'
        }
        const Component = componentsMap[type]
        const modifier = {path: modifierKey, ...value, label}
        return <Component modifier={modifier} save={this.saveModifier} bulkSave={this.bulkSave} values={values} key={modifierKey}/>
      }),
    )(modifierScheme)
  }

  getCodeBlock = () => {
    const {uiModifiers} = this.props
    const {modifierScheme} = require('block').default

    const defaultValues = this.getDefaultValues(modifierScheme)
    const diff = _.flow(
      _.entries,
      _.filter(([key, value]) => {
        if (key in defaultValues) {
          return defaultValues[key] !== value
        }
        return true
      }),
      _.fromPairs,
    )(uiModifiers)
    return (
      <pre style={{paddingTop: 30}}>
        {JSON.stringify(diff, null, 2)}
      </pre>
    )
  }

  render() {
    const {overlay, error} = this.state
    if (error) {
      console.log(error)
      return <div>error</div>
    }
    return (
      <div className="overlay overlay_right">
        <button className="button" onClick={this.toggleOverlay}>Modifiers</button>
        {overlay && (
          <div>
            {this.getModifiers()}
            {this.getCodeBlock()}
          </div>
        )}
      </div>
      )

  }
}
