import React, { useState } from 'react';
import {
  Line,
  XAxis,
  YAxis,
  Tooltip,
  LineChart,
  ResponsiveContainer,
  ReferenceDot,
} from 'recharts';
import format from 'date-fns/format';
import Numeral from 'numeral';
import { dateToTimestamp } from 'data/lib/time';

const toK = (num: number | string) => Numeral(num).format('0.[00]a');

const formattedNum = (number: number | string) => {
  // @ts-ignore
  if (isNaN(number) || number === '' || number === undefined) {
    return '$0';
  }
  // @ts-ignore
  const num = parseFloat(number);

  if (num > 500000000) {
    return '$' + toK(num.toFixed(0));
  }

  if (num === 0) {
    return '$0';
  }

  if (num < 0.0001 && num > 0) {
    return '< $0.0001';
  }

  if (num > 1000) {
    return '$' + Number(num.toFixed(0)).toLocaleString();
  }

  return '$' + Number(num.toFixed(0)).toLocaleString();
};

const toNiceDate = (date: string) => format(new Date(parseInt(date) * 1000), 'MMM dd');

const toNiceDateYear = (date: string) => format(new Date(parseInt(date) * 1000), 'MMMM dd, yyyy');

export interface FeeItem {
  date: number;
  primary: number | null;
  secondary: number | null;
}

function findFee(days: FeeItem[], date: number) {
  for (const day of days) {
    if (day.date === date) {
      return day.primary;
    }
  }
  return 0;
}

interface SeriesChartProps {
  data: FeeItem[];
  primary: string;
  secondary?: string | null;
  loading?: boolean;
  protocols: { [id: string]: string };
  server?: boolean;
  events?: { date: string; description: string }[];
}

interface ActiveTooltip {
  description: string;
  point: { x: number; y: number };
}

const Chart: React.FC<SeriesChartProps> = ({
  data,
  primary,
  secondary,
  loading,
  protocols,
  server,
  events,
}) => {
  const [tooltip, setTooltip] = useState<null | ActiveTooltip>(null);
  const color = 'blue';
  const textColor = 'black';

  const Container: any = server ? 'div' : ResponsiveContainer;

  const margin = server
    ? { top: 20, right: 20, bottom: 20, left: 20 }
    : { top: 0, right: 10, bottom: 6, left: 0 };

  const width = server ? 380 : 500;

  return (
    <Container height={200}>
      <LineChart height={200} width={width} margin={margin} barCategoryGap={1} data={data}>
        <XAxis
          tickLine={false}
          stroke="#efefef"
          interval="preserveStartEnd"
          tickMargin={14}
          minTickGap={0}
          tickFormatter={(tick: any) => toNiceDate(tick)}
          dataKey="date"
          tick={{ fill: textColor }}
          type={'number'}
          domain={['dataMin', 'dataMax']}
        />
        <YAxis
          type="number"
          orientation="right"
          tickFormatter={(tick: any) => '$' + toK(tick)}
          stroke="#efefef"
          interval="preserveEnd"
          minTickGap={80}
          yAxisId={0}
          tickMargin={16}
          tick={{ fill: textColor }}
        />
        <Tooltip
          cursor={true}
          separator={tooltip ? null : ' : '}
          formatter={(val: any) => (tooltip ? [tooltip.description] : formattedNum(val))}
          labelFormatter={(label: any) => toNiceDateYear(label)}
          labelStyle={{ paddingTop: 4 }}
          position={tooltip?.point}
          contentStyle={{
            padding: '10px 14px',
            borderRadius: 10,
            borderColor: color,
            color: 'black',
            maxWidth: 250,
            whiteSpace: 'normal',
          }}
          wrapperStyle={{ top: -70, left: -10 }}
        />
        <Line
          strokeWidth={2}
          dot={false}
          type="monotone"
          name={protocols[primary]}
          dataKey="primary"
          yAxisId={0}
          stroke="#f2a900"
        />

        {events?.map((event) => (
          <ReferenceDot
            key={event.description}
            x={dateToTimestamp(event.date)}
            y={findFee(data, dateToTimestamp(event.date))}
            r={4}
            fill="#b957af"
            onMouseOver={(e: any) =>
              setTooltip({
                description: event.description,
                point: { x: e.cx + 10, y: e.cy - 10 },
              })
            }
            onMouseOut={() => setTooltip(null)}
          />
        ))}

        {secondary && (
          <Line
            strokeWidth={2}
            dot={false}
            type="monotone"
            name={protocols[secondary]}
            dataKey="secondary"
            yAxisId={0}
            stroke="#d6d3cc"
          />
        )}
        {loading && <rect height="100%" width="100%" opacity="0.5" fill="#666" />}
      </LineChart>
    </Container>
  );
};

export default Chart;