import React, { useRef } from 'react';
import { Svg, G } from 'react-native-svg';
import * as d3 from 'd3';
import { Dimensions } from 'react-native';
import { Line } from './line';
import { YAxis } from './y-axis';
import { XAxis } from './x-axis';
import { SBox } from '../../common/s-components/layout/s-box';
import { TLines } from '../types';
import { Button } from '../../common/components/button';
import { fp as _ } from '../../common/utils/fp';
import { XAxisLabels } from './x-axis-labels';
import { YAxisLabels } from './y-axis-labels';
import { theme } from '../../app/theme';
import { ShadowBox } from '../../common/components/shadow-box';
import { PORTRAIT_HEIGHT, GRAPH_PADDING_TOP_RATIO } from '../constants';
import { Icon } from '../../common/components/icon';
import { SRow } from '../../common/s-components/layout/s-row';
import { SGradientCard } from '../../common/s-components/s-gradient-card';
import { InfoTitle } from '../../common/components/info-title';
import { TGraphMaxes, TIconName } from '../../common/types';

const { width: DEVICE_WIDTH } = Dimensions.get('window');
const winWidth = DEVICE_WIDTH - 32;

type TProps = {
  lines: TLines;
  maxes: TGraphMaxes;
  ticks: number[];
  onFullScreen: () => void;
  id: string;
  onInfoPress: () => void;
};

export const MultilineGraph: React.FC<TProps> = props => {
  const {
    lines,
    maxes: { xMin, xMax, yMax },
    ticks,
    onFullScreen,
    id,
    onInfoPress,
  } = props;
  const graphWidth = useRef(winWidth);

  const getSizes = () => {
    const padding = 16;
    const paddingTop = 65;
    const paddingBottom = 57.5;
    const containerHeight = 272;
    const height = PORTRAIT_HEIGHT;
    const innerWidth = graphWidth.current;
    const innerHeight = height - paddingBottom;

    return {
      containerHeight,
      height,
      width: graphWidth.current,
      padding,
      paddingTop,
      paddingBottom,
      innerHeight,
      innerWidth,
    };
  };

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

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

    return { xScale, yScale };
  };

  const {
    containerHeight,
    height,
    innerWidth,
    innerHeight,
    padding,
    width,
  } = getSizes();
  const { xScale, yScale } = getScales();
  const yTicks = [0, yMax];
  const graphMax = yMax / GRAPH_PADDING_TOP_RATIO;
  const hideGraph = _.any(_.isNil)([yMax, xMax, xMin]);
  const btnWidth = 140;
  const btnLeftPosition = (innerWidth - btnWidth) / 2;

  return (
    <SBox position="relative" height={containerHeight}>
      <SBox height={height + 12} borderRadius={8}>
        <ShadowBox height={height} bg={theme.colors.eastBay} borderRadius={8}>
          <SGradientCard
            colors={theme.gradients.marketCard}
            opacity={0.4}
            height={height}
            width={width}
            borderRadius={8}
          />
          <XAxisLabels
            ticks={ticks}
            scale={xScale}
            yOffset={innerHeight}
            ticksVariant="edge"
          />
          <YAxisLabels
            ticks={yTicks}
            scale={yScale}
            offsetLeft={padding}
            offsetTop={17}
            axisExclusion
          />
          <Svg height={height} width={innerWidth}>
            {!hideGraph ? (
              <>
                <YAxis
                  ticks={yTicks}
                  scale={yScale}
                  xOffsetRight={innerWidth}
                />
                <XAxis
                  ticks={ticks}
                  scale={xScale}
                  yOffset={innerHeight}
                  ticksVariant="edge"
                />
                <G transform="translate(0, 0)">
                  {lines.map(line => {
                    if (!line) return null;
                    const { variant, dotted } = line;

                    return (
                      <Line
                        key={variant}
                        graphMax={graphMax}
                        variant={variant}
                        data={dotted}
                        xScale={xScale}
                        yScale={yScale}
                      />
                    );
                  })}
                </G>
              </>
            ) : null}
          </Svg>
          <SBox position="absolute" left={16} top={11}>
            <SRow>
              {id !== 'combined' ? (
                <Icon
                  mt={-1}
                  ml={-4}
                  mr={5}
                  size={22}
                  color={theme.colors.lavenderGray}
                  name={id as TIconName}
                />
              ) : null}
              <InfoTitle
                testID="info-title-combined-streams"
                onPress={onInfoPress}
                position="relative"
                zIndex={2}
                title="Combined Streams"
                medium
              />
            </SRow>
          </SBox>
        </ShadowBox>
      </SBox>
      {!hideGraph && onFullScreen ? (
        <SBox position="absolute" bottom={0} left={btnLeftPosition} zIndex={1}>
          <Button
            testID="multiline-graph-details-button"
            onPress={() => {
              onFullScreen();
            }}
            width={btnWidth}
          >
            Details
          </Button>
        </SBox>
      ) : null}
    </SBox>
  );
};
