import React from 'react';
import { Svg, G } from 'react-native-svg';
import * as d3 from 'd3';
import { Line } from './line';
import { YAxis } from './y-axis';
import { XAxis } from './x-axis';
import { SBox } from '../../common/s-components/layout/s-box';
import { fp as _ } from '../../common/utils/fp';
import { XAxisLabels } from './x-axis-labels';
import { YAxisLabels } from './y-axis-labels';
import { getWinWidth } from '../transducers';
import { theme } from '../../app/theme';
import { TCoordinates, TGraphMaxes } from '../../common/types';
import { useNanoId } from '../../common/hooks/use-nano';

type TProps = {
  result: string[];
  xTicks: number[];
  yTicks: number[];
  entities: Record<string, TCoordinates>;
  maxes: TGraphMaxes;
  variant?: string;
};

export const LatencyGraph: React.FC<TProps> = props => {
  let {
    maxes: { xMin, xMax, yMax },
    xTicks,
    yTicks,
    result,
    entities,
    variant,
  } = props;
  const lineId = useNanoId();

  const getSizes = () => {
    const width = getWinWidth();
    const padding = 4;
    const paddingLine = 6;
    const containerHeight = 140;
    const paddingTop = 22;
    const paddingBottom = 24;
    const height = 142;
    const innerWidth = width;
    const innerHeight = height - paddingBottom;

    return {
      containerHeight,
      height,
      width,
      padding,
      paddingLine,
      paddingTop,
      paddingBottom,
      innerHeight,
      innerWidth,
    };
  };

  const getScales = () => {
    const {
      innerWidth,
      padding,
      paddingLine,
      paddingTop,
      innerHeight,
    } = getSizes();

    const xScale = d3
      .scaleLinear()
      .domain([xMin, xMax])
      .range([38, innerWidth - padding]);
    const xScaleLine = d3
      .scaleLinear()
      .domain([xMin, xMax])
      .range([40, innerWidth - paddingLine]);
    const yScale = d3
      .scaleLinear()
      .domain([0, yMax])
      .range([innerHeight, paddingTop]);

    return { xScale, yScale, xScaleLine };
  };

  const {
    containerHeight,
    height,
    innerWidth,
    innerHeight,
    paddingLine,
  } = getSizes();
  const { xScale, xScaleLine, yScale } = getScales();
  const hideGraph = _.any(_.isNil)([yMax, xMax, xMin]);

  return (
    <SBox ml={16} position="relative" height={containerHeight}>
      <XAxisLabels
        ticks={xTicks}
        scale={xScale}
        yOffset={innerHeight - 2}
        color={theme.colors.eastBay}
        ticksVariant="edge"
      />
      <YAxisLabels
        ticks={yTicks}
        scale={yScale}
        offsetLeft={22}
        offsetTop={18}
        axisExclusion
        icons={result}
        variant="latency"
      />
      <Svg height={height} width={innerWidth}>
        {!hideGraph ? (
          <>
            <YAxis
              ticks={yTicks}
              scale={yScale}
              xOffsetRight={innerWidth - paddingLine}
              xOffset={40}
              variant="latency"
              strokeWidth={4}
            />
            <XAxis
              ticks={xTicks}
              scale={xScale}
              yOffset={innerHeight - 2}
              color={theme.colors.snuff}
              ticksVariant="edge"
            />
            <G transform="translate(0, 0)">
              {result.map(vendor => {
                return (
                  <Line
                    key={`${lineId}${vendor}`}
                    graphMax={xMax}
                    graphMin={xMin}
                    variant={variant}
                    data={entities[vendor]}
                    xScale={xScaleLine}
                    yScale={yScale}
                    strokeWidth={4}
                    gradientHorizontal
                  />
                );
              })}
            </G>
          </>
        ) : null}
      </Svg>
    </SBox>
  );
};

LatencyGraph.defaultProps = {
  variant: 'variant2',
};
