import React, {memo, useCallback, useMemo, useState} from 'react';
import {View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useMutation, useQueryClient} from '@tanstack/react-query';
import {useForm} from 'react-hook-form';
import {z} from 'zod';
import {IconSearch} from '@tabler/icons-react-native';
import {zodResolver} from '@hookform/resolvers/zod';
import {Dialog, InputBox} from '@components';
import {Typography} from '@components/_core';
import {FormValues, ReviewerSelected} from '@modules/performance/interfaces';
import {createExternalReviewer} from '@modules/performance/services';
import {PERFORMANCE_QUERY_KEYS} from '@modules/performance/constants';
import {requiredString} from '@shared/schemas';
import {useTheme} from '@shared/theme';

import {CreateExternalReviewer} from './components/CreateExternalReviewer';
import {SelectReviewers} from './components/SelectReviewers';
import {styles} from './styles';

interface Props {
  initialSelection: ReviewerSelected[];
  onSave: (newSelection: ReviewerSelected[]) => void;
  initialModalVisible: boolean;
}

function SearchUsersToSelectModal({
  initialSelection,
  onSave,
  initialModalVisible,
}: Props) {
  const {t} = useTranslation();
  const {theme, iconSizes} = useTheme();
  const queryClient = useQueryClient();

  const [selected, setSelected] = useState<ReviewerSelected[]>([]);
  const [isSelectUserVisible, setIsSelectUserVisible] =
    useState(initialModalVisible);
  const [showCreateExternalForm, setShowCreateExternalForm] = useState(false);

  const isSelectionEqual = useMemo(
    () => JSON.stringify(selected) === JSON.stringify(initialSelection),
    [selected, initialSelection],
  );

  const methods = useForm<FormValues>({
    resolver: zodResolver(
      z.object({
        firstName: requiredString(),
        lastName: requiredString(),
        email: requiredString().email({
          message: t('forms.invalid_email_error'),
        }),
      }),
    ),
  });

  const onUserPress = useCallback((item: ReviewerSelected, index: number) => {
    setSelected(prev =>
      index > -1 ? prev.filter(user => user.id !== item.id) : [...prev, item],
    );
  }, []);

  const onCloseModal = useCallback(() => {
    setShowCreateExternalForm(false);
    setIsSelectUserVisible(false);
    setSelected([]);
  }, []);

  const onPressSearch = useCallback(() => {
    setIsSelectUserVisible(true);
    setSelected(initialSelection);
  }, [initialSelection]);

  const onPressAccept = useCallback(() => {
    onSave(selected);
    onCloseModal();
  }, [onSave, onCloseModal, selected]);

  const onCreateExternalPress = useCallback(
    () => setShowCreateExternalForm(true),
    [],
  );

  const onCreateFormGoBack = useCallback(
    () => setShowCreateExternalForm(false),
    [],
  );

  const {mutate, isPending: isLoadingCreateExternal} = useMutation({
    mutationFn: createExternalReviewer,
    onSuccess: () => {
      queryClient.invalidateQueries({
        queryKey: PERFORMANCE_QUERY_KEYS.externalReviewers(),
      });
      onCreateFormGoBack();
    },
  });

  const onSubmit = (formValues: FormValues) => mutate(formValues);

  return (
    <>
      <View style={styles.container}>
        <InputBox onPress={onPressSearch}>
          <IconSearch size={iconSizes.x6} color={theme.text.neutral.lighter} />
          <Typography color={theme.text.neutral.lighter}>
            {t('performance.nominate_reviewers.search_select_name')}
          </Typography>
        </InputBox>
      </View>
      <Dialog
        contentStyle={styles.withoutPadding}
        isVisible={isSelectUserVisible}
        fullScreen
        title={t(
          `performance.${
            showCreateExternalForm
              ? 'nominate_reviewers.create_external.title'
              : 'select_reviewers'
          }`,
        )}
        footer={{
          primaryButton: {
            text: t(
              `performance.nominate_reviewers.${
                showCreateExternalForm
                  ? 'create_external.submit'
                  : 'save_selection'
              }`,
            ),
            onPress: showCreateExternalForm
              ? methods.handleSubmit(onSubmit)
              : onPressAccept,
            disabled: isSelectionEqual && !showCreateExternalForm,
            isLoading: isLoadingCreateExternal,
          },
        }}
        onClose={onCloseModal}
        withBackButton={showCreateExternalForm}
        onGoBack={onCreateFormGoBack}>
        {showCreateExternalForm ? (
          <CreateExternalReviewer methods={methods} />
        ) : (
          <SelectReviewers
            selected={selected}
            onItemPress={onUserPress}
            onCreateExternal={onCreateExternalPress}
          />
        )}
      </Dialog>
    </>
  );
}

export default memo(SearchUsersToSelectModal);
