import { ScaleLinear } from 'd3-scale'
import * as shape from 'd3-shape'
import { isInteger } from 'lodash'
import React from 'react'
import { Path } from 'react-native-svg'

interface DataPoint {
  x: number
  y: number | null
}

export type Curve = shape.CurveFactory | shape.CurveFactoryLineOnly

const getLine = (
  yValues: (number | null)[],
  scaleX: ScaleLinear<number, number>,
  scaleY: ScaleLinear<number, number>,
  curve: Curve
): string | null =>
  shape
    .line<DataPoint>()
    .x((p) => scaleX(p.x) ?? 0)
    .y((p) => (p.y != null ? scaleY(p.y) : 0) ?? 0)
    .defined((p) => isInteger(p.y))
    .curve(curve)(yValues.map((y, x) => ({ y, x })))

export function LinePlot<T>({
  strokeColor,
  strokeWidth,
  data,
  scaleX,
  scaleY,
  valueExtractor,
  curve,
}: {
  strokeColor: string
  strokeWidth: number
  data: T[]
  scaleX: ScaleLinear<number, number>
  scaleY: ScaleLinear<number, number>
  valueExtractor: (v: T) => number | null
  curve: Curve
}): React.ReactElement | null {
  const d = getLine(data.map(valueExtractor), scaleX, scaleY, curve)

  return d != null ? (
    <Path
      d={d}
      fill="transparent"
      stroke={strokeColor}
      strokeWidth={strokeWidth}
      strokeLinecap="round"
    />
  ) : null
}
