import { connect } from 'react-redux'
import ServiceGraph from 'components/ServiceGraph'
import { TableValueType } from 'components/NestedTable/data/TableValue'
import { DEFAULT_REDUCER_KEY } from 'modules/metrics_data/actions'

const graphLineColors = [
  'rgba(107,76,154,1)',
  'rgba(57,106,177,1)',
  'rgba(218,124,48,1)',
  'rgba(62,150,81,1)',
  'rgba(204,37,41,1)',
  'rgba(83,81,84,1)',
  'rgba(146,36,40,1)',
  'rgba(148,139,61,1)'
]

const mapStateToProps = (state, ownProps) => {
  let reducerKey = ownProps.reducerKey
  if (reducerKey === undefined) {
    reducerKey = DEFAULT_REDUCER_KEY
  }

  let loading = state[reducerKey].loading
  let showControls = ownProps.showControls
  let curRangeEnd = state[reducerKey].curRangeEnd
  let curBucketType = state[reducerKey].curBucketType
  let curMetricIds = state[reducerKey].curMetricIds

  let graphLabels = []
  let graphData = []
  let graphOptions = ownProps.options
  let validMetricIds = []
  let graphMetricIds = curMetricIds.slice(0)

  if (!loading) {
    let valueType = TableValueType.UNKNOWN
    let valueUnit = ''

    // We need to figure out what metrics are actually graphable based on their metric type.
    state.api_data.metricIds.forEach((metricId, idx) => {
      const metric = state.api_data.metrics[metricId]
      if (metric.type === TableValueType.NUMBER) {
        validMetricIds.push(metricId)
      } else {
        const idxOfMetricId = graphMetricIds.indexOf(metricId)
        if (idxOfMetricId >= 0) {
          graphMetricIds.splice(idxOfMetricId, 1)
        }
      }
    })

    // Initialize our mapping of values for each label in our graph.
    let metricValuesForLabels = {}
    graphMetricIds.forEach((metricId) => {
      metricValuesForLabels[metricId] = []
    })

    // Iterate through our buckets to get our list of graphLabels and the values for each metric at that label.
    const rangeData = state.api_data.ranges[state.user_session.startTime][curRangeEnd]
    const bucketIds = rangeData[curBucketType].buckets
    for (let bucketId of bucketIds) {
      let bucket = state.api_data.buckets[bucketId]
      const serviceValues = bucket.values[ownProps.serviceId]
      // If we couldn't find our service then there won't be any values for this label.
      if (serviceValues === undefined) {
        continue
      }
      // Otherwise let's add this bucket as a label.
      graphLabels.push(bucket.shortName)
      // Let's also grab the values for our metrics at this label.
      graphMetricIds.forEach((metricId) => {
        let value = serviceValues[metricId]
        if (value !== undefined) {
          valueType = value.type
          valueUnit = value.unit
          value = value.value
          if (valueType === TableValueType.NUMBER && valueUnit === '%') {
            value *= 100
          }
        }
        metricValuesForLabels[metricId].push(value)
      })
    }

    // Always make sure the legend is off, because something else controls this getting rendered.
    if (graphOptions === undefined) {
      graphOptions = {}
    }
    if (graphOptions.legend === undefined) {
      graphOptions.legend = {}
    }
    if (graphOptions.legend.display === undefined) {
      graphOptions.legend.display = false
    }

    // // Adjust our graphOptions to fix the scale if need be based on our value's unit and type.
    // if (valueType === TableValueType.NUMBER && valueUnit === '%') {
    //   if (graphOptions === undefined) {
    //     graphOptions = {}
    //   }
    //   if (graphOptions.scales === undefined) {
    //     graphOptions.scales = {}
    //   }
    //   if (graphOptions.scales.yAxes === undefined) {
    //     graphOptions.scales.yAxes = []
    //   }
    //   if (graphOptions.scales.yAxes[0] === undefined) {
    //     graphOptions.scales.yAxes.push({})
    //   }
    //   if (graphOptions.scales.yAxes[0].ticks === undefined) {
    //     graphOptions.scales.yAxes[0].ticks = {}
    //   }
    //   graphOptions.scales.yAxes[0].ticks.max = 100
    //   graphOptions.scales.yAxes[0].ticks.min = 0
    //   graphOptions.scales.yAxes[0].ticks.beginAtZero = true
    // }

    // Now we need ot build or graphData for each of our metricValuesForLabels.
    graphMetricIds.forEach((metricId, idx) => {
      const values = metricValuesForLabels[metricId]
      const metric = state.api_data.metrics[metricId]
      const dataset = {
        label: metric.name,
        fill: false,
        lineTension: 0,
        backgroundColor: graphLineColors[idx],
        borderColor: graphLineColors[idx],
        borderCapStyle: 'butt',
        borderDash: [],
        borderDashOffset: 0.0,
        borderJoinStyle: 'miter',
        pointBorderColor: graphLineColors[idx],
        pointBackgroundColor: '#fff',
        pointBorderWidth: 1,
        pointHoverRadius: 5,
        pointHoverBackgroundColor: graphLineColors[idx],
        pointHoverBorderColor: 'rgba(220,220,220,1)',
        pointHoverBorderWidth: 2,
        pointRadius: 1,
        pointHitRadius: 10,
        data: values
      }
      graphData.push(dataset)
    })
  }
  return {
    loading,
    reducerKey,
    showControls,
    validMetricIds: validMetricIds,
    graphLabels: graphLabels,
    graphData: graphData,
    graphHeight: ownProps.height,
    graphOptions: graphOptions,
    graphMetricIds: graphMetricIds,
    metrics: state.api_data.metrics,
    urlStr: ownProps.urlStr
  }
}

export default connect(mapStateToProps)(ServiceGraph)
