import React from 'react';
import { Dimensions, StyleSheet } from 'react-native';
import { Defs, G, LinearGradient, Path, Stop, Svg } from 'react-native-svg';
import { SBox } from '../../common/s-components/layout/s-box';
import { SText } from '../../common/s-components/typography/s-text';
import { AngleGradient } from '../../common/components/angle-gradient';
import { formatStream } from '../../common/transducers';
import { SCentered } from '../../common/s-components/layout/s-centered';
import { SDot } from '../../market-monitoring/s-components/s-dot';
import { SRow } from '../../common/s-components/layout/s-row';
import { fp as _ } from '../../common/utils/fp';
import {
  calculatePercentage,
  getArcPathGenerator,
  getDonutParameters,
  getDonutSections,
  getDonutTotal,
  getPercentage,
} from '../transducers';
import { TColors, TSegments } from '../types';

// https://stackoverflow.com/questions/48280641/label-for-d3-donut-chart

/*
 * https://github.com/d3/d3-shape?source=post_page---------------------------#arcs
 *
 *  Issue with conical gradient in svg
 * https://stackoverflow.com/a/18210763/6190198
 * http://bl.ocks.org/bycoffe/18441cddeb8fe147b719fab5e30b5d45
 * https://stackoverflow.com/questions/18198252/d3-arc-gradient
 * https://bl.ocks.org/tomshanley/9953da50ec833fdb4819dd065d2f6643
 *
 * About labels centering
 * http://jsfiddle.net/Orbifold/nnm6kg4m/
 * https://bl.ocks.org/laxmikanta415/dc33fe11344bf5568918ba690743e06f
 * https://www.d3-graph-gallery.com/graph/donut_label.html
 * */

type TProps = {
  segments: TSegments;
  range?: string;
  colors?: TColors;
};

export const Donut: React.FC<TProps> = props => {
  const { segments, colors, range } = props;
  const total = getDonutTotal(segments);
  const {
    donutPercentage,
    legendPercentage,
    legendValues,
  } = calculatePercentage(segments, total);
  const sectionAngles = getDonutSections(donutPercentage);
  const pathGenerator = getArcPathGenerator();
  const svgHeight = 230;
  const { width } = Dimensions.get('window');
  const { gradientAngle /*, anchors */ } = getDonutParameters(
    sectionAngles,
    total,
    svgHeight,
    width
  );

  return (
    <SBox position="relative" mt={-10} testID="streams-monitoring-data">
      <SBox
        position="absolute"
        height={svgHeight}
        width={width}
        top={0}
        overflow="hidden"
      >
        <SCentered
          style={[StyleSheet.absoluteFill, { transform: [{ translateX: 6 }] }]}
        >
          <SBox>
            <SText
              medium
              fontSize={24}
              letterSpacing={1}
              mt={5}
              textAlign="center"
            >
              {formatStream(total)}
            </SText>
            <SText
              bold
              textAlign="center"
              mt={4}
              color="periwinkleGray"
              xs
              letterSpacing={1}
            >
              {range}
            </SText>
          </SBox>
        </SCentered>
      </SBox>

      <SBox pl={2}>
        <Svg width={width} height={svgHeight}>
          <Defs>
            {sectionAngles.map(d => {
              const { index } = d;
              // gradient rotation https://codepen.io/NV/pen/jcnmK
              // https://codepen.io/NV/pen/jcnmK
              return (
                <AngleGradient key={index} angle={gradientAngle[index]}>
                  <LinearGradient id={`grad${index}`}>
                    <Stop
                      offset="0"
                      stopColor={_.path([index, 'start'], colors)}
                    />
                    <Stop
                      offset="1"
                      stopColor={_.path([index, 'end'], colors)}
                    />
                  </LinearGradient>
                </AngleGradient>
              );
            })}
          </Defs>
          <G transform={`translate(${width / 2}, ${svgHeight / 2})`}>
            {sectionAngles.map((d, index) => {
              return (
                <Path
                  // eslint-disable-next-line
                  key={index}
                  d={pathGenerator(d)!}
                  fill={`url(#grad${index})`}
                  strokeWidth={1}
                />
              );
            })}
          </G>
        </Svg>
      </SBox>

      <SBox mt={10}>
        {segments.map((o, index) => {
          const percentage = getPercentage(legendPercentage[index], o.value);
          return (
            <SRow
              // eslint-disable-next-line
              key={index}
              alignItems="center"
              mb={7}
              ml={63}
              position="relative"
            >
              <SDot size={10} bg={_.path([index, 'legend'], colors)} mr={9} />
              <SText>{o.label}</SText>
              <SText
                bold
                alignItems="flex-end"
                position="absolute"
                top={0}
                right={114}
              >
                {formatStream(legendValues[index])}
              </SText>
              <SText
                alignItems="flex-end"
                position="absolute"
                top={0}
                right={65}
              >
                ({percentage})
              </SText>
            </SRow>
          );
        })}
      </SBox>
    </SBox>
  );
};
