import React, {useState} from 'react';
import {Pressable, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useMutation} from 'react-query';
import {
  KeyboardAwareScrollView,
  KeyboardStickyView,
} from 'react-native-keyboard-controller';
import {ImageOrVideo} from 'react-native-image-crop-picker';
import {IconArticle} from '@tabler/icons-react-native';
import {
  CardContainer,
  Typography,
  Button,
  InputTextArea,
  Switch,
} from '@components';
import {queryClient} from '@config/queryClient';
import {useSafeAreaBottomPadding} from '@hooks/useSafeAreaBottomPadding';
import {useGoBack} from '@hooks/useGoBack';
import {Icon, IconTypes, PublicIcon} from '@interfaces/icon';
import {Navigation} from '@interfaces/navigation';
import {UserPermissions} from '@interfaces/user';
import {
  createGroup,
  updateGroupBanner,
  updateGroupConfiguration,
} from '@modules/group/services';
import {
  ApprovalPolicy,
  PrivacyPolicy,
  PublicationPolicy,
} from '@modules/group/interfaces';
import PolicyModal from '@modules/group/components/PolicyModal';
import GroupIconModalPicker from '@modules/group/components/GroupIconModalPicker';
import {DEFAULT_GROUP_ICON} from '@modules/group/screens/CreateGroup/constants';
import {getPolicyOptionLabel} from '@modules/group/utils';
import {
  ApprovalPolicyIconsMap,
  GROUP_QUERY_KEYS,
  PolicyModalKey,
  PrivacyPolicyIconsMap,
} from '@modules/group/constants';
import {usePermission, useUserId} from '@redux/selectors';
import {showSnackbar} from '@redux/dispatchers';
import {AMPLITUDE_EVENTS, Screens} from '@shared/constants';
import {logAmplitudeEvent, openGallery, removeQueryParams} from '@shared/utils';
import {useTheme} from '@shared/theme';

import {styles} from './styles';
import ConfigurationItem from './components/ConfigurationItem';
import TitleModal from './components/TitleModal';

