import React, { useState } from 'react';
import { SH6 } from '../s-components/typography/s-h6';
import { SButtonTitle } from '../s-components/s-button-title';
import { SBox } from '../s-components/layout/s-box';
import { getBgColor, getBorderColor } from '../transducers';
import { theme } from '../../app/theme';
import { Icon } from './icon';
import {
  TCssRules,
  TGetBgColorVariant,
  TGetBorderColorVariant,
  TIconName,
} from '../types';
import { fp as _ } from '../utils/fp';
import { SText } from '../s-components/typography/s-text';
import { SPressable } from '../s-components/s-pressable';
import { SRow } from '../s-components/layout/s-row';

type TProps = TCssRules & {
  variant?:
    | 'primary'
    | 'secondary'
    | 'request'
    | 'request-2'
    | 'gold'
    | 'green'
    | 'red'
    | 'white'
    | 'fiord'
    | 'pomegranate'
    | 'transparent';
  onPress: () => void;
  iconName?: TIconName | null;
  iconPosition?: 'left' | 'right';
  normal?: boolean;
  testID?: string;
  disabled?: boolean;
  disabledOpacity?: number;
  iconWithText?: boolean;
  children:
    | React.ReactElement
    | string
    | (React.ReactElement | string | number)[];
  width?: number | string | null;
  px?: number;
};

export const Button: React.FC<TProps> = props => {
  let {
    onPress,
    children,
    width,
    px,
    variant,
    iconName,
    iconPosition,
    color,
    normal,
    disabled,
    disabledOpacity,
    iconWithText,
    ...rest
  } = props;
  const [pressed, setPressed] = useState(false);
  const backgroundColor = getBgColor(variant as TGetBgColorVariant, pressed);
  const borderColor = getBorderColor(
    variant as TGetBorderColorVariant,
    pressed
  );

  const isOutlineButton = !!borderColor;
  const textColor =
    color || theme.colors[variant === 'white' ? 'black' : 'white'];
  let height;
  let borderRadius;
  if (variant === 'transparent') {
    px = 0;
    borderRadius = 0;
    height = 'auto';
  }

  return (
    <SPressable
      onPressIn={() => {
        if (!disabled) {
          setPressed(true);
        }
      }}
      onPressOut={() => {
        setPressed(false);
      }}
      onPress={() => {
        if (!disabled) {
          onPress();
        }
      }}
      flexDirection="row"
      {...rest}
    >
      <>
        {isOutlineButton ? (
          !iconWithText ? (
            <SBox
              alignItems="center"
              px={px || 23}
              pt={13}
              pb={14}
              height={44}
              borderRadius={22}
              borderColor={borderColor}
              borderWidth={2}
              minWidth={140}
            >
              {normal ? (
                <SText semibold color={textColor}>
                  {children}
                </SText>
              ) : (
                <SH6 color={textColor} style={{ opacity: pressed ? 0.7 : 1 }}>
                  {children}
                </SH6>
              )}
            </SBox>
          ) : (
            <SRow
              px={px || 23}
              pt={13}
              pb={14}
              height={44}
              borderRadius={22}
              borderColor={borderColor}
              borderWidth={2}
              minWidth={100}
            >
              {children}
            </SRow>
          )
        ) : (
          <SBox
            opacity={disabled ? disabledOpacity : 1}
            flexDirection="row"
            justifyContent="center"
            alignItems="center"
            width={width || 'auto'}
            px={_.isNotNil(px) ? px : 24.5}
            pt={14}
            pb={15}
            height={height}
            borderRadius={_.isNotNil(borderRadius) ? borderRadius : 21.5}
            backgroundColor={backgroundColor}
          >
            {iconName && iconPosition === 'left' ? (
              <Icon
                mt={-2}
                ml={-3}
                mr={9}
                name={iconName}
                size={10}
                // TODO why hard coded color???
                // TODO why hard coded color???
                // TODO why hard coded color???
                color="lavenderGray"
              />
            ) : null}
            {normal ? (
              <SText semibold color={textColor}>
                {children}
              </SText>
            ) : (
              <SButtonTitle color={textColor}>{children}</SButtonTitle>
            )}
            {iconName && iconPosition === 'right' ? (
              <Icon mt={1} ml={9} name={iconName} size={12} color={textColor} />
            ) : null}
          </SBox>
        )}
      </>
    </SPressable>
  );
};

Button.defaultProps = {
  variant: 'primary',
  width: undefined,
  px: undefined,
  iconName: undefined,
  iconPosition: 'left',
  normal: false,
  disabled: false,
  disabledOpacity: 0.7,
  iconWithText: false,
};
