import React, {PropTypes, Component} from 'react'
import onClickOutside from 'react-onclickoutside'

import {formatRPDuration} from 'utils/formatting'
import YesNoButtons from 'shared/components/YesNoButtons'
import {DATABASE_TABLE} from 'src/admin/constants/tableSizing'

class DatabaseRow extends Component {
  constructor(props) {
    super(props)
    this.state = {
      isEditing: false,
      isDeleting: false,
    }
    this.handleKeyDown = ::this.handleKeyDown
    this.handleClickOutside = ::this.handleClickOutside
    this.handleStartEdit = ::this.handleStartEdit
    this.handleEndEdit = ::this.handleEndEdit
    this.handleCreate = ::this.handleCreate
    this.handleUpdate = ::this.handleUpdate
    this.getInputValues = ::this.getInputValues
    this.handleStartDelete = ::this.handleStartDelete
    this.handleEndDelete = ::this.handleEndDelete
  }

  componentWillMount() {
    if (this.props.retentionPolicy.isNew) {
      this.setState({isEditing: true})
    }
  }

  render() {
    const {
      onRemove,
      retentionPolicy: {name, duration, replication, isDefault, isNew},
      retentionPolicy,
      database,
      onDelete,
      isDeletable,
      isRFDisplayed,
    } = this.props
    const {isEditing, isDeleting} = this.state

    const formattedDuration = formatRPDuration(duration)

    if (isEditing) {
      return (
        <tr>
          <td>
            {isNew
              ? <input
                  className="form-control input-xs"
                  type="text"
                  defaultValue={name}
                  placeholder="Name this RP"
                  onKeyDown={e => this.handleKeyDown(e, database)}
                  ref={r => (this.name = r)}
                  autoFocus={true}
                  spellCheck={false}
                  autoComplete={false}
                />
              : name}
          </td>
          <td style={{width: `${DATABASE_TABLE.colDuration}px`}}>
            <input
              className="form-control input-xs"
              name="name"
              type="text"
              defaultValue={formattedDuration}
              placeholder="How long should Data last"
              onKeyDown={e => this.handleKeyDown(e, database)}
              ref={r => (this.duration = r)}
              autoFocus={!isNew}
              spellCheck={false}
              autoComplete={false}
            />
          </td>
          {isRFDisplayed
            ? <td style={{width: `${DATABASE_TABLE.colReplication}px`}}>
                <input
                  className="form-control input-xs"
                  name="name"
                  type="number"
                  min="1"
                  defaultValue={replication || 1}
                  placeholder="# of Nodes"
                  onKeyDown={e => this.handleKeyDown(e, database)}
                  ref={r => (this.replication = r)}
                  spellCheck={false}
                  autoComplete={false}
                />
              </td>
            : null}
          <td
            className="text-right"
            style={{width: `${DATABASE_TABLE.colDelete}px`}}
          >
            <YesNoButtons
              buttonSize="btn-xs"
              onConfirm={isNew ? this.handleCreate : this.handleUpdate}
              onCancel={
                isNew
                  ? () => onRemove(database, retentionPolicy)
                  : this.handleEndEdit
              }
            />
          </td>
        </tr>
      )
    }

    return (
      <tr>
        <td>
          {`${name} `}
          {isDefault
            ? <span className="default-source-label">default</span>
            : null}
        </td>
        <td
          onClick={this.handleStartEdit}
          style={{width: `${DATABASE_TABLE.colDuration}px`}}
        >
          {formattedDuration}
        </td>
        {isRFDisplayed
          ? <td
              onClick={this.handleStartEdit}
              style={{width: `${DATABASE_TABLE.colReplication}px`}}
            >
              {replication}
            </td>
          : null}
        <td
          className="text-right"
          style={{width: `${DATABASE_TABLE.colDelete}px`}}
        >
          {isDeleting
            ? <YesNoButtons
                onConfirm={() => onDelete(database, retentionPolicy)}
                onCancel={this.handleEndDelete}
                buttonSize="btn-xs"
              />
            : <button
                className="btn btn-danger btn-xs table--show-on-row-hover"
                style={isDeletable ? {} : {visibility: 'hidden'}}
                onClick={this.handleStartDelete}
              >
                {`Delete ${name}`}
              </button>}
        </td>
      </tr>
    )
  }

  handleClickOutside() {
    const {database, retentionPolicy, onRemove} = this.props
    if (retentionPolicy.isNew) {
      onRemove(database, retentionPolicy)
    }

    this.handleEndEdit()
    this.handleEndDelete()
  }

  handleStartEdit() {
    this.setState({isEditing: true})
  }

  handleEndEdit() {
    this.setState({isEditing: false})
  }

  handleStartDelete() {
    this.setState({isDeleting: true})
  }

  handleEndDelete() {
    this.setState({isDeleting: false})
  }

  handleCreate() {
    const {database, retentionPolicy, onCreate} = this.props
    const validInputs = this.getInputValues()
    if (!validInputs) {
      return
    }

    onCreate(database, {...retentionPolicy, ...validInputs})
    this.handleEndEdit()
  }

  handleUpdate() {
    const {database, retentionPolicy, onUpdate} = this.props
    const validInputs = this.getInputValues()
    if (!validInputs) {
      return
    }

    onUpdate(database, retentionPolicy, validInputs)
    this.handleEndEdit()
  }

  handleKeyDown(e) {
    const {key} = e
    const {retentionPolicy, database, onRemove} = this.props

    if (key === 'Escape') {
      if (retentionPolicy.isNew) {
        onRemove(database, retentionPolicy)
        return
      }

      this.handleEndEdit()
    }

    if (key === 'Enter') {
      if (retentionPolicy.isNew) {
        this.handleCreate()
        return
      }

      this.handleUpdate()
    }
  }

  getInputValues() {
    const {notify, retentionPolicy: {name: currentName}} = this.props
    const name = (this.name && this.name.value.trim()) || currentName
    let duration = this.duration.value.trim()
    const replication = +this.replication.value.trim()

    if (!duration || !replication) {
      notify('error', 'Fields cannot be empty')
      return
    }

    if (duration === '∞') {
      duration = 'INF'
    }

    return {
      name,
      duration,
      replication,
    }
  }
}

const {bool, func, number, shape, string} = PropTypes

DatabaseRow.propTypes = {
  retentionPolicy: shape({
    name: string,
    duration: string,
    replication: number,
    isDefault: bool,
    isEditing: bool,
  }),
  isDeletable: bool,
  database: shape(),
  onRemove: func,
  onCreate: func,
  onUpdate: func,
  onDelete: func,
  notify: func,
  isRFDisplayed: bool,
}

export default onClickOutside(DatabaseRow)

@@ -6171,15 +6171,28 @@
 st %7B
+%0A      
 notify,
+%0A     
  ret
@@ -6224,16 +6224,43 @@
 entName%7D
+,%0A      isRFDisplayed,%0A    
 %7D = this
@@ -6258,32 +6258,33 @@
  %7D = this.props%0A
+%0A
     const name =
@@ -6383,16 +6383,75 @@
 .trim()%0A
+    // Replication %3E 1 is only valid for Influx Enterprise%0A
     cons
@@ -6465,16 +6465,32 @@
 cation =
+ isRFDisplayed ?
  +this.r
@@ -6512,16 +6512,20 @@
 e.trim()
+ : 1
 %0A%0A    if
@@ -6538,16 +6538,34 @@
 ation %7C%7C
+ (isRFDisplayed &&
  !replic
@@ -6570,16 +6570,17 @@
 ication)
+)
  %7B%0A     

Fix RP duration editing on admin page