import React from 'react';
import { css, CSSProperties } from 'glamor';
import { Text } from '../components/Text';
import { Button, useApphouse, View } from '..';
import { Elevation } from '../styles/defaults/elevation.styles';
import { ApphouseComponent } from '../components/component.interfaces';
import { useLocalStyles } from '../styles/defaults/useLocalStyles';
import { observer } from 'mobx-react';
import { ThemeColors } from '../styles/defaults/themes.interface';

export type CardAnimationDirection = 'top' | 'bottom' | 'left' | 'right';
const gradient = `linear-gradient(-45deg, #f89b29 0%, #ff0f7b 100%)`;
export interface CardStyles {
  container?: CSSProperties;
  content?: CSSProperties;
  btn?: CSSProperties;
  title?: CSSProperties;
  subtitle?: CSSProperties;
  text?: CSSProperties;
}

const getAnimationDirectionStyles = (
  animationDirection: CardAnimationDirection
) => {
  switch (animationDirection) {
    case 'bottom':
      return {
        ':before': {
          right: 0,
          bottom: 0,
          width: '100%',
          height: '5px'
        },
        ':hover:before': {
          height: '100%'
        }
      };

    case 'top':
      return {
        ':before': {
          top: 0,
          left: 0,
          width: '100%',
          height: '5px'
        },
        ':hover:before': {
          height: '100%'
        }
      };

    case 'left':
      return {
        ':before': {
          top: 0,
          left: 0,
          width: '5px',
          height: '100%'
        },
        ':hover:before': {
          width: '100%'
        }
      };
    case 'right':
      return {
        ':before': {
          bottom: 0,
          right: 0,
          width: '5px',
          height: '100%'
        },
        ':hover:before': {
          width: '100%'
        }
      };
  }
};
const cardStyle = (
  colors: ThemeColors,
  backgroundColor: keyof ThemeColors,
  backgroundHoverColor: string
): CardStyles => ({
  container: {
    position: 'relative',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    width: '320px',
    boxShadow: '0 10px 20px rgba(0, 0, 0, 0.2)',
    padding: '32px',
    overflow: 'hidden',
    boxSizing: 'border-box',
    borderRadius: '10px',
    transition: 'all 0.5s cubic-bezier(0.23, 1, 0.320, 1)',
    '&:hover': {
      transform: 'translateY(-10px)',
      boxShadow: Elevation.depth8.boxShadow,
      color: '#FFFFFF',
      ':before': {
        width: '100%'
      },
      '& button': {
        border: 0,
        background: colors[backgroundColor],
        color: colors.onSurface10
      }
    },
    '::before': {
      content: "''",
      position: 'absolute',
      background: backgroundHoverColor,
      zIndex: -1,
      transition: 'all 0.5s cubic-bezier(0.23, 1, 0.320, 1)'
    }
  },
  content: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'flex-start',
    gap: '20px',
    color: colors.onSurface10,
    transition: 'all 0.5s cubic-bezier(0.23, 1, 0.320, 1)',
    ':hover': {
      color: '#FFFFFF'
    }
  },
  btn: {
    background: backgroundHoverColor,
    color: '#FFFFFF',
    textDecoration: 'none',
    border: 0,
    cursor: 'pointer',
    ':hover': {
      color: colors.onSurface10,
      background: colors[backgroundColor]
    }
  }
});
/**
 * A card component
 */
interface CardProps extends ApphouseComponent<CardStyles> {
  /**
   * The background color of the card on hover
   * @default gradient
   */
  backgroundHoverColor?: string;
  /**
   * The background color of the card
   * @default surface
   */
  backgroundColor?:
    | 'surface'
    | 'surface10'
    | 'surface20'
    | 'surface30'
    | 'surface40';
  /**
   * The title of the card
   */
  title?: string | React.ReactNode;
  /**
   * The subtitle of the card
   */
  subtitle?: string | React.ReactNode;
  /**
   * The text of the card
   */
  text?: string | React.ReactNode;
  /**
   * The text of the button
   */
  buttonText?: string;
  /**
   * The callback function to be executed when the button is clicked.
   */
  onClick?: () => void;
  /**
   * The alignment of the button
   * @default center
   * */
  buttonAlign?: 'left' | 'center' | 'right';
  /**
   * The direction of the animation
   * Starts from the direction and goes to the opposite direction
   * @default left
   */
  animationDirection?: CardAnimationDirection;
}

const getAlignment = (align: 'left' | 'center' | 'right') => {
  switch (align) {
    case 'left':
      return 'flex-start';
    case 'center':
      return 'center';
    case 'right':
      return 'flex-end';
    default:
      return 'center';
  }
};
export const Card: React.FC<CardProps> = observer((props) => {
  const {
    backgroundColor = 'surface',
    backgroundHoverColor = gradient,
    buttonAlign = 'center',
    animationDirection = 'left'
  } = props;
  const { theme } = useApphouse();
  const componentStyles = cardStyle(
    theme.colors,
    backgroundColor,
    backgroundHoverColor
  );
  const localStyles = useLocalStyles<CardStyles>(
    componentStyles,
    props.styleOverwrites,
    props.gutters
  );
  return (
    <div
      data-xray="Card"
      {...css(
        localStyles.container,
        getAnimationDirectionStyles(animationDirection)
      )}
      data-style="container"
    >
      <div {...css(componentStyles.content)} data-style="content">
        {typeof props.title === 'string' ? (
          <Text variant="header" styleOverwrites={localStyles.title}>
            {props.title}
          </Text>
        ) : (
          props.title
        )}

        {typeof props.subtitle === 'string' ? (
          <Text variant="subheader" styleOverwrites={localStyles.subtitle}>
            {props.subtitle}
          </Text>
        ) : (
          props.subtitle
        )}

        {typeof props.text === 'string' ? (
          <Text variant="standard" styleOverwrites={localStyles.text}>
            {props.text}
          </Text>
        ) : (
          props.text
        )}

        <View orientation="vertical" alignItems={getAlignment(buttonAlign)}>
          <Button variant="primary" styleOverwrites={localStyles.btn}>
            {props.buttonText}
          </Button>
        </View>
      </div>
    </div>
  );
});
