import React, {Fragment, useCallback, useMemo, useState} from 'react';
import {View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {
  IconArrowRight,
  IconChevronRight,
  IconPinned,
  IconPinnedOff,
} from '@tabler/icons-react-native';
import {
  CardContainer,
  Dialog,
  Divider,
  Typography,
  Pressable,
} from '@components';
import {useMessageActions} from '@modules/chats/hooks';
import {usePinnedMessagesForChannel} from '@modules/chats/store';
import {useMessagesListMethodsRef} from '@modules/chats/contexts';
import {useTheme} from '@shared/theme';
import {useFeatureFlag} from '@stores/featureFlags';

import {PinnedMessage} from './components/PinnedMessage';
import {PinnedMessagesSheet} from './components/PinnedMessagesSheet';
import {usePinnedMessageDisplay} from './hooks/usePinnedMessageDisplay';
import {styles} from './styles';

interface Props {
  channel: string;
}

export function PinnedMessages({channel}: Props) {
  const {t} = useTranslation();
  const {theme, iconSizes} = useTheme();
  const isPinMessageEnabled = useFeatureFlag('CHATS_V2_PIN_MESSAGE');
  const {pinned} = usePinnedMessagesForChannel(channel);
  const {togglePin} = useMessageActions({channel});
  const messagesListMethodsRef = useMessagesListMethodsRef();
  const [selectedIndex, setSelectedIndex] = useState(0);
  const [isSheetVisible, setIsSheetVisible] = useState(false);
  const [isLongPressVisible, setIsLongPressVisible] = useState(false);

  const safeIndex = pinned.length === 0 ? 0 : selectedIndex % pinned.length;

  const onOpenSheet = useCallback(() => {
    setIsSheetVisible(true);
  }, []);

  const onCloseSheet = useCallback(() => {
    setIsSheetVisible(false);
  }, []);

  const onSheetNavigateToMessage = useCallback(
    (ts: string) => {
      const index = pinned.findIndex(m => m.ts === ts);
      if (index !== -1) {
        setSelectedIndex(index);
      }
    },
    [pinned],
  );

  const onCloseLongPress = useCallback(() => {
    setIsLongPressVisible(false);
  }, []);

  const onSheetUnpin = useCallback(
    (clientMsgId: string) => togglePin({clientMsgId}),
    [togglePin],
  );

  const currentMessage = pinned[safeIndex] ?? pinned[0];
  const hasMultiple = pinned.length > 1;

  const onPress = useCallback(() => {
    if (!currentMessage) {
      return;
    }
    if (hasMultiple) {
      const nextIndex = (safeIndex + 1) % pinned.length;
      const nextMessage = pinned[nextIndex];
      setSelectedIndex(nextIndex);
      messagesListMethodsRef?.current?.scrollToMessageByTs(nextMessage.ts);
    } else {
      messagesListMethodsRef?.current?.scrollToMessageByTs(currentMessage.ts);
    }
  }, [currentMessage, hasMultiple, safeIndex, pinned, messagesListMethodsRef]);

  const onLongPress = useCallback(() => {
    setIsLongPressVisible(true);
  }, []);

  const onUnpin = useCallback(() => {
    onCloseLongPress();
    if (currentMessage) {
      togglePin({clientMsgId: currentMessage.client_msg_id});
    }
  }, [onCloseLongPress, togglePin, currentMessage]);

  const onGoToMessage = useCallback(() => {
    onCloseLongPress();
    if (currentMessage) {
      messagesListMethodsRef?.current?.scrollToMessageByTs(currentMessage.ts);
    }
  }, [onCloseLongPress, currentMessage, messagesListMethodsRef]);

  const pinnedDisplay = usePinnedMessageDisplay({
    message: currentMessage,
  });

  const longPressOptions = useMemo(
    () => [
      {
        key: 'unpin',
        label: t('chat.pin.unpin'),
        Icon: IconPinnedOff,
        onPress: onUnpin,
      },
      {
        key: 'go_to',
        label: t('chat.pin.go_to_message'),
        Icon: IconArrowRight,
        onPress: onGoToMessage,
      },
    ],
    [t, onUnpin, onGoToMessage],
  );

  if (!isPinMessageEnabled || pinned.length === 0) {
    return null;
  }

  return (
    <>
      <Pressable
        onPress={onPress}
        onLongPress={onLongPress}
        style={[
          styles.container,
          {backgroundColor: theme.background.elements.overlay},
        ]}>
        {hasMultiple && (
          <View style={styles.marksContainer}>
            {pinned.map((message, index) => (
              <View
                key={message.ts}
                style={[
                  styles.messageMark,
                  {
                    backgroundColor:
                      index === safeIndex
                        ? theme.brand[500]
                        : theme.background.elements.grey,
                  },
                ]}
              />
            ))}
          </View>
        )}
        <View
          style={[
            styles.iconContainer,
            {backgroundColor: theme.background.elements.grey},
          ]}>
          <IconPinned
            width={iconSizes.x6}
            height={iconSizes.x6}
            color={theme.text.neutral.default}
          />
        </View>
        <PinnedMessage {...pinnedDisplay} />
        {hasMultiple && (
          <Pressable onPress={onOpenSheet} style={styles.chevronContainer}>
            <IconChevronRight
              width={iconSizes.x6}
              height={iconSizes.x6}
              color={theme.text.neutral.default}
            />
          </Pressable>
        )}
      </Pressable>
      <Dialog
        isVisible={isLongPressVisible}
        onClose={onCloseLongPress}
        title={pinnedDisplay.displayText}>
        <CardContainer style={styles.optionsContainer}>
          {longPressOptions.map((option, index) => (
            <Fragment key={option.key}>
              <Pressable onPress={option.onPress} style={styles.optionRow}>
                <Typography
                  variant="xs"
                  weight="semiBold"
                  color={theme.text.neutral.default}
                  style={styles.optionLabel}>
                  {option.label}
                </Typography>
                <option.Icon
                  size={iconSizes.x6}
                  color={theme.text.neutral.default}
                />
              </Pressable>
              {index !== longPressOptions.length - 1 && <Divider />}
            </Fragment>
          ))}
        </CardContainer>
      </Dialog>
      <PinnedMessagesSheet
        channel={channel}
        pinned={pinned}
        isVisible={isSheetVisible}
        onClose={onCloseSheet}
        onUnpin={onSheetUnpin}
        onNavigateToMessage={onSheetNavigateToMessage}
      />
    </>
  );
}
