import React from 'react';
import styled from '@emotion/native';
import { ColorName, ViewStyle } from '@emotion/react';
import { StyleSystemThemedProps, TouchableHighlight, Container } from 'components/layout';
import { TouchableHighlightProps as TouchableHighlightPropsBase } from 'react-native';
import { variant } from 'styled-system';
import { COLOR_VALUES } from 'theme/color';
import { Visible } from 'components/visible';
import { Text } from 'components/text';

const colorVariants: Record<RadioColorVariant, ViewStyle> = {
  primary: { borderWidth: 1, borderColor: 'primary' },
  title: { borderWidth: 1, borderColor: 'title' },
  secondary: { borderWidth: 1, borderColor: 'secondary' },
  base: { borderWidth: 1, borderColor: 'base' },
  'base-01': { borderWidth: 1, borderColor: 'base-01' },
  'base-02': { borderWidth: 1, borderColor: 'base-02' },
};

const innerColorVariants: Record<RadioColorVariant, ViewStyle> = {
  primary: { backgroundColor: 'primary' },
  title: { backgroundColor: 'title' },
  secondary: { backgroundColor: 'secondary' },
  base: { backgroundColor: 'base' },
  'base-01': { backgroundColor: 'base-01' },
  'base-02': { backgroundColor: 'base-02' },
};
const sizeVariants: Record<RadioSizeVariant, ViewStyle> = {
  '2-extra-small': {
    height: 15,
    width: 15,
  },
  'extra-small': {
    height: 20,
    width: 20,
  },
  small: {
    height: 25,
    width: 25,
  },
  medium: {
    width: 30,
    height: 30,
  },
  large: {
    width: 35,
    height: 35,
  },
  'extra-large': {
    width: 40,
    height: 40,
  },
};

const innerSizeVariants: Record<RadioSizeVariant, ViewStyle> = {
  '2-extra-small': {
    height: 7,
    width: 7,
  },
  'extra-small': {
    height: 10,
    width: 10,
  },
  small: {
    height: 14,
    width: 14,
  },
  medium: {
    height: 19,
    width: 19,
  },
  large: {
    height: 24,
    width: 24,
  },
  'extra-large': {
    height: 29,
    width: 29,
  },
};

const RadioLocal = styled(TouchableHighlight)<TouchableProps>(
  variant({
    prop: 'sizeVariant',
    variants: sizeVariants,
  }),
  variant({
    prop: 'colorVariant',
    variants: colorVariants,
  }),
  {
    borderRadius: 50,

    alignItems: 'center',
    justifyContent: 'center',
  }
);

const RadioInnerLocal = styled(Container)<RadioInnerProps>(
  variant({
    prop: 'sizeVariant',
    variants: innerSizeVariants,
  }),
  variant({
    prop: 'colorVariant',
    variants: innerColorVariants,
  }),
  {
    borderRadius: 50,
  }
);
const UnderlayColors: Record<RadioColorVariant, string> = {
  primary: COLOR_VALUES['underlay-primary'],
  title: COLOR_VALUES.light['grey-05'],
  secondary: COLOR_VALUES['underlay-primary'],
  base: COLOR_VALUES.light['grey-04'],
  'base-01': 'transparent',
  'base-02': COLOR_VALUES['underlay-primary'],
};

export const Radio: React.FC<RadioType> = ({
  leftTitle,
  titleColor,
  rightTitle,
  colorVariant,
  leftElement,
  rightElement,
  onPress,
  size,
  isActive,
  sizeVariant,
  ...props
}) => {
  const localSizeOptional = !sizeVariant ? size : undefined;
  const localSizeInnerOptional = localSizeOptional ? localSizeOptional - 7 : undefined;
  const isLeftTitle = !!leftTitle && !leftElement;
  const isRightTitle = !!rightTitle && !rightElement;
  const flexGrow = leftElement ? 1 : 0;
  const justifyContent = leftElement ? 'space-between' : 'flex-start';

  return (
    <TouchableHighlight
      onPress={onPress}
      underlayColor="transparent"
      flexGrow={flexGrow}
      alignItems="center"
      flexDirection="row"
      {...props}
    >
      <Container
        flexGrow={flexGrow}
        flexDirection="row"
        justifyContent={justifyContent}
        alignItems="center"
      >
        <Visible if={!!leftElement}>
          <>{leftElement}</>
        </Visible>
        <Visible if={isLeftTitle}>
          <Text variant="body" mr="xs" color={titleColor}>
            {leftTitle}
          </Text>
        </Visible>
        <RadioLocal
          onPress={onPress}
          underlayColor={UnderlayColors[colorVariant as RadioColorVariant]}
          sizeVariant={sizeVariant}
          height={localSizeOptional}
          width={localSizeOptional}
          colorVariant={colorVariant}
        >
          <Visible if={isActive}>
            <RadioInnerLocal
              height={localSizeInnerOptional}
              width={localSizeInnerOptional}
              sizeVariant={sizeVariant}
              colorVariant={colorVariant}
            />
          </Visible>
        </RadioLocal>
        <Visible if={!!rightElement}>
          <>{rightElement}</>
        </Visible>

        <Visible if={isRightTitle}>
          <Text variant="body" ml="xs" color={titleColor}>
            {rightTitle}
          </Text>
        </Visible>
      </Container>
    </TouchableHighlight>
  );
};

export type RadioVariant =
  | 'primary'
  | 'outline'
  | 'outline-primary'
  | 'text'
  | 'tab'
  | 'tab-active';

export type RadioColorVariant = 'primary' | 'secondary' | 'base' | 'title' | 'base-01' | 'base-02';
export type RadioSizeVariant =
  | '2-extra-small'
  | 'extra-small'
  | 'small'
  | 'medium'
  | 'large'
  | 'extra-large';

type RadioType = StyleSystemThemedProps & TouchableProps & RadioProps;
export interface TouchableProps extends TouchableHighlightPropsBase {
  sizeVariant?: RadioSizeVariant;
  colorVariant?: RadioColorVariant;
}
export interface RadioInnerProps {
  sizeVariant?: RadioSizeVariant;
  size?: number;
  colorVariant?: RadioColorVariant;
}
export interface RadioProps {
  titleColor?: ColorName;
  isActive: boolean;
  size?: number;
  leftTitle?: string;
  rightTitle?: string;
  leftElement?: JSX.Element;
  rightElement?: JSX.Element;
}
