import React, { useState } from 'react';
import {
  View,
  TextInput,
  StyleSheet,
  type KeyboardTypeOptions,
  type ReturnKeyTypeOptions,
  I18nManager,
  TouchableOpacity,
  type NativeSyntheticEvent,
  type TextInputFocusEventData,
  type TextInputSubmitEditingEventData,
} from 'react-native';
import { moderateScale } from 'react-native-size-matters';
import IconSVG from '../../assets/svgs';
import type { AutoCapitalize } from './TTextInputEnum';
import TTypography from '../TTypography/TTypography';
import MaskInput from './MaskInput';
import { TypographyVariant } from '../TTypography/TTypographyEnum';
import { defaultScale } from '../../utils/Common';
import { withTheme, useTheme } from '../../core/theming';
import type { Theme } from '../../utils/types';
import { fontFamilies } from '../../constants/fontFamilies';

interface Props {
  placeholder?: string;
  placeholderTextColor?: string;
  marginTop?: number;
  marginBottom?: number;
  marginLeft?: number;
  marginRight?: number;
  borderColor?: string;
  value?: string | any | undefined;
  autoFocus?: boolean;
  keyboardType?: KeyboardTypeOptions;
  onChangeText?: (masked: string, unmasked: string, obfuscated: string) => void;
  autoCorrect?: boolean;
  returnKeyType?: ReturnKeyTypeOptions | undefined;
  onSubmitEditing?: (
    event: NativeSyntheticEvent<TextInputSubmitEditingEventData>
  ) => void | undefined;
  error?: boolean;
  errorText?: string;
  multiline?: boolean;
  noExteriorView?: boolean;
  autoCapitalize?: AutoCapitalize;
  maxLength?: number | undefined;
  onEndEditing?: (
    event: NativeSyntheticEvent<TextInputSubmitEditingEventData>
  ) => void | undefined;
  isPassword?: any;
  width?: any;
  disable?: boolean;
  iconHeight?: number;
  iconWidth?: number;
  editable?: boolean;
  rightIcon?: React.ReactNode;
  leftIcon?: any;
  isTopText?: boolean;
  showObfuscatedValue?: boolean;
  placeholderFillCharacter?: string;
  obfuscationCharacter?: string;
  mask?: any;
  theme: Theme;
  isOTPInput?: boolean;
  fontSize?: number;
  onFocusText?: (
    event: NativeSyntheticEvent<TextInputFocusEventData>
  ) => void | undefined;
  onBlurText?: (
    event: NativeSyntheticEvent<TextInputFocusEventData>
  ) => void | undefined;
  testID?: string;
  accessibilityLabel?: string;
}

const defaultSize = 20;
const defaultMargin = 0;

const TTextInput = React.forwardRef<TextInput, Props>(
  (
    {
      placeholder,
      placeholderTextColor,
      marginTop = defaultMargin,
      marginBottom = defaultMargin,
      marginLeft = defaultMargin,
      marginRight = defaultMargin,
      borderColor,
      value,
      autoFocus,
      keyboardType,
      onChangeText,
      autoCorrect,
      returnKeyType,
      iconHeight = defaultSize,
      iconWidth = defaultSize,
      editable,
      onSubmitEditing,
      multiline = false,
      errorText,
      autoCapitalize,
      maxLength,
      isPassword,
      onEndEditing,
      width,
      rightIcon,
      leftIcon,
      disable,
      showObfuscatedValue,
      obfuscationCharacter,
      placeholderFillCharacter,
      mask,
      isOTPInput = false,
      fontSize = 16,
      onFocusText,
      onBlurText,
      testID,
      accessibilityLabel,
    },
    ref
  ): any => {
    const [visible, setVisible] = useState(false);

    const [securePassword, setSecurePassword] = useState(isPassword);

    const handlePassword = () => {
      setVisible(!visible);
      setSecurePassword(!securePassword);
    };

    const { colors } = useTheme();

    const stylesWithProp = styles({ colors, multiline, isOTPInput });

    let updatedMask = null;
    if (mask) {
      const maskArray = mask.split('');

      updatedMask = maskArray.map((mapValue: any) => {
        if (mapValue.toLowerCase() === 'x') {
          return /\d/;
        }
        if (mapValue.toLowerCase() === '*') {
          return [/\d/];
        }
        return mapValue;
      });
    }

    const getPlaceholderTextColor = () => {
      if (disable) {
        return colors.greyOpac50;
      }
      if (placeholderTextColor) {
        return placeholderTextColor;
      }
      return colors.textColorLight;
    };

    const renderRightIcon = () => {
      return rightIcon;
    };

    return (
      <View style={stylesWithProp.container}>
        <View
          style={{
            marginTop: moderateScale(marginTop, defaultScale),
            marginBottom: moderateScale(marginBottom, defaultScale),
            marginLeft: moderateScale(marginLeft, defaultScale),
            marginRight: moderateScale(marginRight, defaultScale),
          }}
        >
          <View
            style={[
              disable
                ? stylesWithProp.disableTextInputContainer
                : stylesWithProp.textinputContainer,

              {
                borderColor: errorText ? colors.error : borderColor,
              },
              {
                marginTop: moderateScale(marginTop, defaultScale),
                marginBottom: moderateScale(marginBottom, defaultScale),
                marginLeft: moderateScale(marginLeft, defaultScale),
                marginRight: moderateScale(marginRight, defaultScale),
                width: width,
              },
            ]}
          >
            {!isPassword && leftIcon && (
              <View style={stylesWithProp.lefticon}>
                <IconSVG
                  height={moderateScale(iconHeight, defaultScale)}
                  width={moderateScale(iconWidth, defaultScale)}
                  name={leftIcon}
                />
              </View>
            )}
            <MaskInput
              style={[
                I18nManager.isRTL
                  ? stylesWithProp.textinputRTL
                  : stylesWithProp.textinput,
                {
                  fontSize: fontSize,
                  color: colors.textColor,
                  fontFamily: I18nManager.isRTL
                    ? `${fontFamilies.Fonts.primaryArabic}`
                    : `${fontFamilies.Fonts.primary}-Regular`,
                },
              ]}
              placeholder={placeholder}
              onChangeText={onChangeText}
              editable={editable}
              ref={ref}
              autoCorrect={autoCorrect}
              placeholderTextColor={getPlaceholderTextColor()}
              value={value}
              autoFocus={autoFocus}
              keyboardType={isOTPInput ? 'numeric' : keyboardType}
              returnKeyType={returnKeyType}
              secureTextEntry={securePassword}
              autoCapitalize={autoCapitalize}
              multiline={multiline}
              maxLength={maxLength}
              showObfuscatedValue={showObfuscatedValue}
              obfuscationCharacter={obfuscationCharacter}
              placeholderFillCharacter={placeholderFillCharacter}
              onSubmitEditing={onSubmitEditing}
              onEndEditing={onEndEditing}
              onFocus={onFocusText}
              onBlur={onBlurText}
              mask={updatedMask}
              numberOfLines={multiline ? 2 : 1}
              testID={testID}
              accessible={true}
              accessibilityLabel={accessibilityLabel}
            />
            {isPassword && (
              <TouchableOpacity
                style={stylesWithProp.icon}
                onPress={handlePassword}
                activeOpacity={1}
                hitSlop={{ top: 10, bottom: 10, left: 5, right: 5 }}
              >
                <IconSVG
                  height={iconHeight}
                  width={iconWidth}
                  name={visible ? 'showpassword' : 'hidepassword'}
                />
              </TouchableOpacity>
            )}
            {rightIcon ? (
              <View style={stylesWithProp.icon}>{renderRightIcon()}</View>
            ) : null}
          </View>

          {errorText && !disable ? (
            <TTypography
              children={errorText}
              variant={TypographyVariant.PRIMARY}
              color={colors.error}
              fontSize={14}
              style={stylesWithProp.errorTextStyle}
            />
          ) : null}
        </View>
      </View>
    );
  }
);

