import React, { Ref, useContext, useEffect, useRef } from 'react';
import LinearGradient from 'react-native-linear-gradient';
import { ApplicationContext, MiniAppContext } from '../../Context';
import { Animated, Dimensions, Platform, StyleSheet, View } from 'react-native';
import { HeaderType } from '../../Layout/types';
import { InputRef, InputSearch } from '../../Input';
import Navigation from '../Navigation';
import { Colors, Radius, Spacing } from '../../Consts';
import { Image } from '../../Image';
import { SearchHeaderProps } from '../types';
import BackgroundImageView from './BackgroundImageView';

const SCREEN_PADDING = 12;
const BACK_WIDTH = 28;

const { width: screenWidth } = Dimensions.get('window');
const LinearGradientAnimated = Animated.createAnimatedComponent(LinearGradient);

/**
 * Header extended with background image
 * @constructor
 */
const HeaderExtendHeader: React.FC<{
  headerType?: HeaderType;
  animatedValue: Animated.Value;
  heightHeader: number;
  headerRightWidth: number;
  inputSearchProps?: SearchHeaderProps;
  inputSearchRef?: Ref<InputRef>;
  navigation?: Navigation;
  useShadowHeader?: boolean;
  gradientColor?: string;
  headerBackground?: string;
}> = ({
  headerType = 'default',
  animatedValue,
  heightHeader,
  headerRightWidth = 73,
  inputSearchProps,
  inputSearchRef,
  useShadowHeader = true,
  gradientColor: customGradientColor,
  headerBackground: customBackground,
}) => {
  const { theme } = useContext(ApplicationContext);
  const context = useContext<any>(MiniAppContext);
  const animated = useRef(new Animated.Value(0));
  const gradientColor = customGradientColor ?? theme.colors.gradient;
  const headerBackground = customBackground ?? theme.assets?.headerBackground;
  const leftPosition = inputSearchProps?.leftPosition || BACK_WIDTH + 20;

  const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;

  const opacityBackground = animatedValue?.interpolate({
    inputRange: [0, 52],
    outputRange: [0, 1],
    extrapolate: 'clamp',
  });
  const opacityGradient = animatedValue?.interpolate({
    inputRange: [0, 52],
    outputRange: [1, 0],
    extrapolate: 'clamp',
  });

  useEffect(() => {
    const listener = animatedValue.addListener(({ value }) => {
      animated.current.setValue(value);
    });
    return () => {
      animatedValue?.removeListener(listener);
    };
  }, [animatedValue]);

  const height = animated.current.interpolate({
    inputRange: [0, 100],
    outputRange: [heightHeader + 52, heightHeader],
    extrapolate: 'clamp',
  });

  const translateX = animated.current.interpolate({
    inputRange: [0, 100],
    outputRange: [SCREEN_PADDING, leftPosition],
    extrapolate: 'clamp',
  });

  const backgroundColor = animated.current.interpolate({
    inputRange: [0, 100],
    outputRange: [
      theme.colors.background.surface,
      theme.colors.background.default,
    ],
    extrapolate: 'clamp',
  });

  if (inputSearchProps && Platform.OS === 'android') {
    useShadowHeader = false;
  }

  if (inputSearchProps) {
    return (
      <View style={[{ zIndex: 0 }, showBaseLineDebug && styles.debugBaseLine]}>
        <Animated.View style={{ height: height }} />
        <BackgroundImageView
          useShadowHeader={useShadowHeader}
          heightHeader={heightHeader}
          opacityBackground={opacityBackground}
          headerBackground={headerBackground}
        />
        <Animated.View
          style={[
            styles.headerBox,
            { height: headerType === 'extended' ? height : heightHeader },
          ]}
        >
          {!!gradientColor && (
            <LinearGradientAnimated
              colors={[gradientColor, gradientColor + '00']}
              style={[styles.extendedHeader, { opacity: opacityGradient }]}
            >
              {!!theme.assets?.headerBackground && (
                <Image
                  style={styles.headerBackground}
                  source={{ uri: theme.assets?.headerBackground }}
                  loading={false}
                />
              )}
            </LinearGradientAnimated>
          )}
        </Animated.View>
        <Animated.View
          style={{
            justifyContent: 'flex-end',
            height,
            position: 'absolute',
            zIndex: 2,
          }}
        >
          <Animated.View
            style={{
              transform: [{ translateX }],
              marginVertical: Spacing.S,
              width: animated.current.interpolate({
                inputRange: [0, 100],
                outputRange: [
                  screenWidth - SCREEN_PADDING * 2,
                  screenWidth - leftPosition - 12 - headerRightWidth,
                ],
                extrapolate: 'clamp',
              }),
            }}
          >
            <Animated.View style={{ backgroundColor, borderRadius: Radius.XL }}>
              <InputSearch
                {...inputSearchProps}
                ref={inputSearchRef}
                backgroundColor={'transparent'}
                showButtonText={false}
              />
            </Animated.View>
          </Animated.View>
        </Animated.View>
      </View>
    );
  }

  if (headerType === 'extended') {
    return (
      <View style={[{ zIndex: 0 }, showBaseLineDebug && styles.debugBaseLine]}>
        <BackgroundImageView
          useShadowHeader={useShadowHeader}
          heightHeader={heightHeader}
          opacityBackground={opacityBackground}
          headerBackground={headerBackground}
        />
        {!!gradientColor && (
          <LinearGradientAnimated
            colors={[gradientColor, gradientColor + '00']}
            style={[styles.extendedHeader, { opacity: opacityGradient }]}
          >
            {!!headerBackground && (
              <Image
                style={styles.headerBackground}
                source={{ uri: headerBackground }}
                loading={false}
              />
            )}
          </LinearGradientAnimated>
        )}
        <View style={{ height: heightHeader }} />
      </View>
    );
  }

  return <View />;
};

const styles = StyleSheet.create({
  headerBackground: {
    width: '100%',
    height: undefined,
    position: 'absolute',
    aspectRatio: 375 / 154,
  },
  extendedHeader: {
    aspectRatio: 375 / 154,
    position: 'absolute',
    width: '100%',
  },
  headerBox: {
    width: '100%',
    position: 'absolute',
    overflow: 'hidden',
  },
  verifiedDot: {
    width: 4,
    height: 4,
    borderRadius: 2,
    backgroundColor: Colors.green_03,
    position: 'absolute',
    alignSelf: 'center',
  },
  debugBaseLine: { borderWidth: 1, borderColor: Colors.green_06 },
});

export { HeaderExtendHeader };
