import React, { PropsWithChildren, useRef } from 'react';
import { Animated, StyleSheet, Text, View } from 'react-native';
import { RectButton, Swipeable } from 'react-native-gesture-handler';
import { Colors } from 'src/theme';
import { getFontSize } from 'src/utils';
import { SheetManager } from 'react-native-actions-sheet';

import PinIcon from 'assets/icons/messages/pin.svg';
import ArchiveIcon from 'assets/icons/messages/archive.svg';
import DotsIcon from 'assets/icons/messages/dots.svg';
import UnpinIcon from 'assets/icons/messages/unpin.svg';
import { ChatProps } from '../types';
import { usePostSetArchiveMutation, usePostSetPinMutation } from '@api/chat';

interface AppleStyleSwipeableRowProps extends PropsWithChildren<unknown> {
  chat: ChatProps;
  token: string;
  onRowOpen: (ref: any) => void;
  refetch: () => void;
}

const SwipeableRow: React.FC<AppleStyleSwipeableRowProps> = ({
  children,
  chat,
  token,
  onRowOpen,
  refetch
}) => {
  const swipeableRow = useRef<Swipeable>(null);

  const { mutateAsync: pinChat } = usePostSetPinMutation();
  const { mutateAsync: archiveChat } = usePostSetArchiveMutation();

  const close = () => {
    swipeableRow.current?.close();
  };

  const renderRightAction = (
    text: string,
    color: string,
    x: number,
    progress: Animated.AnimatedInterpolation<number>
  ) => {
    const trans = progress.interpolate({
      inputRange: [0, 1],
      outputRange: [x, 0]
    });

    const pressHandler = async () => {
      close();
      if (text === 'More') {
        SheetManager.show('more-modal', {
          payload: {
            id: chat.id,
            name: chat.name,
            avatar: chat.avatar
          } as any
        });
      } else {
        await archiveChat({
          token,
          value: chat.archive === 1 ? 0 : 1,
          conversation_with_user: chat.id
        });
        refetch();
      }
    };

    return (
      <Animated.View style={{ flex: 1, transform: [{ translateX: trans }] }}>
        <RectButton style={[styles.rightAction, { backgroundColor: color }]} onPress={pressHandler}>
          {text === 'More' ? (
            <DotsIcon height={18} width={18} />
          ) : (
            <ArchiveIcon height={18} width={18} />
          )}
          <Text style={styles.actionText}>{text}</Text>
        </RectButton>
      </Animated.View>
    );
  };

  const renderLeftAction = (
    text: string,
    color: string,
    x: number,
    progress: Animated.AnimatedInterpolation<number>
  ) => {
    const trans = progress.interpolate({
      inputRange: [0, 1],
      outputRange: [-x, 0]
    });

    const pressHandler = async () => {
      close();
      await pinChat({
        token,
        value: chat.pin === 1 ? 0 : 1,
        conversation_with_user: chat.id
      });
      refetch();
    };

    return (
      <Animated.View style={{ flex: 1, transform: [{ translateX: trans }] }}>
        <RectButton style={[styles.rightAction, { backgroundColor: color }]} onPress={pressHandler}>
          {chat.pin === 1 ? <UnpinIcon width={18} /> : <PinIcon width={18} />}
          <Text style={styles.actionText}>{text}</Text>
        </RectButton>
      </Animated.View>
    );
  };

  const renderRightActions = (progress: Animated.AnimatedInterpolation<number>) => (
    <View
      style={{
        width: 168,
        flexDirection: 'row'
      }}
    >
      {renderRightAction(
        chat.archive === 0 ? 'Archive' : 'Unarchive',
        Colors.BORDER_LIGHT,
        168,
        progress
      )}
      {renderRightAction('More', Colors.FILL_LIGHT, 112, progress)}
    </View>
  );

  const renderLeftActions = (progress: Animated.AnimatedInterpolation<number>) => (
    <View
      style={{
        width: 84,
        flexDirection: 'row'
      }}
    >
      {renderLeftAction(chat.pin === 1 ? 'Unpin' : 'Pin', Colors.FILL_LIGHT, 84, progress)}
    </View>
  );

  return (
    <Swipeable
      ref={swipeableRow}
      friction={2}
      enableTrackpadTwoFingerGesture
      rightThreshold={40}
      renderRightActions={renderRightActions}
      renderLeftActions={renderLeftActions}
      onSwipeableOpenStartDrag={() => {
        onRowOpen(swipeableRow.current);
      }}
    >
      {children}
    </Swipeable>
  );
};

const styles = StyleSheet.create({
  actionText: {
    color: Colors.DARK_BLUE,
    fontSize: getFontSize(12),
    fontWeight: '600',
    backgroundColor: 'transparent'
  },
  rightAction: {
    alignItems: 'center',
    flex: 1,
    justifyContent: 'center',
    gap: 12
  }
});

export default SwipeableRow;
