import React, { memo } from 'react';
import { G, Svg } from 'react-native-svg';
import * as d3 from 'd3';
import { ScaleLinear } from 'd3-scale';
import { Undefinable } from 'tsdef';
import { SBox } from '../../common/s-components/layout/s-box';
import { TGraphMaxes, TCoordinates } from '../../graph';
import { GRAPH_PADDING_TOP_RATIO } from '../../graph/constants';
import { XAxisLabels } from '../../graph/components/x-axis-labels';
import { YAxisLabels } from '../../graph/components/y-axis-labels';
import { YAxis } from '../../graph/components/y-axis';
import { XAxis } from '../../graph/components/x-axis';
import { Line } from '../../graph/components/line';
import { CARD_WIDTH } from '../constants';
import { SkeletonGraph } from './skeleton-graph';
import { SText } from '../../common/s-components/typography/s-text';
import { SGraphError } from '../s-components/s-graph-error';

type TProps = {
  graphData: TCoordinates;
  maxes?: TGraphMaxes;
  xTicks: Undefinable<number>[];
  variant?: string;
  entityGraph: {
    loading: boolean;
    error: boolean;
  };
};

export const CardGraph: React.FC<TProps> = memo(props => {
  const {
    maxes: { xMin, xMax, yMax } = {},
    xTicks,
    graphData,
    variant,
    entityGraph,
  } = props;

  const getSizes = () => {
    const width = CARD_WIDTH;
    const padding = 16;
    const paddingTop = 16;
    const paddingBottom = 25;
    const height = 120;
    const innerWidth = width;
    const innerHeight = height - paddingBottom;

    return {
      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 { xScale, yScale } = getScales() as {
    xScale: ScaleLinear<number, number>;
    yScale: ScaleLinear<number, number>;
  };
  const {
    height,
    // paddingBottom,
    innerWidth,
    innerHeight,
    padding,
  } = getSizes();
  const yTicks = [0, yMax!];
  const graphMax = yMax! / GRAPH_PADDING_TOP_RATIO;

  return (
    <SBox height={118} mt={12} overflow="hidden">
      {entityGraph.loading ? <SkeletonGraph /> : null}
      {entityGraph.error ? (
        <SGraphError>
          <SText>Data failed to load.</SText>
        </SGraphError>
      ) : null}
      {!entityGraph.loading && !entityGraph.error && !yMax ? (
        <SGraphError>
          <SText>There’s no data available.</SText>
        </SGraphError>
      ) : null}
      {yMax ? (
        <SBox>
          <XAxisLabels
            ticks={xTicks}
            scale={xScale}
            // height={paddingBottom}
            // width={innerWidth}
            yOffset={innerHeight}
          />
          <YAxisLabels
            ticks={yTicks}
            scale={yScale}
            // height={paddingBottom}
            offsetLeft={padding!}
            offsetTop={15}
            axisExclusion
          />
          <Svg height={height} width={innerWidth}>
            <>
              <YAxis
                ticks={yTicks}
                scale={yScale}
                // height={innerHeight}
                xOffsetRight={innerWidth}
              />
              <XAxis
                ticks={xTicks}
                scale={xScale}
                // height={paddingBottom}
                // width={innerWidth}
                yOffset={innerHeight}
              />
              <G transform="translate(0, 0)">
                <Line
                  graphMax={graphMax}
                  variant={variant}
                  data={graphData}
                  xScale={xScale}
                  yScale={yScale}
                />
              </G>
            </>
          </Svg>
        </SBox>
      ) : null}
    </SBox>
  );
});

CardGraph.defaultProps = {
  // graphData: undefined,
  // xTicks: undefined,
  // maxes: undefined,
  variant: 'variant1',
};
