import React, {useCallback, useEffect, useState} from 'react';
import {Keyboard, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import DatePicker, {DatePickerProps} from 'react-native-date-picker';
import {useFormContext} from 'react-hook-form';
import {Typography} from '@components/_core/Typography';
import {Dialog} from '@components/_HuGo/Dialog';
import {useTheme} from '@shared/theme';
import {getTime} from '@shared/utils';
import {commonStyles} from '@shared/styles';

import {
  useInputController,
  UseInputControllerProps,
} from '../../hooks/useInputController';
import {InputAccessibilities, InputCommonProps} from '../../interfaces';
import {INPUT_ICONS} from '../../constants';
import {InputCore} from '../InputCore';
import {InputBox} from '../InputBox';
import {styles} from './styles';

interface InputTimeProps extends InputCommonProps, InputAccessibilities {
  value?: Date;
  onChange?: (date: Date) => void;
  onClear?: () => void;
  minuteInterval?: DatePickerProps['minuteInterval'];
}

export function InputTime({
  label,
  helper,
  isError,
  isSuccess,
  disabled,
  minuteInterval,
  onChange,
  onClear,
  placeholder,
  value,
  size,
}: InputTimeProps) {
  const {i18n, t} = useTranslation();
  const {iconSizes, isDarkMode, theme} = useTheme();
  const [focused, setFocused] = useState(false);
  const [selectedTime, setSelectedTime] = useState(value || new Date());
  const timeByLanguage = getTime(value);
  const withClear = !!value && !!onClear;
  const textColor = theme.text.neutral[disabled ? 'disabled' : 'default'];

  useEffect(() => {
    if (focused && value) {
      setSelectedTime(value);
    }
  }, [focused, value]);

  const onInputPress = () => {
    Keyboard.dismiss();
    setFocused(true);
  };

  const onDialogClose = () => {
    setSelectedTime(value || new Date());
    setFocused(false);
  };

  const onClearSelection = () => {
    onClear?.();
    onDialogClose();
  };

  const onSelectPress = () => {
    onChange?.(selectedTime);
    onDialogClose();
  };

  const onChangeDate = (date: Date) => {
    setSelectedTime(date);
  };

  return (
    <>
      <InputCore
        label={label}
        helper={helper}
        isSuccess={isSuccess}
        isError={isError}
        focused={focused}
        disabled={disabled}>
        <InputBox
          isSuccess={isSuccess}
          isError={isError}
          disabled={disabled}
          focused={focused}
          onPress={onInputPress}
          size={size}
          RightComponent={
            <INPUT_ICONS.down size={iconSizes.x6} color={textColor} />
          }>
          <View style={commonStyles.flex}>
            {value ? (
              <Typography color={textColor}>{timeByLanguage}</Typography>
            ) : placeholder ? (
              <Typography
                color={theme.text.neutral[disabled ? 'disabled' : 'lighter']}>
                {placeholder}
              </Typography>
            ) : null}
          </View>
        </InputBox>
      </InputCore>
      <Dialog
        isVisible={focused}
        onClose={onDialogClose}
        title={label}
        footer={{
          primaryButton: {
            text: t('general.apply'),
            onPress: onSelectPress,
          },
          secondaryButton: {
            text: t(`general.${withClear ? 'clear_selection' : 'close'}`),
            onPress: withClear ? onClearSelection : onDialogClose,
          },
        }}>
        <DatePicker
          date={selectedTime}
          onDateChange={onChangeDate}
          mode="time"
          minuteInterval={minuteInterval}
          style={styles.picker}
          locale={i18n.language}
          theme={isDarkMode ? 'dark' : 'light'}
        />
      </Dialog>
    </>
  );
}

export type InputTimeControllerProps = InputTimeProps & UseInputControllerProps;

export const InputTimeController = ({
  name,
  showSuccess,
  helper,
  ...props
}: InputTimeControllerProps) => {
  const {resetField} = useFormContext();
  const inputController = useInputController({
    name,
    showSuccess,
    helperText: helper,
  });

  const onClearInput = useCallback(() => {
    // defaultValue can't be undefined due to react-hook-form limitation
    // https://react-hook-form.com/docs/useform/resetfield
    resetField(name, {defaultValue: null});
  }, [name, resetField]);

  return <InputTime {...props} {...inputController} onClear={onClearInput} />;
};
