import React from 'react';
import { withContentRect } from 'react-measure'
import { filter, range, map, pipe } from 'rambda';
import { ScatterChart, Scatter, XAxis, YAxis, CartesianGrid, Brush, Label } from 'recharts';
import Job from './Job';
import { maxTime, minTime } from '../ganttUtils';
import theme from '../theme';

class Gannt extends React.PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      startTime: minTime(props.data),
      endTime: maxTime(props.data)
    };
  }

  render() {
    const { data, measureRef, contentRect: { bounds: dimensions } } = this.props;
    const { startTime } = this.state;
    const endTime = this.state.endTime === startTime ? startTime + 1 : this.state.endTime;

    const scopeData = map(processorData =>
      pipe(
        filter(datum =>
          (datum.startTime >= startTime
            || (datum.startTime < startTime && datum.endTime >= startTime)
          )
          && datum.startTime <= endTime
        ),
        map(datum => {
          let newDatum = datum;
          if (newDatum.startTime < startTime) {
            newDatum = { ...newDatum, startTime, formerStartTime: newDatum.startTime };
          }

          if (newDatum.endTime > endTime) {
            newDatum = { ...newDatum, endTime, formerEndTime: newDatum.endTime };
          }

          return newDatum;
        })
      )(processorData),
      data
    );

    const processors = range(1, data.length + 1);

    const scopeMinTime = minTime(scopeData);
    const scopeMaxTime = maxTime(scopeData);
    const ticksCountX = scopeMinTime + scopeMaxTime;

    const width = Math.max(theme.gantt.maxWidth, dimensions.width);
    const height = 100 + 1.75 * theme.gantt.job.height * processors.length;

    const horizontalGuideLines = map(
      i => theme.gantt.margin.top + i * 1.75 * theme.gantt.job.height - i * 10,
      range(0, processors.length)
    );

    return (
      <div ref={measureRef}>
        <h1>Ganttov diagram</h1>

        <ScatterChart width={width} height={height} data={data[0]} margin={theme.gantt.margin}>
          <CartesianGrid
            stroke={theme.gantt.grid.stroke}
            strokeDasharray="5 5"
            horizontalPoints={horizontalGuideLines}
          />
          <XAxis
            type="number"
            dataKey="startTime"
            interval={0}
            domain={[scopeMinTime, scopeMaxTime]}
            tickCount={ticksCountX}
            allowDecimals={false}
          >
            <Label offset={-30} position="insideBottom">Čas</Label>
          </XAxis>
          <YAxis
            type="number"
            dataKey="processor"
            interval={0}
            name="processor"
            allowDecimals={false}
            domain={[0.5, processors.length + 0.5]}
            ticks={processors}
          >
            <Label position="insideLeft" angle={-90}>Pracovníci</Label>
          </YAxis>
          <Brush
            dataKey="startTime"
            y={height - theme.gantt.brush.height - 10}
            height={theme.gantt.brush.height}
            stroke={theme.gantt.brush.stroke}
            onChange={({ startIndex, endIndex }) =>
              this.setState({ startTime: startIndex + 1, endTime: endIndex + 1 })
            }
          />
          {scopeData.map((processorData, i) => (
            <Scatter key={i} data={processorData} shape={<Job />} />
          ))}
        </ScatterChart>
      </div>
    );
  }
}

export default withContentRect('bounds')(Gannt);