import React, { FC, ReactNode, useContext } from 'react';
import {
  GestureResponderEvent,
  TouchableOpacity,
  View,
  ViewStyle,
} from 'react-native';
import { ApplicationContext } from '../Context';
import { Theme } from '../Application/types';
import { Styles } from '../Consts';
import { Icon } from '../Icon';
import { useScaleSize, Text } from '../Text';
import styles from './styles';
import { Loader } from '../Loader';
import IconSources from '../Assets/icon.json';

type FloatingViewProps = {
  floatingValue?: string;
  floatingIconColor?: string;
  componentId?: string;
  disabled?: boolean;
  floatingIcon?: string;
  required?: boolean;
  style?: ViewStyle;
  onPress?: (e: GestureResponderEvent) => void;
};

type TrailingProps = {
  loading?: boolean;
  color?: string;
  icon?: string;
  componentId?: string;
  onPressIcon?: () => void;
};

export const MAX_LENGTH = 300;

export const getBorderColor = (
  theme: Theme,
  focused: boolean,
  errorMessage?: string,
  disabled?: boolean,
) => {
  let borderColor = theme.colors.border.default;

  if (focused) {
    borderColor = theme.colors.primary;
  }

  if (errorMessage) {
    borderColor = theme.colors.error.primary;
  }

  if (disabled) {
    borderColor = theme.colors.border.disable;
  }

  return { borderColor };
};

export const getSizeStyle = (
  size?: 'small' | 'large',
  multiline: boolean = false,
  height?: number,
) => {
  let scaleStyle: ViewStyle = {};
  if (height) {
    scaleStyle = { height };
  }

  if (multiline)
    return [
      styles.multilineContainer,
      {
        minHeight: height,
      },
    ];

  if (size === 'small') {
    return [styles.smallContainer, scaleStyle];
  }
  return [styles.container, scaleStyle];
};

export const ErrorView: FC<{
  errorMessage?: string;
  errorSpacing?: boolean;
  hintText?: string;
  componentId?: string;
}> = ({ errorMessage, errorSpacing, hintText, componentId }) => {
  const { theme } = useContext(ApplicationContext);
  const errorColor = theme.colors.error.primary;
  const hintColor = theme.colors.text.hint;
  const hintTextDefault = hintText ?? 'Không thể chỉnh sửa';
  const scaledIconSize = useScaleSize(16);

  if (errorMessage || hintText) {
    return (
      <View style={styles.errorView}>
        <View style={styles.errorIcon}>
          <Icon
            color={errorMessage ? errorColor : hintColor}
            source="ic_error"
            size={scaledIconSize}
          />
        </View>
        <Text
          accessibilityLabel={`${componentId}|${
            errorMessage ? 'error' : 'hint'
          }-text`}
          style={Styles.flex}
          color={errorMessage ? errorColor : hintColor}
          typography={'description_default_regular'}
        >
          {errorMessage ?? hintTextDefault}
        </Text>
      </View>
    );
  }
  if (errorSpacing) {
    return <View style={[styles.errorView, { height: 18 }]} />;
  }
  return <View />;
};

export const FloatingView: FC<FloatingViewProps> = ({
  floatingValue,
  floatingIconColor,
  disabled,
  floatingIcon,
  required,
  style,
  onPress,
  componentId,
}) => {
  const { theme } = useContext(ApplicationContext);
  const scaledTop = useScaleSize(10);
  if (floatingValue) {
    let floatingTextColor = theme.colors.text.hint;
    let floatingIconTintColor = floatingIconColor;
    if (disabled) {
      floatingTextColor = theme.colors.text.disable;
      floatingIconTintColor = theme.colors.text.disable;
    }

    return (
      <View
        style={[
          styles.floatingView,
          {
            backgroundColor: theme.colors.background.surface,
            zIndex: 10,
            top: -scaledTop,
          },
          style,
        ]}
      >
        <Text
          color={floatingTextColor}
          typography={'label_s_medium'}
          accessibilityLabel={`${componentId}|floating-text`}
        >
          {floatingValue}
          {required && (
            <Text
              typography={'label_s_medium'}
              color={theme.colors.error.primary}
            >
              *
            </Text>
          )}
        </Text>
        {!!floatingIcon && (
          <TouchableOpacity
            activeOpacity={onPress ? 0.6 : 1}
            onPress={onPress}
            accessibilityLabel={`${componentId}|floating-icon-touch`}
          >
            <Icon
              color={floatingIconTintColor}
              source={floatingIcon}
              size={16}
              style={styles.floatingIcon}
              accessibilityLabel={`${componentId}|floating-icon`}
            />
          </TouchableOpacity>
        )}
      </View>
    );
  }
  return null;
};

export const RenderTrailing: FC<TrailingProps> = ({
  loading,
  color,
  icon,
  onPressIcon,
  componentId,
}) => {
  const { theme } = useContext(ApplicationContext);
  if (loading) {
    return <Loader type={'spinner'} color={color} style={styles.icon} />;
  }

  if (icon) {
    const isIcon =
      (IconSources as any)?.[icon as string]?.uri || icon?.includes('http');
    const renderIconTouchable = (icon: ReactNode) => {
      return (
        <TouchableOpacity
          accessibilityLabel={`${componentId}|trailing-touch`}
          onPress={onPressIcon}
          style={styles.icon}
        >
          {icon}
        </TouchableOpacity>
      );
    };

    if (isIcon) {
      return renderIconTouchable(
        <Icon
          color={color}
          source={icon as string}
          size={24}
          accessibilityLabel={`${componentId}|trailing-icon`}
        />,
      );
    }
    return renderIconTouchable(
      <Text
        typography="action_xs_bold"
        color={color ?? theme.colors.primary}
        numberOfLines={1}
        accessibilityLabel={`${componentId}|trailing-text`}
      >
        {icon!.substring(0, 15)}
      </Text>,
    );
  }
  return null;
};
