import React, { useRef } from 'react';
import styled from '@emotion/native';
import { ColorName, ViewStyle } from '@emotion/react';
import { StyleSystemThemedProps, TouchableHighlight } from 'components/layout';
import { TouchableHighlightProps as TouchableHighlightPropsBase } from 'react-native';
import { variant } from 'styled-system';
import { COLOR_VALUES } from 'theme/color';
import { useHover } from 'react-native-web-hooks';

const variants: Record<FabVariant, ViewStyle> = {
  outline: {
    borderWidth: 1,
    borderColor: 'divider',
    backgroundColor: 'transparent',
  },
  'outline-dashed': {
    borderWidth: 1,
    borderColor: 'caption',
    borderStyle: 'dashed',
    backgroundColor: 'transparent',
  },
  plain: {
    backgroundColor: 'transparent',
  },
};
const sizeVariants: Record<FabSizeVariant, ViewStyle> = {
  'extra-small': {
    height: 25,
    width: 25,
  },
  small: {
    height: 30,
    width: 30,
  },
  medium: {
    height: 35,
    width: 35,
  },
  large: {
    height: 40,
    width: 40,
  },
  'extra-large': {
    height: 50,
    width: 50,
  },
};

const colorVariants: Record<FabColorVariant, ViewStyle> = {
  primary: {
    backgroundColor: 'primary',
  },
  'primary-hover': {
    backgroundColor: 'primary-hover',
  },
  base: {
    backgroundColor: 'base',
  },
  'base-01': {
    backgroundColor: 'base-01',
  },
  'base-02': {
    backgroundColor: 'base-02',
  },
  'base-02-hover': {
    backgroundColor: 'base-02-hover',
  },
  'base-opacity-05': {
    backgroundColor: 'base-opacity-05',
  },
  'base-opacity-06': {
    backgroundColor: 'base-opacity-06',
  },
  'base-hover': {
    backgroundColor: 'base-hover',
  },
  body: {
    backgroundColor: 'body',
  },
  success: {
    backgroundColor: 'success',
  },
  'success-01': {
    backgroundColor: 'success-01',
  },
  secondary: {
    backgroundColor: 'secondary',
  },
  'secondary-01': {
    backgroundColor: 'secondary-01',
  },
  'secondary-hover': {
    backgroundColor: 'secondary-hover',
  },
  transparent: {
    backgroundColor: 'transparent',
  },
};

const fabSizeVariants: Record<FabSizeVariant, number> = {
  'extra-small': 25,
  small: 30,
  medium: 35,
  large: 40,
  'extra-large': 50,
};

const fabBorderRadius: Record<FabSizeVariant, number> = {
  'extra-small': 5,
  small: 6,
  medium: 8,
  large: 10,
  'extra-large': 11,
};

const FabLocal = styled(TouchableHighlight)<TouchableHighlightProps>(
  variant({
    variants,
  }),
  variant({
    prop: 'sizeVariant',
    variants: sizeVariants,
  }),
  variant({
    prop: 'colorVariant',
    variants: colorVariants,
  }),
  {
    alignItems: 'center',
    justifyContent: 'center',
  }
);
const UnderlayColors: Record<FabVariant, string> = {
  outline: COLOR_VALUES['underlay-primary'],
  'outline-dashed': COLOR_VALUES['underlay-primary'],
  plain: COLOR_VALUES['underlay-dark'],
};

export const Fab: React.FC<FabType> = ({
  centerElement,
  size = 25,
  sizeVariant,
  colorVariant,
  shapeVariant = 'circle',
  hoverColorVariant,
  underlayColor,
  ...props
}) => {
  const fabRef = useRef(null);
  const isHovered = useHover(fabRef);

  const localSize = sizeVariant ? fabSizeVariants[sizeVariant] : size || fabSizeVariants.medium;
  const localBorderRadius = sizeVariant ? fabBorderRadius[sizeVariant] : size * 0.2;
  const borderRadius = shapeVariant === 'circle' ? localSize / 2 : localBorderRadius;
  const localColorVariant = isHovered ? hoverColorVariant || 'primary-hover' : colorVariant;
  const underlayColorLocal = underlayColor || UnderlayColors[props.variant];
  const localSizeOptional = !sizeVariant ? size : undefined;
  return (
    <FabLocal
      ref={fabRef}
      borderRadius={borderRadius}
      sizeVariant={sizeVariant}
      width={localSizeOptional}
      height={localSizeOptional}
      underlayColor={underlayColorLocal}
      colorVariant={localColorVariant}
      {...props}
    >
      {centerElement}
    </FabLocal>
  );
};

export type FabVariant = 'outline' | 'outline-dashed' | 'plain';
export type FabSizeVariant = 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large';
export type FabColorVariant =
  | 'transparent'
  | 'primary'
  | 'primary-hover'
  | 'base'
  | 'base-hover'
  | 'base-01'
  | 'base-02'
  | 'base-02-hover'
  | 'base-opacity-05'
  | 'base-opacity-06'
  | 'body'
  | 'success'
  | 'success-01'
  | 'secondary'
  | 'secondary-01'
  | 'secondary-hover';

export type AvatarShapeVariant = 'round' | 'circle';

type FabType = StyleSystemThemedProps & TouchableHighlightProps & FabProps;
export interface TouchableHighlightProps extends TouchableHighlightPropsBase {
  variant: FabVariant;
  sizeVariant?: FabSizeVariant;
  shapeVariant?: AvatarShapeVariant;
  colorVariant: FabColorVariant;
}

export interface FabProps {
  size?: number;
  centerElement?: JSX.Element;
  hoverColorVariant?: FabColorVariant;
  underlayColor?: ColorName;
}
