import React, {useMemo, useState} from 'react';
import {View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {shallowEqual} from 'react-redux';
import {useMutation} from 'react-query';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {InputSelect, Button} from '@components';
import {SelectValue} from '@components/SelectInput';
import i18next, {setStoredLanguage} from '@config/i18n/instance';
import {Language} from '@config/i18n';
import {Navigation} from '@interfaces/navigation';
import {languageEnabledKeys} from '@modules/settings/constants';
import {patchUserLanguage} from '@modules/settings/service';
import {useAppSelector} from '@redux/utils';
import {showSnackbar} from '@redux/dispatchers';
import {Screens} from '@shared/constants';
import {useTheme} from '@shared/theme';
import {useCommunityFeature} from '@stores/communityFeatures';

import {styles} from './styles';
import {useThemePreview} from './hooks/useThemePreview';
import {AppearanceSelector} from './components/AppearanceSelector';

function Settings({navigation}: Navigation<Screens.SETTINGS>) {
  const {t} = useTranslation();
  const {theme} = useTheme();
  const {
    selectedThemePreference,
    hasThemeChanged,
    onChangeThemePreference,
    commitThemePreference,
  } = useThemePreview();
  const [userPostTranslationLanguage, userId, userLanguage] = useAppSelector(
    ({user: {postTranslationLanguage, id, language}}) => [
      postTranslationLanguage,
      id,
      language,
    ],
    shallowEqual,
  );
  const initialPostTranslationLanguage = userPostTranslationLanguage || 'en';
  const [newLanguage, setNewLanguage] = useState(
    initialPostTranslationLanguage,
  );
  const [newPlatformLanguage, setNewPlatformLanguage] = useState(userLanguage);

  const canTranslatePosts = useCommunityFeature('TRANSLATE_POSTS');

  const onSelectNewLanguage = (newLang: SelectValue) =>
    setNewLanguage(newLang as string);

  const onSelectNewPlatformLanguage = (newLang: SelectValue) =>
    setNewPlatformLanguage(newLang as string);

  const {bottom: paddingBottom} = useSafeAreaInsets();

  const {mutate: changeLanguageMutate, isLoading} = useMutation(
    ({
      postTranslationLanguage,
      language,
    }: {
      postTranslationLanguage: string;
      language: string;
      successTitle: string;
    }) =>
      patchUserLanguage({
        postTranslationLanguage,
        userId,
        language,
      }),
    {
      onSuccess: (_, {language, successTitle}) => {
        setStoredLanguage(language);
        i18next.changeLanguage(language);
        showSnackbar({
          title: successTitle,
          variant: 'success',
        });
        navigation.goBack();
      },
    },
  );

  const languageAppOptions = useMemo(
    () =>
      Object.values(Language)
        .filter(value => ![Language.NoNb, Language.NoNn].includes(value))
        .map(value => ({
          id: value.toLowerCase(),
          label: t(
            `dashboard.language_${value.replace('-', '_').toLowerCase()}`,
          ),
        })),
    [t],
  );

  const options = useMemo(
    () =>
      languageEnabledKeys.map(key => ({
        id: key,
        label: t(`settings.languages.${key}`),
      })),
    [t],
  );

  const languageChanged =
    newLanguage !== initialPostTranslationLanguage ||
    newPlatformLanguage !== userLanguage;

  const acceptButtonEnabled = languageChanged || hasThemeChanged;

  const onAcceptButtonPress = () => {
    commitThemePreference();

    const successTitle = hasThemeChanged
      ? t('settings.preferences_updated')
      : t('settings.language_changed_successfully');

    if (languageChanged && !!newLanguage && !!newPlatformLanguage) {
      changeLanguageMutate({
        postTranslationLanguage: newLanguage,
        language: newPlatformLanguage,
        successTitle,
      });
      return;
    }

    showSnackbar({title: successTitle, variant: 'success'});
    navigation.goBack();
  };

  return (
    <View
      style={[
        styles.container,
        {backgroundColor: theme.background.layout.default},
      ]}>
      <View style={styles.content}>
        <AppearanceSelector
          selectedTheme={selectedThemePreference}
          onChangeThemePreference={onChangeThemePreference}
        />
        <InputSelect
          options={languageAppOptions}
          onChange={onSelectNewPlatformLanguage}
          value={newPlatformLanguage}
          label={t('settings.language_app_select_label')}
          showRadioButtonItem
          placeholder={t('settings.language_app_modal_title')}
          modalTitleNumberOfLines={2}
        />
        {canTranslatePosts && (
          <InputSelect
            options={options}
            onChange={onSelectNewLanguage}
            value={newLanguage}
            label={t('settings.language_select_label')}
            showRadioButtonItem
            placeholder={t('settings.language_modal_title')}
            modalTitleNumberOfLines={2}
          />
        )}
      </View>
      <View
        style={[
          styles.buttonContainer,
          {
            paddingBottom,
            backgroundColor: theme.background.elements.default,
            borderColor: theme.border.neutral.default,
          },
        ]}>
        <Button
          isLoading={isLoading}
          text={t('settings.general.save')}
          disabled={!acceptButtonEnabled}
          onPress={onAcceptButtonPress}
        />
      </View>
    </View>
  );
}

export default Settings;
