import React, {Component} from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import uuid from 'uuid'

import {SourceContext} from 'src/CheckSources'
import TemplateVariableTable from 'src/dashboards/components/template_variables/Table'

import {TEMPLATE_VARIABLE_TYPES} from 'src/dashboards/constants'

const TemplateVariableManager = ({
  onClose,
  onDelete,
  isEdited,
  templates,
  onAddVariable,
  onRunQuerySuccess,
  onRunQueryFailure,
  tempVarAlreadyExists,
  onSaveTemplatesSuccess,
  onEditTemplateVariables,
}) => (
  <div className="template-variable-manager">
    <div className="template-variable-manager--header">
      <div className="page-header__left">
        <h1 className="page-header__title">Template Variables</h1>
      </div>
      <div className="page-header__right">
        <button
          className="btn btn-primary btn-sm"
          type="button"
          onClick={onAddVariable}
        >
          Add Variable
        </button>
        <button
          className={classnames('btn btn-success btn-sm', {
            disabled: !isEdited,
          })}
          type="button"
          onClick={onEditTemplateVariables(templates, onSaveTemplatesSuccess)}
        >
          Save Changes
        </button>
        <span className="page-header__dismiss" onClick={onClose} />
      </div>
    </div>
    <div className="template-variable-manager--body">
      <SourceContext.Consumer>
        {source => (
          <TemplateVariableTable
            source={source}
            onDelete={onDelete}
            templates={templates}
            onRunQuerySuccess={onRunQuerySuccess}
            onRunQueryFailure={onRunQueryFailure}
            tempVarAlreadyExists={tempVarAlreadyExists}
          />
        )}
      </SourceContext.Consumer>
    </div>
  </div>
)

class TemplateVariableManagerWrapper extends Component {
  constructor(props) {
    super(props)

    this.state = {
      rows: this.props.templates,
      isEdited: false,
    }
  }

  onAddVariable = () => {
    const {rows} = this.state

    const newRow = {
      tempVar: '',
      values: [],
      id: uuid.v4(),
      type: 'csv',
      query: {
        influxql: '',
        db: '',
        // rp, TODO
        measurement: '',
        tagKey: '',
      },
      isNew: true,
    }

    const newRows = [newRow, ...rows]

    this.setState({rows: newRows})
  }

  onRunQuerySuccess = (template, queryConfig, parsedData, tempVar) => {
    const {rows} = this.state
    const {id, links} = template
    const {
      type,
      query: influxql,
      database: db,
      measurement,
      tagKey,
    } = queryConfig

    // Determine which is the selectedValue, if any
    const currentRow = rows.find(row => row.id === id)

    let selectedValue
    if (currentRow && currentRow.values && currentRow.values.length) {
      const matchedValue = currentRow.values.find(val => val.selected)
      if (matchedValue) {
        selectedValue = matchedValue.value
      }
    }

    if (
      !selectedValue &&
      currentRow &&
      currentRow.values &&
      currentRow.values.length
    ) {
      selectedValue = currentRow.values[0].value
    }

    if (!selectedValue) {
      selectedValue = parsedData[0]
    }

    const values = parsedData.map(value => ({
      value,
      type: TEMPLATE_VARIABLE_TYPES[type],
      selected: selectedValue === value,
    }))

    const templateVariable = {
      tempVar,
      values,
      id,
      type,
      query: {
        influxql,
        db,
        // rp, TODO
        measurement,
        tagKey,
      },
      links,
    }

    const newRows = rows.map(r => (r.id === template.id ? templateVariable : r))

    this.setState({rows: newRows, isEdited: true})
  }

  onSaveTemplatesSuccess = () => {
    const {rows} = this.state

    const newRows = rows.map(row => ({...row, isNew: false}))

    this.setState({rows: newRows, isEdited: false})
  }

  onDeleteTemplateVariable = templateID => {
    const {rows} = this.state

    const newRows = rows.filter(({id}) => id !== templateID)

    this.setState({rows: newRows, isEdited: true})
  }

  tempVarAlreadyExists = (testTempVar, testID) => {
    const {rows: tempVars} = this.state
    return tempVars.some(
      ({tempVar, id}) => tempVar === testTempVar && id !== testID
    )
  }

  handleDismissManager = () => {
    const {onDismissOverlay} = this.props
    const {isEdited} = this.state

    if (
      !isEdited ||
      (isEdited && confirm('Do you want to close without saving?')) // eslint-disable-line no-alert
    ) {
      onDismissOverlay()
    }
  }

  render() {
    const {rows, isEdited} = this.state
    return (
      <TemplateVariableManager
        {...this.props}
        onClose={this.handleDismissManager}
        onRunQuerySuccess={this.onRunQuerySuccess}
        onSaveTemplatesSuccess={this.onSaveTemplatesSuccess}
        onAddVariable={this.onAddVariable}
        templates={rows}
        isEdited={isEdited}
        onDelete={this.onDeleteTemplateVariable}
        tempVarAlreadyExists={this.tempVarAlreadyExists}
      />
    )
  }
}

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

TemplateVariableManager.propTypes = {
  ...TemplateVariableManagerWrapper.propTypes,
  onRunQuerySuccess: func.isRequired,
  onSaveTemplatesSuccess: func.isRequired,
  onAddVariable: func.isRequired,
  isEdited: bool.isRequired,
  onDelete: func.isRequired,
}

TemplateVariableManagerWrapper.propTypes = {
  onEditTemplateVariables: func.isRequired,
  templates: arrayOf(
    shape({
      type: string.isRequired,
      tempVar: string.isRequired,
      query: shape({
        db: string,
        influxql: string,
      }),
      values: arrayOf(
        shape({
          value: string.isRequired,
          type: string.isRequired,
          selected: bool.isRequired,
        })
      ).isRequired,
    })
  ),
  onRunQueryFailure: func.isRequired,
  onDismissOverlay: func,
}

export default TemplateVariableManagerWrapper

@@ -132,55 +132,8 @@
 d'%0A%0A
-import %7BSourceContext%7D from 'src/CheckSources'%0A
 impo
@@ -317,16 +317,26 @@
 er = (%7B%0A
+  source,%0A
   onClos
@@ -1383,64 +1383,8 @@
 y%22%3E%0A
-      %3CSourceContext.Consumer%3E%0A        %7Bsource =%3E (%0A    
     
@@ -1416,20 +1416,16 @@
         
-    
 source=%7B
@@ -1432,20 +1432,16 @@
 source%7D%0A
-    
         
@@ -1464,28 +1464,24 @@
 te%7D%0A        
-    
 templates=%7Bt
@@ -1490,20 +1490,16 @@
 plates%7D%0A
-    
         
@@ -1540,28 +1540,24 @@
 ss%7D%0A        
-    
 onRunQueryFa
@@ -1582,20 +1582,16 @@
 ailure%7D%0A
-    
         
@@ -1644,56 +1644,9 @@
     
-    /%3E%0A        )%7D%0A      %3C/SourceContext.Consumer
+/
 %3E%0A  
@@ -4575,16 +4575,69 @@
 .props%7D%0A
+        templates=%7Brows%7D%0A        isEdited=%7BisEdited%7D%0A
         
@@ -4831,61 +4831,8 @@
 le%7D%0A
-        templates=%7Brows%7D%0A        isEdited=%7BisEdited%7D%0A
     

Fix sources not being provided by props