import React, {FC, PropsWithChildren, useCallback, useMemo} from 'react';
import {StyleProp, ViewStyle, View} from 'react-native';
import {IconChevronRight, IconProps} from '@tabler/icons-react-native';
import {AvatarGroup, AvatarGroupProps} from '@components/_HuGo/AvatarGroup';
import {Avatar, AvatarProps} from '@components/_HuGo/Avatar';
import {ButtonSize, ButtonVariant, IconButton} from '@components/_HuGo/Button';
import {
  CardContainer,
  CardContainerProps,
} from '@components/_HuGo/CardContainer';
import {Title, TitleProps} from '@components/_HuGo/Title';
import {Pressable} from '@components/_core/Pressable';
import {Typography} from '@components/_core/Typography';
import {commonStyles} from '@shared/styles';
import {useTheme} from '@shared/theme';

import {styles} from './styles';

interface ListRowProps extends PropsWithChildren {
  style?: StyleProp<ViewStyle>;
  onPress?: () => void;
  disabled?: boolean;
  pressedColor?: string;
  backgroundColor?: string;
  accessible?: boolean;
}

interface ListRowSideContentProps {
  withRightIcon?: boolean;
  RightIconButton?: FC<IconProps>;
  onPressRightButton?: () => void;
  iconSize?: number;
  size?: ButtonSize;
  style?: StyleProp<ViewStyle>;
  variant?: ButtonVariant;
  disabled?: boolean;
  /** Small copetín shown above {@link value}. Only rendered when no icon/button is set. */
  label?: string;
  /** Main right-side text. Only rendered when no icon/button is set. */
  value?: string;
}

export function ListRow({
  children,
  style,
  onPress,
  pressedColor,
  backgroundColor,
  disabled = false,
  accessible,
}: ListRowProps) {
  const ref = React.useRef<Nullable<View>>(null);

  const onPressIn = useCallback(() => {
    if (pressedColor) {
      ref.current?.setNativeProps({
        style: {
          backgroundColor: pressedColor,
        },
      });
    }
  }, [ref, pressedColor]);

  const onPressOut = useCallback(() => {
    ref.current?.setNativeProps({
      style: {backgroundColor},
    });
  }, [ref, backgroundColor]);

  const combinedStyle = useMemo(() => [styles.container, style], [style]);

  return (
    <Pressable
      ref={ref}
      backgroundColor={backgroundColor}
      onPress={onPress}
      style={combinedStyle}
      onPressIn={pressedColor ? onPressIn : undefined}
      onPressOut={pressedColor ? onPressOut : undefined}
      disabled={disabled}
      accessible={accessible}>
      {children}
    </Pressable>
  );
}

function ListRowAvatar(props: AvatarProps) {
  return <Avatar {...props} />;
}

function ListRowAvatarGroup(props: AvatarGroupProps) {
  return <AvatarGroup {...props} />;
}

// TODO: Remove flex style, We should create a new wrap component: ListRow.Content
function ListRowTitle({flex = true, ...props}: TitleProps & {flex?: boolean}) {
  return (
    <Title
      {...props}
      size={props.size || 's'}
      style={[flex && commonStyles.flex, props.style]}
    />
  );
}

function ListRowSideContent({
  withRightIcon,
  RightIconButton,
  onPressRightButton,
  iconSize,
  size,
  style,
  variant,
  disabled,
  label,
  value,
}: ListRowSideContentProps) {
  const {iconSizes, spacing, theme} = useTheme();

  if (withRightIcon) {
    return (
      <IconChevronRight
        size={iconSize || iconSizes.x6}
        color={theme.text.neutral[disabled ? 'disabled' : 'default']}
        style={style}
      />
    );
  }

  if (RightIconButton) {
    return (
      <IconButton
        hitSlop={spacing.x1}
        Icon={RightIconButton}
        onPress={onPressRightButton}
        variant={variant || 'tertiary'}
        size={size}
        style={style}
      />
    );
  }

  if (label || value) {
    return (
      <View style={[styles.sideTextContainer, style]}>
        {!!label && (
          <Typography
            variant="xxs"
            weight="regular"
            color={theme.text.neutral.lighter}>
            {label}
          </Typography>
        )}
        {!!value && (
          <Typography
            variant="m"
            weight="semiBold"
            color={theme.text.neutral.brand}>
            {value}
          </Typography>
        )}
      </View>
    );
  }

  return null;
}

function ListCardContainer(props: CardContainerProps) {
  return <CardContainer {...props} />;
}

ListRow.Avatar = ListRowAvatar;
ListRow.AvatarGroup = ListRowAvatarGroup;
ListRow.Title = ListRowTitle;
ListRow.SideContent = ListRowSideContent;
ListRow.CardContainer = ListCardContainer;