const styles = (props: {
  colors: any;
  multiline: boolean;
  isOTPInput: boolean;
}) =>
  StyleSheet.create({
    container: { width: '100%' },
    textinputContainer: {
      flexDirection: 'row',
      alignItems: 'center',
      borderRadius: 4,
      borderWidth: 1,
      backgroundColor: props.colors.white,
    },
    icon: {
      paddingRight: moderateScale(15, defaultScale),
      paddingLeft: moderateScale(5, defaultScale),
    },
    lefticon: {
      paddingRight: moderateScale(5, defaultScale),
      paddingLeft: moderateScale(15, defaultScale),
    },
    textinput: {
      flex: 1,
      height: moderateScale(props.multiline ? 160 : 28, defaultScale),
      paddingHorizontal: moderateScale(12, defaultScale),
      marginVertical: moderateScale(props.multiline ? 0 : 5, defaultScale),
      color: props.colors.black,
      paddingTop: props.multiline ? 10 : 0,
      paddingBottom: props.multiline ? 10 : 0,
      marginTop: props.multiline ? 0 : 14,
      marginBottom: props.multiline ? 0 : 14,
      textAlign: props.isOTPInput ? 'center' : 'left',
      textAlignVertical: props.multiline ? 'top' : 'center',
    },
    textinputRTL: {
      flex: 1,
      height: moderateScale(props.multiline ? 160 : 28, defaultScale),
      paddingHorizontal: moderateScale(12, defaultScale),
      marginVertical: moderateScale(props.multiline ? 0 : 5, defaultScale),
      color: props.colors.black,
      paddingTop: props.multiline ? 10 : 0,
      paddingBottom: props.multiline ? 10 : 0,
      marginTop: props.multiline ? 0 : 14,
      marginBottom: props.multiline ? 0 : 14,
      textAlign: props.isOTPInput ? 'center' : 'right',
      textAlignVertical: props.multiline ? 'top' : 'center',
    },
    shadow: {
      shadowColor: props.colors.shadowColor,
      shadowOffset: {
        width: 0,
        height: 0,
      },
      shadowOpacity: defaultScale,
      shadowRadius: 3,
      elevation: 15,
    },
    disableTextInputContainer: {
      flexDirection: 'row',
      alignItems: 'center',
      backgroundColor: props.colors.lightgrey,
      borderRadius: 4,
    },
    disableTextinput: {
      flex: 1,
      height: moderateScale(48, defaultScale),
      paddingLeft: moderateScale(15, defaultScale),
      textAlign: I18nManager.isRTL ? 'right' : 'left',
    },
    errorTextStyle: {
      marginTop: moderateScale(5, defaultScale),
    },
  });

export default withTheme(TTextInput);
