import React, { useState } from 'react';
import { ScrollView, View, Text, Linking, StyleSheet } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import { Formik } from 'formik';
import * as yup from 'yup';
import { CommonActions, useNavigation } from '@react-navigation/native';
import { useQueryClient } from '@tanstack/react-query';
import { Image } from 'expo-image';

import {
  usePostGetProfileQuery,
  usePostSetProfileMutation,
  usePostUpdateEmailMutation,
  userQueryKeys,
  type PostSetProfileData
} from '@api/user';

import { useGetRegionsWithFlagQuery } from '@api/regions';

import { API_HOST } from '../../../../constants';

import {
  AvatarPicker,
  BigText,
  Header,
  Input,
  PageWrapper,
  Button,
  Loading,
  WarningModal
} from '../../../../components';
import { InputDatePicker } from '../../../../components/Calendar/InputDatePicker';
import { ModalFlatList } from '../../../../components/FlatList/modal-flatlist';

import { storage, StoreType } from '../../../../storage';
import { Colors } from '../../../../theme';

import FacebookIcon from '../../../../../assets/icons/facebook.svg';
import InstagramIcon from '../../../../../assets/icons/instagram.svg';
import XIcon from '../../../../../assets/icons/x(twitter).svg';
import YoutubeIcon from '../../../../../assets/icons/youtube.svg';
import GlobeIcon from '../../../../../assets/icons/bottom-navigation/globe.svg';
import LinkIcon from '../../../../../assets/icons/link.svg';
import { ButtonVariants } from 'src/types/components';
import { NAVIGATION_PAGES } from 'src/types';
import { useDeleteUserMutation } from '@api/app';
import { useMessagesStore } from 'src/stores/unreadMessagesStore';
import { useAvatarStore } from 'src/stores/avatarVersionStore';
import { useFriendsNotificationsStore } from 'src/stores/friendsNotificationsStore';
import { getFontSize } from 'src/utils';
import { clearLocalDatabaseOnLogout } from 'src/watermelondb/features/chat/data/chat.repo';
import { stopAutoSyncListener } from 'src/watermelondb/features/chat/networkSync';

const ProfileSchema = yup.object({
  username: yup.string().optional(),
  email: yup.string().email().optional(),
  first_name: yup.string().optional(),
  last_name: yup.string().optional(),
  date_of_birth: yup.string().optional(),
  homebase: yup.number().optional(),
  homebase2: yup.number().nullable().optional(),
  bio: yup.string().optional(),
  f: yup.string().optional(),
  t: yup.string().optional(),
  i: yup.string().optional(),
  y: yup.string().optional(),
  www: yup.string().optional(),
  other: yup.string().optional(),
  new_email: yup.string().email().optional()
});

