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

const variants: Record<TouchableTileVariant, ViewStyle> = {
  active: {
    borderWidth: 1,
    borderColor: 'transparent',
    backgroundColor: 'primary-01',
  },
  hover: {
    borderWidth: 1,
    borderColor: 'transparent',
    backgroundColor: 'base-02-hover',
  },
  base: {
    borderWidth: 1,
    borderColor: 'transparent',
    backgroundColor: 'base',
  },
  'base-01': {
    borderWidth: 1,
    borderColor: 'transparent',
    backgroundColor: 'base-01',
  },
  outline: {
    borderWidth: 1,
    borderColor: 'divider',
    backgroundColor: 'transparent',
  },
  'outline-active': {
    borderWidth: 1,
    borderColor: 'primary',
    backgroundColor: 'primary-01',
  },
  text: {
    borderWidth: 1,
    borderColor: 'transparent',
    backgroundColor: 'transparent',
  },
};
const sizeVariants: Record<TouchableTileSizeVariant, ViewStyle> = {
  undefined: {
    height: undefined,
  },
  content: {
    height: undefined,
  },
  'extra-small': {
    height: 25,
  },
  small: {
    height: 30,
  },
  medium: {
    height: 35,
  },
  large: {
    height: 40,
  },
  'extra-large': {
    height: 45,
  },
  '2-extra-large': {
    height: 50,
  },
};

const shapeVariants: Record<TouchableTileShapeVariant, ViewStyle> = {
  square: {
    borderRadius: 0,
  },
  round: {
    borderRadius: 'button',
  },
};

const TouchableTileLocal = styled(TouchableHighlight)<TouchableHighlightProps>(
  styledVariant({
    variants,
  }),
  styledVariant({
    prop: 'sizeVariant',
    variants: sizeVariants,
  }),
  styledVariant({
    prop: 'shapeVariant',
    variants: shapeVariants,
  }),
  {
    justifyContent: 'center',
  }
);
const UnderlayColors: Record<TouchableTileVariant, string> = {
  outline: COLOR_VALUES['underlay-primary'],
  base: COLOR_VALUES['underlay-primary'],
  'base-01': COLOR_VALUES['underlay-primary'],
  'outline-active': COLOR_VALUES['underlay-primary'],
  text: COLOR_VALUES['underlay-primary'],
  active: COLOR_VALUES['underlay-primary'],
  hover: COLOR_VALUES['underlay-dark-06'],
};

const TextVariants: Record<TouchableTileVariant, ColorName> = {
  outline: 'body',
  'outline-active': 'title',
  text: 'body',
  active: 'title',
  hover: 'title',
  base: 'title',
  'base-01': 'title',
};

export const TouchableTile: React.FC<TouchableTileType> = ({
  title,
  caption,
  centerElement,
  isCollapsed,
  leftElement,
  underlayColorVariant,
  rightElement,
  titleColor,
  variant,
  isHoverAllowed = true,
  collapsedWidth,
  shapeVariant = 'round',
  titleVariant = 'body',
  sizeVariant,
  px = 'xs',
  ...props
}) => {
  const typeRef = useRef(null);
  const ml = leftElement ? '2xs' : null;
  const width = isCollapsed ? collapsedWidth : undefined;
  const isHovered = useHover(typeRef);
  const localVariant = isHoverAllowed && isHovered ? 'hover' : variant;

  return (
    <TouchableTileLocal
      ref={typeRef}
      underlayColor={underlayColorVariant || UnderlayColors[variant]}
      sizeVariant={sizeVariant}
      shapeVariant={shapeVariant}
      variant={localVariant}
      width={width}
      px={px}
      {...props}
    >
      <>
        <Visible if={isCollapsed}>
          <Container alignItems="center" justifyContent="center">
            {leftElement}
          </Container>
        </Visible>
        <Visible if={!isCollapsed}>
          <Row justifyContent="space-between">
            <Row alignItems="center" flexShrink={1}>
              {leftElement}
              <Col ml={ml} flexShrink={1}>
                {centerElement || (
                  <Visible if={!!title}>
                    <Text
                      flexShrink={1}
                      variant={titleVariant}
                      color={titleColor || TextVariants[variant]}
                    >
                      {title}
                    </Text>
                  </Visible>
                )}

                <Visible if={!!caption}>
                  <Text variant="caption-01">{caption}</Text>
                </Visible>
              </Col>
            </Row>
            <Row alignItems="center">{rightElement}</Row>
          </Row>
        </Visible>
      </>
    </TouchableTileLocal>
  );
};

type TouchableTileShapeVariant = 'square' | 'round';
export type TouchableTileVariant =
  | 'active'
  | 'hover'
  | 'base'
  | 'base-01'
  | 'outline'
  | 'outline-active'
  | 'text';
export type TouchableTileSizeVariant =
  | 'undefined'
  | 'content'
  | 'extra-small'
  | 'small'
  | 'medium'
  | 'large'
  | 'extra-large'
  | '2-extra-large';

export type TouchableTileType = StyleSystemThemedProps &
  TouchableHighlightProps &
  TouchableTileProps;
interface TouchableHighlightProps extends TouchableHighlightPropsBase {
  variant: TouchableTileVariant;
  sizeVariant?: TouchableTileSizeVariant;
  shapeVariant?: TouchableTileShapeVariant;
}

export interface TouchableTileProps {
  caption?: string | null;
  title?: string;
  titleColor?: ColorName;
  centerElement?: JSX.Element;
  leftElement?: JSX.Element;
  rightElement?: JSX.Element;
  titleVariant?: TextVariant;
  isCollapsed?: boolean;
  isHoverAllowed?: boolean;
  collapsedWidth?: number;
  icon?: JSX.Element;
  underlayColorVariant?: ColorName;
}
