import styled from '@emotion/native';
import {
  GestureResponderEvent,
  ImageSourcePropType,
  ViewProps as ViewPropsBase,
} from 'react-native';
import { variant } from 'styled-system';
import { ColorName, ViewStyle } from '@emotion/react';
import { Text } from 'components/text';
import {
  Center,
  Container,
  Image,
  StyleSystemThemedProps,
  TouchableHighlight,
} from 'components/layout';
import React from 'react';
import { Pencil, EllipseBordered } from 'icons';
import { Visible } from 'components/visible';
import { TextVariant } from 'components/text/Text';
import { Fab } from 'components/fab';
import { sliceFirstAndCapitalize } from 'utils/text';

const colorVariants: Record<AvatarColorVariant, ViewStyle> = {
  base: {
    backgroundColor: 'base',
  },
  'base-01': {
    backgroundColor: 'base-01',
  },
  'base-02': {
    backgroundColor: 'base-02',
  },
  primary: {
    backgroundColor: 'primary',
  },
  'primary-01': {
    backgroundColor: 'primary-01',
  },
  secondary: {
    backgroundColor: 'secondary',
  },
  'secondary-01': {
    backgroundColor: 'secondary-01',
  },
  success: {
    backgroundColor: 'success',
  },
  'success-01': {
    backgroundColor: 'success-01',
  },
  transparent: {
    backgroundColor: 'transparent',
  },
};

const sizeVariants: Record<AvatarSizeVariant, ViewStyle> = {
  'extra-small': {
    width: 25,
    height: 25,
  },
  small: {
    width: 30,
    height: 30,
  },
  medium: {
    width: 40,
    height: 40,
  },
  large: {
    width: 50,
    height: 50,
  },
  'extra-large': {
    width: 55,
    height: 55,
  },
};

const imageSizeVariants: Record<AvatarSizeVariant, number> = {
  'extra-small': 25,
  small: 30,
  medium: 40,
  large: 50,
  'extra-large': 55,
};

const ellipseColorVariants: Record<AvatarStatusVariants, ColorName> = {
  online: 'success',
  offline: 'body',
  'out-of-office': 'secondary',
};

const avatarBorderRadius: Record<AvatarSizeVariant, number> = {
  'extra-small': 5,
  small: 6,
  medium: 8,
  large: 10,
  'extra-large': 11,
};
const AvatarLocal = styled(Center)<ViewProps>(
  variant({
    prop: 'colorVariant',
    variants: colorVariants,
  }),
  variant({
    prop: 'sizeVariant',
    variants: sizeVariants,
  })
);

export const Avatar: React.FC<AvatarType> = ({
  title,
  size = 25,
  bordered,
  borderedWidth = 1,
  shapeVariant = 'circle',
  titleVariant,
  statusBorderVariant = 'base',
  asset,
  sizeVariant,
  colorVariant,
  titleColor,
  status,
  editable,
  borderedColor,
  uri,
  icon,
  onPress,
  ...props
}) => {
  const localSize = sizeVariant ? imageSizeVariants[sizeVariant] : size || imageSizeVariants.medium;

  const ellipseColor = status && ellipseColorVariants[status];

  const source = asset ? asset : { uri };

  const isSource = asset || uri;
  const isTitle = !isSource && title;
  const isIcon = !isTitle && icon;

  const isSizeVariant = sizeVariant ? avatarBorderRadius[sizeVariant] : size * 0.2;
  const borderRadius = shapeVariant === 'circle' ? localSize / 2 : isSizeVariant;

  const borderRadiusColor = borderedColor ? borderedColor : 'transparent';
  const isLess70 = size < 80 ? -2 : -1;
  const topRight = size < 51 ? -3 : isLess70;
  return (
    <TouchableHighlight borderRadius={borderRadius} onPress={onPress}>
      <>
        <AvatarLocal
          {...props}
          colorVariant={colorVariant}
          height={localSize + borderedWidth}
          width={localSize + borderedWidth}
          borderWidth={borderedWidth}
          borderColor={borderRadiusColor}
          borderRadius={borderRadius}
        >
          <Visible if={!!status}>
            <Container position="absolute" zIndex={2} top={topRight} right={topRight}>
              <EllipseBordered colorVariant={ellipseColor} borderVariant={statusBorderVariant} />
            </Container>
          </Visible>
          <Visible if={editable}>
            <TouchableHighlight
              onPress={() => {}}
              underlayColor="transparent"
              backgroundColor="transparent"
              position="absolute"
              zIndex={2}
              bottom={0}
              left={0}
              right={0}
              borderRadius={localSize}
              top={0}
              alignItems="flex-start"
              justifyContent="flex-end"
            >
              <Fab
                variant="plain"
                sizeVariant="medium"
                shapeVariant="circle"
                colorVariant="base-01"
                centerElement={<Pencil />}
              />
            </TouchableHighlight>
          </Visible>
          <Visible if={!!isSource}>
            <Image
              height={localSize}
              width={localSize}
              borderRadius={borderRadius}
              source={source as ImageSourcePropType}
            />
          </Visible>
          <Visible if={!!isTitle}>
            <Text variant={titleVariant || 'caption-bold'} color={titleColor || 'grey-08'}>
              {sliceFirstAndCapitalize(title)}
            </Text>
          </Visible>
          <Visible if={!!isIcon}>
            <Container>{icon}</Container>
          </Visible>
        </AvatarLocal>
      </>
    </TouchableHighlight>
  );
};

export type AvatarColorVariant =
  | 'base'
  | 'base-01'
  | 'base-02'
  | 'secondary'
  | 'secondary-01'
  | 'primary'
  | 'primary-01'
  | 'success'
  | 'success-01'
  | 'transparent';

export type AvatarSizeVariant = 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large';
export type AvatarShapeVariant = 'square' | 'circle';

type AvatarType = StyleSystemThemedProps & ViewProps & AvatarProps;
export type AvatarStatusVariants = 'online' | 'offline' | 'out-of-office';
export interface ViewProps extends ViewPropsBase {
  colorVariant?: AvatarColorVariant;
  sizeVariant?: AvatarSizeVariant;
}
export interface AvatarProps {
  onPress?: ((event: GestureResponderEvent) => void) | undefined;
  editable?: boolean;
  icon?: JSX.Element;
  uri?: string | null;
  shapeVariant?: AvatarShapeVariant;
  size?: number; // you have to pass size or sizeVariant
  title?: string;
  statusBorderVariant?: ColorName;
  status?: AvatarStatusVariants;
  titleColor?: ColorName;
  borderedColor?: ColorName;
  titleVariant?: TextVariant;
  bordered?: boolean;
  borderedWidth?: number;
  asset?: ImageSourcePropType;
}
