import React from 'react';
import { Svg, G } from 'react-native-svg';
import * as d3 from 'd3';
import { Line } from './line';
import { YAxis } from './y-axis';
import { XAxis } from './x-axis';
import { SBox } from '../../common/s-components/layout/s-box';
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_WIDTH,
  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 { TCoordinates, TGraphMaxes, TIconName } from '../../common/types';
import { SGraphTitle } from '../s-components/s-graph-title';

type TProps = {
  title?: string;
  dotted: TCoordinates;
  maxes: TGraphMaxes;
  ticks: number[];
  onFullScreen: () => void;
  variant?: string;
  id: string;
};

export const LineGraph: React.FC<TProps> = props => {
  let {
    dotted,
    maxes: { xMin, xMax, yMax },
    ticks,
    onFullScreen,
    title,
    variant,
    id,
  } = props;
  const graphWidth = PORTRAIT_WIDTH;

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

    return {
      containerHeight,
      height,
      width,
      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 ml={16} position="relative" height={containerHeight}>
      <SBox height={height + 12} borderRadius={8}>
        <ShadowBox
          height={height}
          bg={theme.colors.eastBay}
          borderRadius={8}
          androidShadowOffset={2}
        >
          <SGradientCard
            colors={theme.gradients.marketCard}
            opacity={0.4}
            height={height}
            width={width}
            borderRadius={8}
          />
          <SBox position="absolute" left={16} top={10}>
            <SRow>
              {id && id !== 'combined' ? (
                <Icon
                  mt={2}
                  ml={-4}
                  mr={5}
                  size={22}
                  color={theme.colors.lavenderGray}
                  name={id as TIconName}
                />
              ) : null}
              <SGraphTitle>{title}</SGraphTitle>
            </SRow>
          </SBox>
          <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)">
                  {dotted ? (
                    <Line
                      graphMax={graphMax}
                      variant={variant}
                      data={dotted}
                      xScale={xScale}
                      yScale={yScale}
                    />
                  ) : null}
                </G>
              </>
            ) : null}
          </Svg>
        </ShadowBox>
      </SBox>
      {!hideGraph && onFullScreen ? (
        <SBox position="absolute" bottom={0} left={btnLeftPosition} zIndex={1}>
          <Button
            testID="line-graph-details-button"
            onPress={() => {
              onFullScreen();
            }}
            width={btnWidth}
          >
            Details
          </Button>
        </SBox>
      ) : null}
    </SBox>
  );
};

LineGraph.defaultProps = {
  title: 'STREAMS',
  variant: 'variant2',
};
