import React, { useState, useRef, useEffect } from 'react';
import {
  TextInput,
  Surface,
  Divider,
  HelperText,
  Searchbar,
  Text,
  Provider as PaperProvider,
  useTheme,
} from 'react-native-paper';
import {
  View,
  Dimensions,
  Platform,
  SectionList,
  ActivityIndicator,
} from 'react-native';
import Modal from 'react-native-modal';
import Lo from 'lodash';

import Item from '../Components/Item';
import { defaultDropdownProps, ITEMLAYOUT } from '../constants';
import styles from '../styles';
import type {
  IDropdownData,
  IGroupDropdownData,
  IGroupDropdownProps,
} from '../types';
import { deviceWidth, deviceHeight } from '../util';
import EmptyList from '../Components/EmptyList';
import PressableTouch from '../Components/PressableTouch';

const GroupDropdown: React.FC<IGroupDropdownProps> = props => {
  const {
    error,
    value,
    label,
    required,
    disabled,
    data,
    onChange,
    floating,
    enableSearch,
    primaryColor,
    elevation,
    borderRadius,
    activityIndicatorColor,
    searchPlaceholder,
    helperText,
    errorColor,
    itemTextStyle,
    itemContainerStyle,
    showLoader,
    animationIn = 'fadeIn',
    animationOut = 'fadeOut',
    supportedOrientations = ['portrait', 'landscape'],
    animationInTiming,
    animationOutTiming,
    headerTextStyle,
    headerContainerStyle,
    stickySectionHeadersEnabled,
    parentDDContainerStyle,
    rippleColor,
    emptyListText,
    enableAvatar,
    avatarSize,
    onBlur,
    paperTheme,
    textInputStyle,
    mainContainerStyle,
    underlineColor,
    disableSelectionTick,
    selectedItemTextStyle,
    selectedItemViewStyle,
    removeLabel,
    mode = 'flat',
    disabledItemTextStyle,
    disabledItemViewStyle,
    dropdownIcon = 'menu-down',
    dropdownIconSize = 30,
    itemSelectIcon,
    itemSelectIconSize,
    multiline = false,
    searchInputTheme,
  } = props;
  const { colors } = useTheme();
  const [selected, setSelected] = useState<string | number>();
  const [labelv, setlabelV] = useState<string>('');
  const [isVisible, setIsVisible] = useState<boolean>(false);
  const [iconColor, setIconColor] = useState<string | undefined>('grey');
  const [options, setOptions] = useState<IGroupDropdownData[]>([]);
  const [hasError, setError] = useState<boolean>(false);
  const [singluarData, setSingularData] = useState<IDropdownData[]>([]);

  const [contMeasure, setConMeasure] = useState({
    vx: 0,
    vy: 0,
    vWidth: 0,
    vHeight: 0,
  });
  const [dimension, setDimension] = useState({
    dw: deviceWidth,
    dh: deviceHeight,
  });
  const [searchQuery, setSearchQuery] = useState('');

  const pViewRef = useRef<View | any>();
  const listRef = useRef<SectionList | any>();

  useEffect(() => {
    Dimensions.addEventListener('change', () => {
      const { width, height } = Dimensions.get('window');
      setDimension({ dw: width, dh: height });
      setIsVisible(false);
      setIconColor('grey');
    });
    return () => {
      Dimensions.removeEventListener('change', () => {});
    };
  }, []);

  useEffect(() => {
    const destructuredData: IDropdownData[] = [];
    Lo.forEach(data, d => {
      Lo.forEach(d.data, dv => destructuredData.push(dv));
    });
    setSingularData(destructuredData);
    setOptions(data);
  }, [data]);

  useEffect(() => {
    if (!Lo.isEmpty(singluarData) && value) {
      const lFilter = Lo.filter(singluarData, { value: value })[0];
      if (!Lo.isEmpty(lFilter)) setlabelV(lFilter.label);
      setSelected(value);
    }
  }, [value, singluarData]);

  useEffect(() => {
    if (isVisible && listRef) {
      listRef.current.flashScrollIndicators();
    }
  }, [isVisible]);

  useEffect(() => {
    if (isVisible && selected) {
      let secionIndex = 0;
      let itemIndex = 0;
      if (!Lo.isEmpty(options)) {
        options.forEach((e, secIndex) => {
          const itIndex = Lo.findIndex(e.data, { value: selected });
          if (itIndex >= 0 && listRef) {
            itemIndex = itIndex;
            secionIndex = secIndex;
            setTimeout(() => {
              listRef.current.scrollToLocation({
                animated: false,
                sectionIndex: secionIndex,
                itemIndex: itemIndex,
                viewPosition: Platform.OS === 'android' ? 0 : 0.5,
              });
            }, 100);
          }
        });
      }
    }
  }, [selected, options, isVisible]);

  useEffect(() => {
    if (disabled) {
      setIconColor('lightgrey');
    }
  }, [disabled]);

  useEffect(() => {
    if (required && error) {
      setError(true);
      setIconColor(errorColor);
    } else {
      setError(false);
      setIconColor('grey');
    }
  }, [required, error, errorColor]);

  const onTextInputFocus = () => {
    if (hasError) {
      setIconColor('red');
    } else {
      setIconColor(primaryColor);
    }
    // if (Platform.OS === 'ios') {
    pViewRef.current.measureInWindow(
      (vx: number, vy: number, vWidth: number, vHeight: number) => {
        const ddTop = vy + vHeight;
        const bottomMetric = dimension.dh - vy;
        if (bottomMetric < 300) {
          setConMeasure({ vx, vy: ddTop - 217, vWidth, vHeight });
        } else {
          setConMeasure({ vx, vy: ddTop, vWidth, vHeight });
        }
      }
    );
    // }
    setIsVisible(true);
  };

  const androidOnLayout = () => {
    if (Platform.OS === 'android') {
      pViewRef.current.measureInWindow(
        (vx: number, vy: number, vWidth: number, vHeight: number) => {
          const ddTop = vy + vHeight;
          const bottomMetric = dimension.dh - vy;
          // setPx(bottomMetric);
          if (bottomMetric < 300) {
            setConMeasure({ vx, vy: ddTop - 217, vWidth, vHeight });
          } else {
            setConMeasure({ vx, vy: ddTop, vWidth, vHeight });
          }
        }
      );
    }
  };

  const onModalBlur = () => {
    setIsVisible(false);
    if (hasError) {
      setIconColor('red');
    } else {
      setIconColor('grey');
    }
    if (onBlur && typeof onBlur === 'function') onBlur();
  };

  const handleOptionSelect = (v: string | number) => {
    const lFilter = Lo.filter(singluarData, { value: v })[0];
    if (!Lo.isEmpty(lFilter)) setlabelV(lFilter.label);
    setSelected(v);
    if (onChange && typeof onChange === 'function') {
      onChange(v);
      setIsVisible(false);
    }
    if (hasError) {
      setIconColor('red');
    } else {
      setIconColor('grey');
    }
    setSearchQuery('');

    setOptions(data);
  };

  const onChangeSearch = (query: string) => {
    setSearchQuery(query);
    if (!Lo.isEmpty(data) && query) {
      let matches: IGroupDropdownData[] = [];
      data.forEach(e => {
        const sF = e.data.filter(c =>
          c.label
            .toString()
            .toLowerCase()
            .trim()
            .includes(query.toString().toLowerCase())
        );
        if (!Lo.isEmpty(sF))
          matches = matches.concat([{ title: e.title, data: sF }]);
      });
      if (matches.length === 0) setOptions([]);
      else setOptions(matches);
    } else if (!Lo.isEmpty(data) && !query) {
      setOptions(data);
    }
  };

  const getEmptyComponent = () => {
    if (typeof emptyListText === 'string')
      return <EmptyList emptyItemMessage={emptyListText} />;
    else return <>{emptyListText}</>;
  };

  const labelAction = () => {
    if (removeLabel) {
      return '';
    } else {
      return required ? `${label}*` : label;
    }
  };

  return (
    <PaperProvider theme={paperTheme}>
      <View>
        <View>
          <PressableTouch
            onPress={onTextInputFocus}
            disabled={disabled}
            rippleColor={rippleColor}
          >
            <View
              style={[styles.fullWidth, mainContainerStyle]}
              ref={pViewRef}
              onLayout={androidOnLayout}
              pointerEvents="none"
            >
              <TextInput
                label={labelAction()}
                value={labelv}
                style={[styles.textInput, textInputStyle]}
                underlineColor={underlineColor}
                underlineColorAndroid={underlineColor}
                editable={false}
                error={hasError}
                disabled={disabled}
                multiline={multiline}
                theme={{
                  ...searchInputTheme,
                  colors: { primary: primaryColor, error: errorColor },
                }}
                right={
                  <TextInput.Icon
                    name={dropdownIcon}
                    size={dropdownIconSize}
                    color={iconColor}
                  />
                }
                mode={mode}
              />
            </View>
            {required && hasError ? (
              <HelperText
                type="error"
                theme={{ colors: { error: errorColor } }}
                visible={hasError}
              >
                {helperText ? helperText : `${label} is required`}
              </HelperText>
            ) : null}
          </PressableTouch>
        </View>
        <View>
          <Modal
            isVisible={isVisible}
            onBackdropPress={onModalBlur}
            backdropColor={floating ? 'rgba(0,0,0,0.1)' : 'transparent'}
            style={styles.modalStyle}
            animationIn={animationIn}
            animationOut={animationOut}
            animationInTiming={animationInTiming}
            animationOutTiming={animationOutTiming}
            supportedOrientations={supportedOrientations}
          >
            <View
              style={{
                backgroundColor: 'transparent',
                width: !floating ? contMeasure.vWidth : 'auto',
                left: !floating ? contMeasure.vx : 0,
                top: !floating ? contMeasure.vy : 100,
                right: 0,
                position: 'absolute',
                padding: floating ? 20 : 0,
              }}
            >
              <Surface
                style={[
                  styles.surface,
                  parentDDContainerStyle,
                  { elevation, borderRadius },
                  floating ? { maxHeight: dimension.dh / 2 } : null,
                ]}
              >
                {showLoader ? (
                  <View style={[styles.loader, { borderRadius }]}>
                    <ActivityIndicator
                      size="small"
                      color={activityIndicatorColor}
                    />
                  </View>
                ) : null}
                <SectionList
                  ref={listRef}
                  sections={options}
                  legacyImplementation
                  initialNumToRender={25}
                  maxToRenderPerBatch={25}
                  ListHeaderComponent={
                    enableSearch ? (
                      <View>
                        <Searchbar
                          placeholder={searchPlaceholder}
                          onChangeText={onChangeSearch}
                          value={searchQuery}
                          theme={{ colors: { primary: primaryColor } }}
                          style={{
                            elevation: 0,
                            backgroundColor: showLoader
                              ? 'transparent'
                              : colors.background,
                            height: ITEMLAYOUT,
                          }}
                        />
                        <Divider style={styles.divider} />
                      </View>
                    ) : null
                  }
                  stickyHeaderIndices={enableSearch ? [0] : undefined}
                  renderItem={({ item }) => (
                    <Item
                      item={item}
                      onSelect={handleOptionSelect}
                      selected={value}
                      selectedColor={primaryColor}
                      itemTextStyle={itemTextStyle}
                      itemContainerStyle={itemContainerStyle}
                      rippleColor={rippleColor}
                      disabled={showLoader || item?.disabled}
                      enableAvatar={enableAvatar}
                      avatarSize={avatarSize}
                      disableSelectionTick={disableSelectionTick}
                      selectedItemTextStyle={selectedItemTextStyle}
                      selectedItemViewStyle={selectedItemViewStyle}
                      disabledItemTextStyle={disabledItemTextStyle}
                      disabledItemViewStyle={disabledItemViewStyle}
                      itemSelectIcon={itemSelectIcon}
                      itemSelectIconSize={itemSelectIconSize}
                    />
                  )}
                  renderSectionHeader={({ section: { title } }) => (
                    <View
                      style={{
                        backgroundColor: showLoader
                          ? 'transparent'
                          : colors.background,
                        borderRadius: 3,
                      }}
                    >
                      <Divider style={styles.divider} />
                      <View style={[styles.headerView, headerContainerStyle]}>
                        <Text style={[styles.headerText, headerTextStyle]}>
                          {title.trim()}
                        </Text>
                      </View>
                      <Divider style={styles.divider} />
                    </View>
                  )}
                  keyExtractor={() => Math.random().toString()}
                  ItemSeparatorComponent={() => (
                    <Divider style={styles.divider} />
                  )}
                  getItemLayout={(_d, index) => ({
                    length: ITEMLAYOUT,
                    offset: ITEMLAYOUT * index,
                    index,
                  })}
                  stickySectionHeadersEnabled={stickySectionHeadersEnabled}
                  ListEmptyComponent={getEmptyComponent()}
                />
              </Surface>
            </View>
          </Modal>
        </View>
      </View>
    </PaperProvider>
  );
};

GroupDropdown.defaultProps = defaultDropdownProps;
export default GroupDropdown;