export const EditPersonalInfo = () => {
  const token = storage.get('token', StoreType.STRING) as string;
  const uid = storage.get('uid', StoreType.STRING) as string;
  const { mutate: deleteUser } = useDeleteUserMutation();

  const { mutate: updateProfile, data: updateResponse, reset } = usePostSetProfileMutation();
  const { mutate: updateEmail } = usePostUpdateEmailMutation();

  const navigation = useNavigation();
  const queryClient = useQueryClient();

  const { data, error } = usePostGetProfileQuery(String(token), true);
  const updateNotificationStatus = useFriendsNotificationsStore(
    (state) => state.updateNotificationStatus
  );
  const updateUnreadMessagesCount = useMessagesStore((state) => state.updateUnreadMessagesCount);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [isNewEmailSubmitted, setIsNewEmailSubmitted] = useState(false);
  const { incrementAvatarVersion } = useAvatarStore();

  const regions = useGetRegionsWithFlagQuery(true);
  const [modalInfo, setModalInfo] = useState({
    visible: false,
    type: 'confirm',
    message: '',
    action: () => {}
  });

  const openModal = (type: string, message: string, action: any) => {
    setModalInfo({
      visible: true,
      type,
      message,
      action
    });
  };

  const closeModal = () => {
    setModalInfo({ ...modalInfo, visible: false });
  };

  if (!data) return <Loading />;

  const originRegion = regions.data?.data.find((region) => region.id === data.homebase);
  const secondOrigin = regions.data?.data.find((region) => region.id === data.homebase2);

  const handleLogout = async () => {
    stopAutoSyncListener();
    await clearLocalDatabaseOnLogout();

    storage.remove('token');
    storage.remove('uid');
    storage.remove('currentUserData');
    storage.remove('showNomads');
    storage.remove('filterSettings');
    storage.remove('visitedRegions');
    storage.remove('visitedCountries');
    storage.remove('visitedDares');
    storage.remove('visitedSeries');

    updateNotificationStatus();
    updateUnreadMessagesCount();
    navigation.dispatch(
      CommonActions.reset({
        index: 1,
        routes: [{ name: NAVIGATION_PAGES.WELCOME }]
      })
    );
  };

  const handleDeleteAccount = () => {
    deleteUser({ token }, { onSuccess: handleLogout });
  };

  const handleVerifyEmailChange = async (newEmail: string) => {
    setIsSubmitting(true);
    await updateEmail(
      { token, email: newEmail },
      {
        onSuccess: () => {
          setIsSubmitting(false);
          setIsNewEmailSubmitted(true);
        },
        onError: () => {
          setIsSubmitting(false);
        }
      }
    );
  };

  return (
    <PageWrapper>
      <Header label={'Edit Personal Info'} />
      <ScrollView showsVerticalScrollIndicator={false}>
        <KeyboardAwareScrollView>
          <Formik
            validationSchema={ProfileSchema}
            initialValues={{
              username: data.username,
              email: data.email,
              first_name: data.first_name,
              last_name: data.last_name,
              date_of_birth: data.date_of_birth,
              homebase: data.homebase,
              homebase2: data.homebase2,
              bio: data.bio?.toString() ?? '',
              f: data.links.f!.link,
              i: data.links.i!.link,
              t: data.links.t!.link,
              y: data.links.y!.link,
              www: data.links.www!.link,
              other: data.links.other!.link,
              photo: {
                type: '',
                uri: '',
                name: ''
              },
              new_email: ''
            }}
            onSubmit={async (values) => {
              setIsSubmitting(true);

              const profileData: PostSetProfileData = {
                token: String(token),
                user: {
                  username: values.username,
                  email: values.email,
                  first_name: values.first_name,
                  last_name: values.last_name,
                  date_of_birth: values.date_of_birth,
                  homebase: values.homebase,
                  bio: values.bio,
                  f: values.f,
                  i: values.i,
                  t: values.t,
                  y: values.y,
                  www: values.www,
                  other: values.other
                }
              };

              if (values.homebase2) {
                profileData.user!.homebase2 = values.homebase2;
              }

              if (values.photo.uri) {
                profileData.photo = {
                  type: values.photo.type,
                  uri: values.photo.uri,
                  name: values.photo.uri.split('/').pop()!
                };
              }

              await updateProfile(profileData, {
                onSuccess: () => {
                  queryClient.invalidateQueries({
                    queryKey: userQueryKeys.getProfileData(),
                    refetchType: 'all'
                  });
                  queryClient.invalidateQueries({
                    queryKey: userQueryKeys.getProfileInfoData(+uid),
                    refetchType: 'all'
                  });

                  Image.clearDiskCache();
                  Image.clearMemoryCache();

                  incrementAvatarVersion();

                  setIsSubmitting(false);
                  navigation.goBack();
                },
                onError: () => {
                  setIsSubmitting(false);
                }
              });
            }}
          >
            {(props) => (
              <View style={{ gap: 10 }}>
                <View style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
                  <AvatarPicker
                    defaultAvatar={API_HOST + '/img/avatars/' + data.avatar}
                    selectedAvatar={(asset) => props.setFieldValue('photo', asset)}
                  />
                </View>
                <BigText>Account</BigText>
                <Input
                  editable={false}
                  header={"Username (can't edit)"}
                  placeholder={'Text'}
                  inputMode={'text'}
                  onChange={props.handleChange('username')}
                  value={props.values.username}
                  onBlur={props.handleBlur('username')}
                  formikError={props.touched.username && props.errors.username}
                />
                <Input
                  editable={false}
                  header={"Email address (can't edit)"}
                  placeholder={'Email'}
                  inputMode={'email'}
                  onChange={props.handleChange('email')}
                  value={props.values.email}
                  onBlur={props.handleBlur('email')}
                  formikError={props.touched.email && props.errors.email}
                />
                <Input
                  editable={!isNewEmailSubmitted}
                  header={'Change email address'}
                  placeholder={'new_email@address.com'}
                  inputMode={'email'}
                  onChange={props.handleChange('new_email')}
                  value={props.values.new_email}
                  onBlur={props.handleBlur('new_email')}
                  formikError={props.touched.new_email && props.errors.new_email}
                />
                {!props.errors.new_email && props.values.new_email && !isNewEmailSubmitted ? (
                  <Button
                    onPress={() => handleVerifyEmailChange(props.values.new_email)}
                    disabled={isSubmitting}
                    variant={ButtonVariants.FILL}
                  >
                    Verify email change
                  </Button>
                ) : (
                  <Button onPress={() => {}} disabled={true} variant={ButtonVariants.OPACITY}>
                    Verify email change
                  </Button>
                )}

                {isNewEmailSubmitted ? (
                  <Text style={styles.text}>
                    Confirmation message sent. Please check your old email inbox.
                  </Text>
                ) : (
                  <Text style={styles.text}>
                    We will send a confirmation message to your old email address. Once you click
                    the link in that message, your new email will become active. If you don't have
                    access to your old email mailbox, please contact us{' '}
                    <Text
                      style={{
                        color: Colors.ORANGE
                      }}
                      onPress={() => Linking.openURL('https://nomadmania.com/contact/')}
                    >
                      here
                    </Text>
                    .
                  </Text>
                )}

                <BigText>General Info</BigText>
                <Input
                  header={'First name'}
                  placeholder={'Text'}
                  inputMode={'text'}
                  onChange={props.handleChange('first_name')}
                  value={props.values.first_name}
                  onBlur={props.handleBlur('first_name')}
                  formikError={props.touched.first_name && props.errors.first_name}
                />
                <Input
                  header={'Last name'}
                  placeholder={'Text'}
                  inputMode={'text'}
                  onChange={props.handleChange('last_name')}
                  value={props.values.last_name}
                  onBlur={props.handleBlur('last_name')}
                  formikError={props.touched.last_name && props.errors.last_name}
                />
                <InputDatePicker
                  headerTitle={'Date of birth'}
                  defaultDate={new Date(data.date_of_birth)}
                  selectedDate={(date) => props.setFieldValue('date_of_birth', date)}
                  formikError={props.touched.date_of_birth && props.errors.date_of_birth}
                />
                <ModalFlatList
                  headerTitle={'Region of origin'}
                  defaultObject={{ name: originRegion?.name }}
                  selectedObject={(data) => props.setFieldValue('homebase', data.id)}
                />
                <ModalFlatList
                  headerTitle={'Second region'}
                  defaultObject={{ name: secondOrigin?.name }}
                  selectedObject={(data) => props.setFieldValue('homebase2', data.id)}
                />
                <Input
                  multiline={true}
                  header={'Bio'}
                  placeholder={'Bio'}
                  inputMode={'text'}
                  onChange={props.handleChange('bio')}
                  value={props.values.bio}
                  onBlur={props.handleBlur('bio')}
                  formikError={props.touched.bio && props.errors.bio}
                />
                <BigText>Links</BigText>
                <Input
                  icon={<FacebookIcon fill={Colors.LIGHT_GRAY} />}
                  placeholder={'https://www.facebook.com'}
                  inputMode={'text'}
                  onChange={props.handleChange('f')}
                  value={props.values.f as unknown as string}
                  onBlur={props.handleBlur('f')}
                  formikError={props.touched.f && props.errors.f}
                />
                <Input
                  icon={<InstagramIcon fill={Colors.LIGHT_GRAY} />}
                  placeholder={'https://www.instagram.com'}
                  inputMode={'text'}
                  onChange={props.handleChange('i')}
                  value={props.values.i as unknown as string}
                  onBlur={props.handleBlur('i')}
                  formikError={props.touched.i && props.errors.i}
                />
                <Input
                  icon={<XIcon fill={Colors.LIGHT_GRAY} />}
                  placeholder={'https://www.twitter.com'}
                  inputMode={'text'}
                  onChange={props.handleChange('t')}
                  value={props.values.t as unknown as string}
                  onBlur={props.handleBlur('t')}
                  formikError={props.touched.t && props.errors.t}
                />
                <Input
                  icon={<YoutubeIcon fill={Colors.LIGHT_GRAY} />}
                  placeholder={'https://www.youtube.com'}
                  inputMode={'text'}
                  onChange={props.handleChange('y')}
                  value={props.values.y as unknown as string}
                  onBlur={props.handleBlur('y')}
                  formikError={props.touched.y && props.errors.y}
                />
                <Input
                  icon={<GlobeIcon fill={Colors.LIGHT_GRAY} />}
                  placeholder={'My Website'}
                  inputMode={'text'}
                  onChange={props.handleChange('www')}
                  value={props.values.www as unknown as string}
                  onBlur={props.handleBlur('www')}
                  formikError={props.touched.www && props.errors.www}
                />
                <Input
                  icon={<LinkIcon fill={Colors.LIGHT_GRAY} />}
                  placeholder={'Other link'}
                  inputMode={'text'}
                  onChange={props.handleChange('other')}
                  value={props.values.other as unknown as string}
                  onBlur={props.handleBlur('other')}
                  formikError={props.touched.other && props.errors.other}
                />
                <View style={{ marginTop: 15, marginBottom: 15, gap: 8 }}>
                  <Button onPress={props.handleSubmit} disabled={isSubmitting}>
                    Save
                  </Button>
                  <Button
                    variant={ButtonVariants.OPACITY}
                    containerStyles={{ backgroundColor: Colors.WHITE, borderColor: Colors.RED }}
                    textStyles={{ color: Colors.RED }}
                    onPress={() =>
                      openModal('confirm', 'Are you sure you want to logout?', handleLogout)
                    }
                  >
                    Log out
                  </Button>
                  <Button
                    variant={ButtonVariants.FILL}
                    containerStyles={{ backgroundColor: Colors.RED }}
                    onPress={() =>
                      openModal(
                        'confirm',
                        'Are you sure you want to delete your account?',
                        handleDeleteAccount
                      )
                    }
                  >
                    Delete account
                  </Button>
                </View>
              </View>
            )}
          </Formik>
        </KeyboardAwareScrollView>
      </ScrollView>
      <WarningModal
        isVisible={modalInfo.visible}
        onClose={closeModal}
        type={modalInfo.type}
        message={modalInfo.message}
        action={() => {
          modalInfo.action();
          closeModal();
        }}
      />
    </PageWrapper>
  );
};

const styles = StyleSheet.create({
  text: {
    color: Colors.DARK_BLUE,
    fontSize: getFontSize(12),
    fontFamily: 'redhat-600'
  }
});