// TODO: Use react-hook-form
function CreateGroup({navigation, route}: Navigation<Screens.CREATE_GROUP>) {
  const {t} = useTranslation();
  const paddingBottom = useSafeAreaBottomPadding();
  const {theme, spacing} = useTheme();
  const {goBack} = useGoBack();
  const groupToEdit = route?.params?.group;
  const multicompanyPermission = usePermission(
    UserPermissions.CREATE_MULTICOMPANY_GROUPS,
  );
  const [isMultiCompany, setIsMultiCompany] = useState(
    groupToEdit?.isMultiCompany || false,
  );
  const [title, setTitle] = useState(groupToEdit?.title || '');
  const [isTitleModalVisible, setIsTitleModalVisible] = useState(false);
  const [description, setDescription] = useState(
    groupToEdit?.description || '',
  );
  const [bannerImage, setBannerImage] = useState<Nullable<ImageOrVideo>>(null);
  const [groupIconPickerVisible, setGroupIconPickerVisible] = useState(false);
  const [icon, setIcon] = useState<Icon>(
    groupToEdit?.icon || DEFAULT_GROUP_ICON,
  );
  const [membersCanLeave, setMembersCanLeave] = useState(
    !!groupToEdit?.membersCanLeave,
  );
  const [approvalPolicy, setApprovalPolicy] = useState(
    groupToEdit?.approvalPolicy || ApprovalPolicy.NotNeeded,
  );
  const [privacyPolicy, setPrivacyPolicy] = useState(
    groupToEdit?.privacyPolicy || PrivacyPolicy.Open,
  );
  const [publicationPolicy, setPublicationPolicy] = useState(
    groupToEdit?.publicationPolicy || PublicationPolicy.Open,
  );
  const [policyModalKey, setPolicyModalKey] =
    useState<Nullable<PolicyModalKey>>(null);

  const userId = useUserId();
  const isEditing = !!groupToEdit;

  const onOpenIconPickerModal = () => setGroupIconPickerVisible(true);
  const onCloseIconPickerModal = () => setGroupIconPickerVisible(false);
  const onPickIcon = ({custom, source}: PublicIcon) => {
    setIcon({
      custom,
      type: IconTypes.IMAGE,
      value: custom ? removeQueryParams(source) : source,
    });
    onCloseIconPickerModal();
  };
  const onPickEmoji = (value: string) => {
    setIcon({
      value,
      custom: false,
      type: IconTypes.EMOJI,
    });
    onCloseIconPickerModal();
  };

  const disableButton = !title;

  const createGroupMutation = useMutation(createGroup, {
    onSuccess: group => {
      logAmplitudeEvent(AMPLITUDE_EVENTS.GROUPS_GROUP_CREATED, {
        groupId: group.id,
        userId,
      });

      navigation.replace(Screens.SUCCESS_GROUP_CREATED, {groupId: group.id});
    },
  });

  const editGroupMutation = useMutation(updateGroupConfiguration);
  const editBannerMutation = useMutation(updateGroupBanner);

  const onCreateGroup = () => {
    createGroupMutation.mutate({
      approvalPolicy,
      bannerImage,
      description: description || null,
      icon,
      memberIds: [],
      privacyPolicy,
      publicationPolicy,
      title,
      membersCanLeave,
      // Adding this condition in case the permission is revoked after selecting the option
      isMultiCompany: multicompanyPermission && isMultiCompany,
    });
  };

  const onPickBanner = () =>
    openGallery({
      save: (image: ImageOrVideo) => setBannerImage(image),
      options: {cropping: true},
    });

  const onClosePolicyModal = () => setPolicyModalKey(null);
  const onSavePolicyModal = (key: PolicyModalKey, value: string | boolean) => {
    onClosePolicyModal();

    switch (key) {
      case PolicyModalKey.ApprovalPolicyKey:
        setApprovalPolicy(value as ApprovalPolicy);
        break;
      case PolicyModalKey.PrivacyPolicyKey:
        setPrivacyPolicy(value as PrivacyPolicy);
        break;
      case PolicyModalKey.PublicationPolicyKey:
        setPublicationPolicy(value as PublicationPolicy);
        break;
      case PolicyModalKey.MembersCanLeaveKey:
        setMembersCanLeave(value as boolean);
        break;
    }
  };

  const policyValues = {
    [PolicyModalKey.ApprovalPolicyKey]: approvalPolicy,
    [PolicyModalKey.PrivacyPolicyKey]: privacyPolicy,
    [PolicyModalKey.PublicationPolicyKey]: publicationPolicy,
    [PolicyModalKey.MembersCanLeaveKey]: membersCanLeave,
  };

  const onPrivacyOptionPress = (key: PolicyModalKey) => () =>
    setPolicyModalKey(key);

  const onSaveEdits = async () => {
    if (!groupToEdit) {
      return;
    }
    try {
      await editGroupMutation.mutateAsync({
        id: groupToEdit.id,
        title,
        description: description || null,
        icon,
        approvalPolicy,
        privacyPolicy,
        publicationPolicy,
        membersCanLeave,
      });
      if (bannerImage) {
        await editBannerMutation.mutateAsync({
          id: groupToEdit.id,
          image: bannerImage,
        });
      }

      // Needed to refresh options from the group
      queryClient.invalidateQueries(GROUP_QUERY_KEYS.group(groupToEdit.id));

      showSnackbar({title: t('group.configuration_changed')});
      goBack();
    } catch (e) {
      // Do nothing
    }
  };

  const onToggleMulticompany = () => {
    if (isMultiCompany) {
      setPrivacyPolicy(PrivacyPolicy.Open);
    } else {
      setPrivacyPolicy(PrivacyPolicy.Secret);
    }
    setIsMultiCompany(prev => !prev);
  };
  const onPressTitle = () => {
    setIsTitleModalVisible(true);
  };

  const onAcceptTitle = (newTitle: string) => {
    setTitle(newTitle);
    setIsTitleModalVisible(false);
  };

  return (
    <>
      <View
        style={[
          styles.container,
          {backgroundColor: theme.background.elements.grey},
        ]}>
        <KeyboardAwareScrollView
          keyboardShouldPersistTaps="handled"
          contentContainerStyle={[
            styles.scrollView,
            {backgroundColor: theme.background.elements.grey},
          ]}>
          <View
            style={[
              styles.sectionContainer,
              {backgroundColor: theme.background.elements.default},
            ]}>
            <Typography variant="m" weight="semiBold">
              {t('group.configure_group')}
            </Typography>
          </View>
          <View
            style={[
              styles.sectionContainer,
              {backgroundColor: theme.background.elements.default},
            ]}>
            <Pressable
              onPress={onPressTitle}
              style={[
                styles.titlePressable,
                {
                  backgroundColor: theme.background.elements.default,
                  borderColor: theme.border.neutral.default,
                },
              ]}>
              <Typography
                numberOfLines={1}
                variant="s"
                color={title ? undefined : theme.text.neutral.lighter}>
                {title || t('group.group_name')}
              </Typography>
            </Pressable>
          </View>
          <View
            style={[
              styles.sectionContainer,
              {backgroundColor: theme.background.elements.default},
              styles.smallGap,
            ]}>
            <ConfigurationItem
              label={t('group.group_icon')}
              onPressItem={onOpenIconPickerModal}
            />
            <ConfigurationItem
              label={t('group.banner_image')}
              onPressItem={onPickBanner}
            />
          </View>
          <View
            style={[
              styles.sectionContainer,
              {backgroundColor: theme.background.elements.default},
            ]}>
            <InputTextArea
              value={description}
              onChangeText={setDescription}
              label={t('group.optional_description')}
              placeholder={t('group.enter_description')}
            />
          </View>
          {multicompanyPermission && (
            <View
              style={[
                styles.sectionContainer,
                {backgroundColor: theme.background.elements.default},
              ]}>
              <Switch
                value={isMultiCompany}
                disabled={isEditing}
                onToggle={onToggleMulticompany}
                title={t('group.multi_company_create_group')}
                description={t('group.multi_company_create_group_description')}
              />
            </View>
          )}
          <View
            style={[
              styles.sectionContainer,
              {backgroundColor: theme.background.elements.default},
              styles.gap,
            ]}>
            <ConfigurationItem
              label={t('group.group_privacy')}
              value={t(
                getPolicyOptionLabel(
                  PolicyModalKey.PrivacyPolicyKey,
                  privacyPolicy,
                ),
              )}
              Icon={PrivacyPolicyIconsMap[privacyPolicy]}
              onPressItem={onPrivacyOptionPress(
                PolicyModalKey.PrivacyPolicyKey,
              )}
            />
            <ConfigurationItem
              label={t('group.post_privacy')}
              value={t(
                getPolicyOptionLabel(
                  PolicyModalKey.PublicationPolicyKey,
                  publicationPolicy,
                ),
              )}
              Icon={IconArticle}
              onPressItem={onPrivacyOptionPress(
                PolicyModalKey.PublicationPolicyKey,
              )}
            />
            <ConfigurationItem
              label={t('group.require_post_approval')}
              value={t(
                getPolicyOptionLabel(
                  PolicyModalKey.ApprovalPolicyKey,
                  approvalPolicy,
                ),
              )}
              Icon={ApprovalPolicyIconsMap[approvalPolicy]}
              onPressItem={onPrivacyOptionPress(
                PolicyModalKey.ApprovalPolicyKey,
              )}
            />
            <ConfigurationItem
              label={t('group.leave_group')}
              value={t(
                getPolicyOptionLabel(
                  PolicyModalKey.MembersCanLeaveKey,
                  membersCanLeave,
                ),
              )}
              Icon={ApprovalPolicyIconsMap[approvalPolicy]}
              onPressItem={onPrivacyOptionPress(
                PolicyModalKey.MembersCanLeaveKey,
              )}
            />
          </View>
        </KeyboardAwareScrollView>
        <KeyboardStickyView
          offset={{
            closed: 0,
            opened: paddingBottom - spacing.x2,
          }}>
          <CardContainer elevation style={[styles.footer, {paddingBottom}]}>
            <Button
              text={
                isEditing ? t('general.save_changes') : t('screens.CreateGroup')
              }
              onPress={isEditing ? onSaveEdits : onCreateGroup}
              disabled={disableButton}
              isLoading={
                isEditing
                  ? editGroupMutation.isLoading || editBannerMutation.isLoading
                  : createGroupMutation.isLoading
              }
            />
          </CardContainer>
        </KeyboardStickyView>
      </View>
      {policyModalKey !== null && (
        <PolicyModal
          onSave={onSavePolicyModal}
          disabled={
            isMultiCompany && policyModalKey === PolicyModalKey.PrivacyPolicyKey
          }
          policyKey={policyModalKey}
          currentValue={policyValues[policyModalKey]}
          onCloseModal={onClosePolicyModal}
        />
      )}
      <GroupIconModalPicker
        onPickIcon={onPickIcon}
        onPickEmoji={onPickEmoji}
        isVisible={groupIconPickerVisible}
        onCloseModal={onCloseIconPickerModal}
      />
      <TitleModal
        isVisible={isTitleModalVisible}
        title={title}
        onAccept={onAcceptTitle}
      />
    </>
  );
}

export default CreateGroup;
