import { ResponsiveLine } from '@nivo/line'
import { PortfolioMetrics } from 'common/user'
import { formatMoney } from 'common/util/format'
import dayjs from 'dayjs'
import { last, set } from 'lodash'
import { memo } from 'react'
import { useWindowSize } from 'web/hooks/use-window-size'
import { Col } from '../layout/col'

export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: {
  portfolioHistory: PortfolioMetrics[]
  mode: 'value' | 'profit'
  setGraphDisplayNumber: (arg0: number | string | null) => void
  height?: number
  includeTime?: boolean
}) {
  const { portfolioHistory, height, includeTime, mode, setGraphDisplayNumber } =
    props
  const { width } = useWindowSize()

  function getPoints(line: 'value' | 'posProfit' | 'negProfit') {
    let points = portfolioHistory.map((p) => {
      const { timestamp, balance, investmentValue, totalDeposits } = p
      const value = balance + investmentValue

      const profit = value - totalDeposits
      let posProfit = null
      let negProfit = null
      if (profit < 0) {
        negProfit = profit
      } else {
        posProfit = profit
      }

      return {
        x: new Date(timestamp),
        y:
          line === 'value'
            ? value
            : line === 'posProfit'
            ? posProfit
            : negProfit,
      }
    })
    return points
  }

  let data

  if (mode === 'value') {
    data = [{ id: 'value', data: getPoints('value'), color: '#4f46e5' }]
  } else {
    data = [
      {
        id: 'negProfit',
        data: getPoints('negProfit'),
        color: '#dc2626',
      },
      {
        id: 'posProfit',
        data: getPoints('posProfit'),
        color: '#14b8a6',
      },
    ]
  }
  let firstPoints = data[0].data
  const numYTickValues = 2
  const endDate = last(data[0].data)?.x

  const firstPointsY = firstPoints
    .map((p) => p.y)
    .filter((y) => {
      return y !== null
    })

  const yMin =
    mode === 'value'
      ? Math.min(...firstPointsY)
      : Math.min(
          ...firstPointsY,
          ...data[1].data
            .filter((p) => {
              return p.y !== null
            })
            .map((p) => p.y)
        )

  const yMax =
    mode === 'value'
      ? Math.max(...firstPointsY)
      : Math.max(
          ...firstPointsY,
          ...data[1].data
            .filter((p) => {
              return p.y !== null
            })
            .map((p) => p.y)
        )

  return (
    <div
      className="w-full overflow-hidden"
      style={{ height: height ?? (!width || width >= 800 ? 200 : 100) }}
      onMouseLeave={() => setGraphDisplayNumber(null)}
    >
      <ResponsiveLine
        margin={{ top: 10, right: 0, left: 40, bottom: 10 }}
        data={data}
        xScale={{
          type: 'time',
          min: firstPoints[0]?.x,
          max: endDate,
        }}
        yScale={{
          type: 'linear',
          stacked: false,
          min: yMin,
          max: yMax,
        }}
        curve="stepAfter"
        enablePoints={false}
        colors={{ datum: 'color' }}
        axisBottom={{
          tickValues: 0,
        }}
        pointBorderColor="#fff"
        pointSize={firstPoints.length > 100 ? 0 : 6}
        axisLeft={{
          tickValues: numYTickValues,
          format: '.3s',
        }}
        enableGridX={false}
        enableGridY={true}
        gridYValues={numYTickValues}
        enableSlices="x"
        animate={false}
        yFormat={(value) => formatMoney(+value)}
        enableArea={true}
        areaOpacity={0.1}
        sliceTooltip={({ slice }) => {
          slice.points.map((point) =>
            setGraphDisplayNumber(point.data.yFormatted)
          )
          return (
            <div className="rounded bg-white px-4 py-2 opacity-80">
              {slice.points.map((point) => (
                <div
                  key={point.id}
                  className="text-xs font-semibold sm:text-sm"
                >
                  <Col>
                    <div>{dayjs(point.data.xFormatted).format('MMM/D/YY')}</div>
                    <div className="text-greyscale-6 text-2xs font-normal sm:text-xs">
                      {dayjs(point.data.xFormatted).format('h:mm A')}
                    </div>
                  </Col>
                </div>
              ))}
            </div>
          )
        }}
      ></ResponsiveLine>
    </div>
  )
})
