import React, {useCallback, useEffect, useState} from 'react';
import {Share} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useMutation, useQueryClient} from 'react-query';
import {useDispatch} from 'react-redux';
import {useNavigation} from '@react-navigation/native';
import {
  IconCalendarPlus,
  IconDotsVertical,
  IconEdit,
  IconShare2,
  IconTrash,
  IconUserDown,
} from '@tabler/icons-react-native';
import {Typography, Dialog, IconButton, ListItem, Spinner} from '@components';
import {useGoBack} from '@hooks/useGoBack';
import {EVENTS_QUERY_KEYS} from '@modules/events/constants';
import {WorkEvent} from '@modules/events/interfaces';
import {deleteEvent} from '@modules/events/services';
import {useCalendarApp} from '@modules/events/hooks/useCalendarApp';
import {showSnackbar} from '@redux/events';
import {Screens} from '@shared/constants';
import {HUMAND_URL} from '@shared/keys';

import {styles} from './styles';
import {exportGuestList} from './utils';

interface Props {
  event: WorkEvent;
  isPastEvent: boolean;
  isOrgByMe: boolean;
  canManageEvent: boolean;
}

function EventOptionsDialog({
  event,
  isPastEvent,
  isOrgByMe,
  canManageEvent,
}: Props) {
  const dispatch = useDispatch();
  const {t} = useTranslation();
  const {goBack} = useGoBack();
  const queryClient = useQueryClient();
  const navigation = useNavigation();
  const [showDeleteText, setShowDeleteText] = useState(false);
  const [isDownloadingFile, setIsDownloadingFile] = useState(false);
  const [showDialog, setShowDialog] = useState(false);
  const {scheduleEventInCalendarApp} = useCalendarApp(event);

  const onClose = useCallback(() => {
    setShowDialog(false);
    setShowDeleteText(false);
  }, []);

  const {mutate: onDeleteEvent, isLoading} = useMutation(deleteEvent, {
    onSuccess: () => {
      onClose();
      if (isPastEvent) {
        queryClient.invalidateQueries(EVENTS_QUERY_KEYS.pastEvents);
      } else {
        queryClient.invalidateQueries(EVENTS_QUERY_KEYS.upcomingEvents);
        queryClient.invalidateQueries(EVENTS_QUERY_KEYS.invitationEvents);
      }
      if (isOrgByMe) {
        queryClient.invalidateQueries(EVENTS_QUERY_KEYS.organizedByMeEvents);
      }
      goBack();
      dispatch(showSnackbar({title: t('events.delete_event_success')}));
    },
  });

  useEffect(() => {
    const headerRight = () => (
      <IconButton
        Icon={IconDotsVertical}
        onPress={() => setShowDialog(true)}
        hitSlop={16}
        variant="tertiary"
      />
    );
    // TODO: Try to use Header component instead of Navigation's header
    event && navigation.setOptions({headerRight, headerTitle: event.name});
  }, [event, navigation]);

  const onPressEdit = () => {
    onClose();
    navigation.navigate(Screens.EVENT_CREATION, {event});
  };

  const onPressDelete = () => setShowDeleteText(true);

  const onCancelDelete = () => setShowDeleteText(false);

  const onConfirmDelete = () => onDeleteEvent(event.id);

  const onPressAddToCalendar = () => {
    scheduleEventInCalendarApp(onClose);
  };

  const onPressExportGuestList = useCallback(async () => {
    if (!isDownloadingFile) {
      setIsDownloadingFile(true);
      await exportGuestList(event);
      setIsDownloadingFile(false);
    }
  }, [event, isDownloadingFile]);

  const onPressShare = () => {
    onClose();
    Share.share({
      message: `${HUMAND_URL}events/${event.id}`,
      title: t('events.share_event_link_title'),
    });
  };

  return (
    <Dialog
      isVisible={showDialog}
      onClose={onClose}
      title={t(
        `events.${showDeleteText ? 'delete_event_title' : 'event_options'}`,
      )}
      titleNumberOfLines={2}
      footer={
        showDeleteText
          ? {
              primaryButton: {
                isLoading,
                text: t('general.delete'),
                onPress: onConfirmDelete,
              },
              secondaryButton: {
                text: t('general.cancel'),
                onPress: onCancelDelete,
              },
            }
          : undefined
      }>
      {showDeleteText ? (
        <Typography>
          {t('events.delete_event_description', {event: event.name})}
        </Typography>
      ) : (
        <>
          <ListItem
            avatar={{Icon: IconShare2}}
            onItemPress={onPressShare}
            title={t('events.share_event_link_title')}
            description={t('events.share_event_link_description')}
            style={styles.listItem}
            descriptionNumberOfLines={2}
          />
          <ListItem
            avatar={{Icon: IconCalendarPlus}}
            onItemPress={onPressAddToCalendar}
            title={t('events.add_to_calendar')}
            description={t('events.add_to_calendar_description')}
            style={styles.listItem}
            descriptionNumberOfLines={2}
          />
          {canManageEvent && (
            <ListItem
              avatar={{Icon: IconUserDown}}
              onItemPress={onPressExportGuestList}
              title={t('events.export_guest_list')}
              description={t('events.export_guest_list_description')}
              style={styles.listItem}
              descriptionNumberOfLines={2}>
              {isDownloadingFile ? <Spinner /> : null}
            </ListItem>
          )}
          {canManageEvent && !isPastEvent && (
            <ListItem
              avatar={{Icon: IconEdit}}
              onItemPress={onPressEdit}
              title={t('general.edit')}
              description={t('events.edit_description')}
              style={styles.listItem}
              descriptionNumberOfLines={2}
            />
          )}
          {canManageEvent && (
            <ListItem
              avatar={{Icon: IconTrash}}
              onItemPress={onPressDelete}
              title={t('general.delete')}
              description={t('events.delete_description')}
              style={styles.listItem}
              descriptionNumberOfLines={2}
            />
          )}
        </>
      )}
    </Dialog>
  );
}

export default EventOptionsDialog;
