import React, { cloneElement, useMemo } from 'react';
import { Animated, PanResponder, Platform } from 'react-native';

import { Box } from '../Box';
import useTheme from '../../context/theme/useTheme';
import createSxStyle from '../../lib/sx';
import { BottomSheetProps } from './types';
import { Modal } from '../Modal';
import { Button } from '../Button';
import { CloseIcon } from '../../icons';
import { isValidChild } from '../../utils/render';
import { Text } from '../Text';
import { getOpacity } from '../../utils';

export const BottomSheet: React.FC<BottomSheetProps> = ({
  children,
  visible,
  onClose,
  fullScreen,
  sx,
  headerSx,
  styles,
  containerStyle,
  containerSx,
  contentStyle,
  contentSx,
  headerPan,
  title,
  height,
  width,
  headerStyle = {},
  animationType = 'slide',
  showHeaderPan = Platform.select({
    web: false,
    default: true,
  }),
  closeButton = (
    <Button
      mr={-1}
      size="small"
      bg="transparent"
      startContent={<CloseIcon size={16} />}
    />
  ),
  showCloseButton = Platform.select({
    default: false,
    web: true,
  }),
  ...rest
}) => {
  const isWeb = Platform.OS === 'web';
  const theme = useTheme();

  const pan = React.useRef(new Animated.Value(0)).current;

  const panResponder = React.useRef(
    PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onPanResponderTerminate: () => {
        Animated.spring(pan, {
          toValue: 0,
          useNativeDriver: false,
        }).start();
        onClose?.();
      },
      onPanResponderMove: (evt, gestureState) => {
        const isDown = gestureState.dy > 0;
        if (isDown) {
          const newY = Math.max(-10, Math.min(gestureState.dy, 10));
          pan.setValue(newY);
        }
      },
      onPanResponderRelease: () => {
        Animated.spring(pan, {
          toValue: 0,
          useNativeDriver: false,
        }).start();
        onClose?.();
      },
    })
  ).current;

  const header = useMemo(() => {
    if (title || isWeb) {
      return (
        <Box
          gap={2}
          width="100%"
          flexDirection="row"
          alignItems="center"
          justifyContent="space-between"
        >
          <Box>
            {isValidChild(title) ? (
              title
            ) : (
              <Text fontWeight="bold" size="base">
                {title}
              </Text>
            )}
          </Box>
          {showCloseButton && (
            <Box>
              {!!closeButton &&
                cloneElement(closeButton, {
                  onPress: onClose,
                })}
            </Box>
          )}
        </Box>
      );
    }

    return null;
  }, [closeButton, isWeb, onClose, showCloseButton, title]);

  return (
    <Modal
      p={0}
      position="bottom"
      visible={visible}
      onClose={onClose}
      closable={false}
      maskClosable={false}
      fullScreen={fullScreen}
      width={width ?? theme?.maxWidth}
      height={height ?? theme?.maxHeight}
      animationType={animationType}
      styles={styles}
      removePaddingRoot
      scrollProps={{
        alwaysBounceVertical: false,
      }}
      sx={{
        ...sx,
        mask: {
          ...sx?.mask,
          bg: 'rgba(0, 0, 0, 0.7)',
        },
        container: {
          ...sx?.container,
          roundedTop: 'modal',
          roundedBottom: 0,
        },
      }}
      {...rest}
      header={
        <Box
          style={contentStyle}
          sx={{
            width: '100%',
            justifyContent: 'center',
            alignItems: 'center',
            zIndex: 'max',
            ...contentSx,
          }}
        >
          {showHeaderPan && (
            <Box
              width="100%"
              alignItems="center"
              bg={getOpacity(theme.colors.get('background.foreground'), 0.02)}
            >
              <Animated.View
                {...panResponder.panHandlers}
                style={createSxStyle(
                  {
                    // py: 1,
                    transform: [{ translateY: pan }],
                    sx: headerSx,
                    style: Platform.select({
                      web: {
                        cursor: 'pointer',
                      },
                      default: headerStyle,
                    }),
                  },
                  theme
                )}
              >
                {headerPan ?? (
                  <Box
                    height={5}
                    width={50}
                    mt={1}
                    mb={1}
                    bg="text"
                    rounded={1}
                  />
                )}
              </Animated.View>
            </Box>
          )}

          {!!header && (
            <Box px={3} py={1} width="100%">
              {header}
            </Box>
          )}
        </Box>
      }
      {...rest}
    >
      <Modal.Content
        rounded="modal"
        py={2}
        // flex={fullScreen && 1}
        sx={{
          roundedBottom: 0,
          ...containerSx,
        }}
        style={containerStyle}
      >
        {children}
      </Modal.Content>
    </Modal>
  );
};
