import React, { PureComponent } from 'react';
import { Animated, Dimensions } from 'react-native';
import once from 'lodash/fp/once';
import { Subscription } from 'rxjs';
import { SBox } from '../s-components/layout/s-box';
import { infiniteAnimation } from '../utils/animation-service';
import { getCathetus } from '../transducers';
import { theme } from '../../app/theme';
import { LinearGradientClass } from './animated-gradient-base';

const { width } = Dimensions.get('window');

const AnimGradient: React.FC<any> = Animated.createAnimatedComponent<any>(
  LinearGradientClass
);

type TProps = {
  angle: number;
  primaryColor?: string;
  secondaryColor?: string;
  gradientWidth: number;
};

type TState = {
  blockHeight: number | null;
};

export class AnimatedGradient extends PureComponent<TProps, TState> {
  subscription?: Subscription;

  translateX?: number;

  static defaultProps = {
    primaryColor: theme.colorsRgba.gradientPrimaryDark,
    secondaryColor: theme.colorsRgba.gradientSecondaryDark,
  };

  constructor(props: TProps) {
    super(props);
    this.state = {
      blockHeight: null,
    };
  }

  onLayout = once(e => {
    const { angle, gradientWidth } = this.props;
    const blockHeight = e.nativeEvent.layout.height;
    const leftPosition = getCathetus(blockHeight, angle);
    const start = -(gradientWidth + leftPosition);
    const end = width + gradientWidth;
    this.setState({ blockHeight });
    this.subscription = infiniteAnimation([start, end], 1500).subscribe(
      translateX => {
        this.translateX = translateX as number;
        this.forceUpdate();
      }
    );
  });

  componentWillUnmount() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }

  render() {
    const { blockHeight } = this.state;
    const { angle, primaryColor, secondaryColor, gradientWidth } = this.props;
    const { translateX } = this;

    return (
      <SBox flex={1} onLayout={this.onLayout}>
        {translateX && blockHeight ? (
          <AnimGradient
            style={{
              transform: [{ translateX }, { rotate: `${angle}deg` }],
              width: gradientWidth,
              height: '120%',
              top: '-10%',
            }}
            colors={[primaryColor, secondaryColor, primaryColor]}
            locations={[0, 0.5, 1]}
            start={{ x: 0, y: 1 }}
            end={{ x: 1, y: 1 }}
          />
        ) : null}
      </SBox>
    );
  }
}
