import React from 'react';
import * as d3 from 'd3';
import { G, Path, Defs, LinearGradient, Stop } from 'react-native-svg';
import { ScaleLinear } from 'd3';
import { fp as _ } from '../../common/utils/fp';
import { getGradientEdges } from '../transducers';
import { AngleGradient } from '../../common/components/angle-gradient';
import { TCoordinates } from '../../common/types';
import { useNanoId } from '../../common/hooks/use-nano';

type TProps = {
  xScale?: ScaleLinear<number, number>;
  yScale?: ScaleLinear<number, number>;
  graphMax?: number;
  graphMin?: number;
  data?: TCoordinates;
  path?: string;
  variant?: string;
  color?: string;
  strokeWidth?: number;
  gradientHorizontal?: boolean;
  // testID?: string;
};

export const Line: React.FC<TProps> = props => {
  const id = useNanoId();

  const {
    color,
    data,
    xScale,
    yScale,
    path,
    graphMax,
    graphMin,
    variant,
    gradientHorizontal,
    strokeWidth,
  } = props;
  let line: string;
  const gradientId = `grad-area-${id}`;
  let start;
  let end;

  if (!path && data) {
    // styles of curves
    // https://bl.ocks.org/d3noob/ced1b9b18bd8192d2c898884033b5529
    line = d3
      .line<any>()
      .defined(_.isNotNil)
      // .curve(d3.curveCatmullRom)
      .curve(d3.curveMonotoneX)
      // .x((d, i) => x(d.x))
      .x(d => xScale!(d.x)!)
      .y(d => yScale!(d.y)!)(data)!;
  }

  if (data) {
    const edges = getGradientEdges({
      variant: variant!,
      graphMax: graphMax!,
      data,
      graphMin,
      axis: gradientHorizontal ? 'x' : 'y',
    });
    start = edges.start;
    end = edges.end;
  }
  // @ts-ignore
  const d = path || line;

  return (
    <G>
      <Defs>
        <AngleGradient angle={gradientHorizontal ? 0 : 90}>
          <LinearGradient id={gradientId}>
            <Stop
              offset="0%"
              stopColor={gradientHorizontal ? start : end}
              // stopOpacity={0.5}
            />
            <Stop
              offset="100%"
              stopColor={gradientHorizontal ? end : start}
              // stopOpacity={1}
            />
          </LinearGradient>
        </AngleGradient>
      </Defs>

      <G>
        {d ? (
          <Path
            d={d}
            fill="none"
            // stroke={color}
            stroke={start ? `url(#${gradientId})` : color}
            strokeLinejoin="round"
            strokeLinecap="round"
            strokeWidth={strokeWidth || 2}
          />
        ) : null}
      </G>
    </G>
  );
};

Line.defaultProps = {
  graphMax: 0,
};
