import React, {
  forwardRef,
  useContext,
  useImperativeHandle,
  useRef,
  useState,
} from 'react';
import {
  NativeSyntheticEvent,
  StyleSheet,
  TextInput,
  TextInputFocusEventData,
  TouchableOpacity,
  View,
} from 'react-native';
import { useComponentId } from '../Application';
import {
  ApplicationContext,
  ComponentContext,
  MiniAppContext,
} from '../Context';
import { Colors, Spacing, Styles } from '../Consts';
import { Icon } from '../Icon';
import { useScaleSize, Text } from '../Text';
import {
  ErrorView,
  getBorderColor,
  getSizeStyle,
  RenderTrailing,
} from './common';
import { InputPhoneNumberProps } from './index';
import styles from './styles';
import SystemTextInput from './SystemTextInput';
import { Image } from '../Image';
import { Typography } from '../Text/types';

/**
 * Input default component
 */
const InputPhoneNumber = forwardRef(
  (
    {
      value,
      onChangeText,
      size = 'small',
      placeholder = '0123456789',
      onBlur,
      onFocus,
      errorMessage,
      trailing,
      trailingColor,
      onPressTrailing,
      disabled = false,
      errorSpacing,
      loading = false,
      secureTextEntry,
      keyboardType,
      style,
      params,
      hintText,
      editable = true,
      showClearIcon = true,
      defaultValue,
      ...props
    }: InputPhoneNumberProps,
    ref,
  ) => {
    const { theme } = useContext(ApplicationContext);
    const context = useContext<any>(MiniAppContext);
    const scaleHeight = useScaleSize(size === 'small' ? 48 : 56, 1.1);
    const [focused, setFocused] = useState(false);
    const haveValue = !!value || !!defaultValue;
    const inputRef = useRef<TextInput | null>(null);
    const componentName = 'InputPhoneNumber';

    const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;

    const { componentId } = useComponentId(
      `${componentName}/${placeholder}`,
      props.accessibilityLabel,
    );

    const onClearText = () => {
      inputRef?.current?.clear();
      _onChangeText('');
    };

    const _onChangeText = (text: string) => {
      onChangeText?.(text);
    };

    const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
      setFocused(true);
      onFocus?.(e);
    };

    const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
      setFocused(false);
      onBlur?.(e);
    };

    const _setText = (text: string) => {
      inputRef?.current?.setNativeProps({ text });
      _onChangeText(text);
    };

    useImperativeHandle(ref, () => {
      return {
        clear: onClearText,
        focus: () => inputRef.current?.focus(),
        blur: () => inputRef.current?.blur(),
        setText: _setText,
      };
    });

    let inputTextStyles = {};
    let dividerHeight = 24;
    let size14 = useScaleSize(14);
    let size18 = useScaleSize(18);
    let typography: Typography;
    if (size === 'small') {
      inputTextStyles = { fontSize: size14, fontWeight: '600' };
      dividerHeight = 24;
      typography = 'header_s_semibold';
    } else {
      inputTextStyles = { fontSize: size18, fontWeight: '700' };
      dividerHeight = 32;
      typography = 'header_m_bold';
    }

    /**
     * Render input view
     */
    const renderInputView = () => {
      const disabledColor = theme.colors.text.disable;
      const secure = secureTextEntry;
      let textColor = theme.colors.text.default;
      let placeholderColor = theme.colors.text.hint;
      let iconTintColor = trailingColor ?? theme.colors.text.default;
      const borderWidth = focused ? 1.5 : 1;

      if (disabled) {
        textColor = disabledColor;
        placeholderColor = disabledColor;
        iconTintColor = disabledColor;
      }

      return (
        <View
          style={[
            styles.inputWrapper,
            { backgroundColor: theme.colors.background.surface },
            getSizeStyle(size, undefined, scaleHeight),
            { borderWidth },
            getBorderColor(theme, focused, errorMessage, disabled),
          ]}
        >
          <View style={styles.inputView}>
            <View style={[styles.leadingIconContainer, Styles.row]}>
              <Image
                source={{
                  uri: 'https://static.momocdn.net/app/img/icon/ic-qrcode-package/ic_vn_flag.png',
                }}
                style={innerStyle.iconFlag}
                resizeMode="contain"
                accessibilityLabel={`${componentId}|leading-icon`}
              />
              <View style={{ width: Spacing.XS }} />
              <Text typography={typography} color={textColor}>
                {'+84'}
              </Text>
              <View
                style={[
                  styles.phoneNumberDivider,
                  {
                    height: dividerHeight,
                    backgroundColor: Colors.black_04,
                  },
                ]}
              />
            </View>
            <SystemTextInput
              {...props}
              accessibilityLabel={`${componentId}`}
              editable={editable && !disabled}
              secureTextEntry={secure}
              textAlignVertical="center"
              ref={inputRef}
              accessibilityState={{
                disabled,
                ...props.accessibilityState,
              }}
              style={[
                styles.input,
                {
                  color: textColor,
                },
                inputTextStyles,
                secure && haveValue && { fontSize: size === 'small' ? 18 : 22 },
              ]}
              defaultValue={defaultValue}
              allowFontScaling={false}
              textBreakStrategy="highQuality"
              value={value}
              onChangeText={_onChangeText}
              onFocus={_onFocus}
              onBlur={_onBlur}
              placeholder={placeholder}
              selectionColor={theme.colors.primary}
              placeholderTextColor={placeholderColor}
              keyboardType={keyboardType ?? 'number-pad'}
            />
          </View>
          <View style={styles.iconView}>
            {showClearIcon && focused && haveValue && (
              <TouchableOpacity
                accessibilityLabel={`${componentId}|clear-icon-touch`}
                accessible={false}
                style={styles.iconWrapper}
                onPress={onClearText}
              >
                <Icon
                  source="24_navigation_close_circle_full"
                  size={16}
                  color={theme.colors.text.hint}
                  accessibilityLabel={`${componentId}|clear-icon`}
                />
              </TouchableOpacity>
            )}
            <RenderTrailing
              color={iconTintColor}
              icon={trailing}
              onPressIcon={onPressTrailing}
              loading={loading}
              componentId={componentId}
            />
          </View>
        </View>
      );
    };

    let inputState = 'active';
    if (value && value?.length > 0) {
      inputState = 'filled';
    }
    if (errorMessage && errorMessage?.length > 0) {
      inputState = 'error';
    }

    return (
      <ComponentContext.Provider
        value={{
          componentName,
          componentId,
          params,
          state: inputState,
        }}
      >
        <View
          style={[
            style,
            styles.wrapper,
            showBaseLineDebug && styles.debugBaseLine,
          ]}
        >
          {renderInputView()}
          <ErrorView
            errorMessage={errorMessage}
            errorSpacing={errorSpacing}
            hintText={hintText}
            componentId={componentId}
          />
        </View>
      </ComponentContext.Provider>
    );
  },
);

const innerStyle = StyleSheet.create({
  iconFlag: {
    width: 24,
    height: 24,
    marginHorizontal: 2,
  },
});

export default InputPhoneNumber;
