import {
  createContext,
  createElement,
  forwardRef,
  HTMLAttributes,
  RaxNode,
  RefForwardingComponent,
  useContext,
} from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import List from '@rax-ui/list';
import Context from './context';

export interface FormItemContextProps {
  error: boolean;
  align: 'left' | 'right';
  solo: boolean;
}

export const FormItemContext = createContext<FormItemContextProps>({
  error: false,
  align: 'left',
  solo: false,
});

export interface FormItemProps extends HTMLAttributes<HTMLElement> {
  label?: RaxNode;
  labelWidth?: string | number;
  labelType?: 'inner' | 'upper';
  helpText?: string;
  errorText?: string;
  required?: boolean;
  tapable?: boolean;
}

const FormItem: RefForwardingComponent<any, FormItemProps> = (props, ref) => {
  const {
    label,
    labelWidth,
    labelType: labelTypeProp,
    helpText,
    errorText,
    tapable,
    style,
    children,
    required,
    ...others
  } = props;
  const { styles, labelType: contextLabelType } = useContext(Context);

  const labelType = labelTypeProp || contextLabelType;
  const align = labelType === 'upper' ? 'left' : 'right';

  return (
    <List.Item {...others}>
      <List.ItemContent>
        <View style={{ ...styles.itemContainer, ...(labelType === 'inner' ? styles.itemInnerContainer : {}) }}>
          {label ? (
            <View
              style={{
                ...styles.itemLabelContainer,
                ...(labelType === 'inner' ? styles.itemLabelInnerContainer : {}),
                width: labelWidth,
                flexShrink: 0,
              }}
            >
              <Text
                style={{
                  ...styles.itemLabel,
                  ...(labelType === 'inner' ? styles.itemInnerLabel : {}),
                }}
              >
                {label as string}
              </Text>
              {required ? (
                <Text
                  style={{
                    ...styles.itemRequiredText,
                    ...(labelType === 'inner' ? styles.itemInnerRequiredText : null),
                  }}
                >
                  *
                </Text>
              ) : null}
            </View>
          ) : null}
          <FormItemContext.Provider
            value={{
              error: !!errorText,
              align,
              solo: true,
            }}
          >
            <View style={{ ...styles.itemInput, justifyContent: align === 'right' ? 'flex-end' : 'flex-start' }}>
              {children}
            </View>
          </FormItemContext.Provider>
        </View>
        {errorText || helpText ? (
          <View style={{ ...styles.itemHelp, textAlign: align }}>
            {errorText ? (
              <Text style={styles.itemErrorText}>{errorText}</Text>
            ) : helpText ? (
              <Text style={styles.itemHelpText}>{helpText}</Text>
            ) : null}
          </View>
        ) : null}
      </List.ItemContent>
      {tapable ? <List.ItemAction icon="arrow-right" /> : null}
    </List.Item>
  );
};

export default forwardRef<any, FormItemProps>(FormItem);
