import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {ListRenderItem, BlurEvent, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useController} from 'react-hook-form';
import Text from '@components/Text';
import Checkbox from '@components/Checkbox';
import {BottomModalList} from '@components/Modals';
import InputContainer from '@components/InputContainer';
import ActivityIndicator from '@components/ActivityIndicator';
import Button from '@components/Button';
import {INPUT_SPACING} from '@components/constants';
import {COLORS} from '@shared/colors';

import {SelectInputProps, SelectOption, SelectValue} from './interfaces';
import {styles} from './styles';

/**
 * @deprecated Use `_HuGo/Inputs/InputSelect` instead
 */
function SelectInput<T extends SelectOption>({
  variant = 'checkbox',
  value = null,
  placeholder,
  options,
  setSelectedValue,
  label,
  modalTitle,
  filterable,
  modalSearchPlaceholder,
  onBlur,
  onEndReached,
  isLoading,
  showClearButton,
  onClear,
  autocompleteUniqueOption,
  disabled,
  checkboxColor,
  ...props
}: SelectInputProps<T>) {
  const {t} = useTranslation();
  const [isVisible, setIsVisible] = useState(false);
  const autocomplete = autocompleteUniqueOption && options.length === 1;
  const isDisabled = disabled || autocomplete;

  useEffect(() => {
    autocomplete && setSelectedValue(options[0].id);
  }, [autocomplete, options, setSelectedValue]);

  const selectedOption = useMemo(
    () => options.find(option => option.id === value),
    [options, value],
  );

  const showModal = () => setIsVisible(true);
  const hideModal = () => setIsVisible(false);

  const handleSelectItem = useCallback(
    (id: SelectValue) => () => {
      setSelectedValue?.(id);
      hideModal();
      onBlur?.();
    },
    [onBlur, setSelectedValue],
  );

  const handleClear = useCallback(() => {
    hideModal();
    onClear?.();
  }, [onClear]);

  const renderCheckboxItem: ListRenderItem<T> = useCallback(
    ({item, index}) => (
      <Checkbox
        key={index}
        radio
        color={checkboxColor}
        checked={item.id === value}
        title={item.name}
        onPress={handleSelectItem(item.id)}
      />
    ),
    [handleSelectItem, checkboxColor, value],
  );

  const renderButtonItem: ListRenderItem<T> = useCallback(
    ({item, index}) => (
      <Button
        key={index}
        text={item.name}
        onPress={handleSelectItem(item.id)}
        leftIconName={item.icon}
        variant="text"
        color="black"
        style={styles.button}
      />
    ),
    [handleSelectItem],
  );

  return (
    <>
      <InputContainer
        label={label}
        hasValue={!!selectedOption}
        rightIcon="arrowDown"
        leftIcon={selectedOption?.icon}
        onPress={showModal}
        disabled={isDisabled}
        {...props}>
        <View>
          {isLoading ? (
            <ActivityIndicator />
          ) : (
            <Text
              variant={INPUT_SPACING.inputVariant}
              color={
                selectedOption && !isDisabled
                  ? COLORS.BLACK
                  : COLORS.GRAY_THIRTY_THREE
              }>
              {selectedOption?.name || (!label && placeholder)}
            </Text>
          )}
        </View>
      </InputContainer>
      <BottomModalList
        isVisible={isVisible}
        onClose={hideModal}
        renderItem={
          variant === 'checkbox' ? renderCheckboxItem : renderButtonItem
        }
        data={options}
        title={modalTitle || label}
        filterable={filterable}
        searchPlaceholder={modalSearchPlaceholder}
        onEndReached={onEndReached}
        footerComponent={
          showClearButton ? (
            <View style={styles.footer}>
              <Button
                text={t('general.clear_selection')}
                variant="text"
                onPress={handleClear}
                disabled={!selectedOption}
                style={styles.clearButton}
              />
            </View>
          ) : null
        }
      />
    </>
  );
}

interface InputSelectControllerProps<T extends SelectOption>
  extends Omit<SelectInputProps<T>, 'value' | 'setSelectedValue'> {
  name: string;
  defaultValue?: Nullable<string>;
  onChange?: (value: SelectValue) => void;
}

export const SelectInputController = <T extends SelectOption>({
  name,
  defaultValue,
  onBlur,
  onChange,
  ...props
}: InputSelectControllerProps<T>) => {
  const {field, fieldState} = useController({
    name,
    defaultValue,
  });

  const handleBlur = (e?: BlurEvent) => {
    field.onBlur();
    onBlur?.(e);
  };

  const handleChange = (value: SelectValue) => {
    onChange?.(value);
    field.onChange(value);
  };

  return (
    <SelectInput<T>
      {...props}
      setSelectedValue={handleChange}
      value={field.value ?? defaultValue}
      errorMessage={fieldState.error?.message}
      onBlur={handleBlur}
    />
  );
};

export * from './interfaces';

export default SelectInput;
