import React, {useCallback, useState} from 'react';
import {View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {IconEyeOff} from '@tabler/icons-react-native';
import {useMutation} from 'react-query';
import {Button, Pill, Typography} from '@components';
import {Poll} from '@interfaces/poll';
import {voteGroupPoll} from '@modules/group/services';
import {VotersData} from '@modules/post/interfaces';
import {changeOptionVote} from '@modules/post/services';
import {addPollVote} from '@modules/post/store';
import {updateFeedPost, updatePostDetail} from '@modules/post/utils';
import {useUser} from '@redux/selectors';
import {capitalize, isBefore} from '@shared/utils';
import {useTheme} from '@shared/theme';
import {commonStyles} from '@shared/styles';
import {useCommunityFeature} from '@stores/communityFeatures';

import {styles} from './styles';
import VotersBottomSheet from './components/VotersBottomSheet';
import PollItem from './components/PollItem';
import {getTimeRemaining} from './utils';

interface Props {
  canInteract: boolean;
  groupId?: number;
  poll: Poll;
  postId: number;
}

function PostPoll({canInteract, groupId, poll, postId}: Props) {
  const {t} = useTranslation();
  const {iconSizes, theme} = useTheme();
  const user = useUser();
  const canViewGroupPostsInFeed = useCommunityFeature(
    'VIEW_GROUP_POSTS_IN_FEED',
  );
  const [pollOptionSelected, setPollOptionSelected] = useState(-1);
  const [votersData, setVotersData] = useState<Nullable<VotersData>>(null);
  const {mutate, isLoading} = useMutation(
    ({pollOptionIndexSelected}: {pollOptionIndexSelected: number}) => {
      const commonParams = {
        pollId: poll.id,
        postId,
        optionId: poll.pollOptions[pollOptionIndexSelected].id,
        ...(!poll.pollConfiguration.isAnonymous && {user}),
      };
      return groupId
        ? voteGroupPoll({...commonParams, groupId})
        : changeOptionVote(commonParams);
    },
    {
      onSuccess: (_, {pollOptionIndexSelected}) => {
        if (!groupId || canViewGroupPostsInFeed) {
          const updater = addPollVote({
            postId,
            optionIndex: pollOptionIndexSelected,
            user: poll.pollConfiguration.isAnonymous ? undefined : user,
          });
          updateFeedPost(postId, updater);
          updatePostDetail(postId, updater);
        }
      },
    },
  );
  const noOptionSelected = pollOptionSelected === -1;
  const isPollFinished =
    !!poll.pollConfiguration.endsAt &&
    isBefore(poll.pollConfiguration.endsAt, new Date());

  const onShowVoters = useCallback(
    (params: VotersData) => () => {
      setVotersData(params);
    },
    [],
  );

  const onCloseVoters = useCallback(() => {
    setVotersData(null);
  }, []);

  const handlePollOptionPress = useCallback(
    (index: number) => () => {
      !poll.hasBeenAnswered && setPollOptionSelected(index);
    },
    [poll.hasBeenAnswered],
  );

  const onVotePoll = useCallback(() => {
    if (poll) {
      mutate({
        pollOptionIndexSelected: pollOptionSelected,
      });
    }
  }, [poll, mutate, pollOptionSelected]);

  return (
    <>
      <View style={styles.pollContainer}>
        {!!poll.pollConfiguration.endsAt && (
          <Pill
            variant={isPollFinished ? 'warning' : 'info'}
            text={
              isPollFinished
                ? t('post.poll_finished')
                : getTimeRemaining(poll.pollConfiguration.endsAt)
            }
            size="md"
            withIcon
          />
        )}
        {!poll.hasBeenAnswered && poll.pollConfiguration.isAnonymous && (
          <View style={styles.hiddenTextContainer}>
            <IconEyeOff size={iconSizes.x6} color={theme.neutralText} />
            <Typography style={commonStyles.flex}>
              {t('post.name_is_hidden')}
            </Typography>
          </View>
        )}
        {poll.pollOptions.map((pollOption, index) => (
          <PollItem
            key={index}
            pollOption={pollOption}
            index={index}
            pollOptionSelected={pollOptionSelected}
            onShowVoters={onShowVoters}
            postId={postId}
            groupId={groupId}
            handlePollOptionPress={handlePollOptionPress}
            poll={poll}
            disabled={isPollFinished && !poll.hasBeenAnswered}
          />
        ))}
      </View>
      <Typography weight="semiBold" style={styles.voteCount}>
        {t('post.vote_count', {count: poll.totalAnswerCount})}
      </Typography>
      {!poll.hasBeenAnswered && (
        <View style={styles.answerContainer}>
          <Button
            variant="primary"
            size="sm"
            text={capitalize(t('post.vote')) ?? ''}
            disabled={
              !canInteract || noOptionSelected || isLoading || isPollFinished
            }
            onPress={onVotePoll}
            isLoading={isLoading && !isPollFinished}
          />
        </View>
      )}
      {!!votersData && (
        <VotersBottomSheet onClose={onCloseVoters} data={votersData} />
      )}
    </>
  );
}

export default PostPoll;
