import React, { useCallback, useEffect, useRef, useState } from 'react';
import { filter, throttleTime } from 'rxjs/operators';
import { Animated, Keyboard } from 'react-native';
import { NavigationProp } from '@react-navigation/native';
import { Input } from './input';
import { scrollNamedSubject$ } from '../utils/scroll-service';
import { blurSubject$, focusSubject$ } from '../utils/input-service';
import { theme } from '../../app/theme';
import { fp as _ } from '../utils/fp';
import { withNavigation } from '../hoc/with-navigation';

type TProps = {
  placeholder: string;
  navigation: NavigationProp<any>;
  searchLoading?: boolean;
  animation?: Record<string, Animated.AnimatedInterpolation<any>>;
  bg?: string;
  value?: string | null;
  onChange: (value: string) => void;
  onFocus?: () => void;
  onBlur?: () => void;
  blurOnScroll?: boolean;
  [key: string]: any;
};

export const SearchInputComponent: React.FC<TProps> = props => {
  const { inFocus, searchLoading, placeholder, ...rest } = props;
  const inputRef = useRef<React.RefObject<any> | null>();
  const [isKeyboardShown, setIsKeyboardShown] = useState(false);

  const keyboardDidHide = () => {
    setIsKeyboardShown(false);
  };

  const keyboardDidShow = () => {
    setIsKeyboardShown(true);
  };

  const blurField = useCallback(() => {
    if (isKeyboardShown && !searchLoading) {
      Keyboard.dismiss();
    }
  }, [searchLoading]);

  useEffect(() => {
    const scrollWatcher = scrollNamedSubject$
      .pipe(
        throttleTime(250),
        filter(_.pathEq(['name'], 'search'))
      )
      .subscribe(blurField);

    const focusWatcher = focusSubject$.subscribe(() => {
      if (inFocus) {
        setTimeout(() => {
          if (inputRef.current) {
            //@ts-ignore
            inputRef!.current!.focus();
          }
        }, 0);
      }
    });
    //@ts-ignore
    const blurWatcher = blurSubject$.subscribe(inputRef!.current!.blur);
    const keyboardHideListener = Keyboard.addListener(
      'keyboardDidHide',
      keyboardDidHide
    );
    const keyboardShowListener = Keyboard.addListener(
      'keyboardDidShow',
      keyboardDidShow
    );

    return () => {
      scrollWatcher.unsubscribe();

      focusWatcher.unsubscribe();

      blurWatcher.unsubscribe();

      keyboardShowListener.remove();

      keyboardHideListener.remove();
    };
  }, [inFocus]);

  return (
    <Input
      ref={inputRef}
      placeholder={placeholder}
      iconName="search"
      placeholderTextColor={theme.colors.logan}
      {...rest}
    />
  );
};

export const SearchInput = withNavigation(SearchInputComponent);
