import { NavigationProp, useFocusEffect } from '@react-navigation/native';
import React, { FC, useCallback, useEffect, useState } from 'react';
import { ActivityIndicator } from 'react-native';
import { Header, HorizontalTabView, Loading, PageWrapper, WarningModal } from 'src/components';

import { Colors } from 'src/theme';
import { FlashList } from '@shopify/flash-list';
import { StoreType, storage } from 'src/storage';
import { FilterButton, FilterModal } from '../../TravellersScreen/Components/FilterModal';
import { RankingDropdown } from '../../TravellersScreen/utils/types';
import { dataRanking } from '../../TravellersScreen/utils';
import {
  useGetMyFriendsMutation,
  usePostHideShowRequestMutation,
  usePostUpdateFriendStatusMutation
} from '@api/friends';
import { FriendsProfile } from './FriendsProfile';
import { useNotification } from 'src/contexts/NotificationContext';

type Props = {
  navigation: NavigationProp<any>;
  route: any;
};

type Routes = {
  key: 'friends' | 'received' | 'sent';
  title: string;
};

const MyFriendsScreen: FC<Props> = ({ navigation }) => {
  const token = storage.get('token', StoreType.STRING) as string;
  const { isNotificationActive, updateNotificationStatus } = useNotification();

  const { mutateAsync: getMyFriends } = useGetMyFriendsMutation();
  const [loading, setLoading] = useState(true);
  const [isModalVisible, setModalVisible] = useState(false);
  const [confirmedValueRanking, setConfirmedValueRanking] = useState<RankingDropdown | null>();
  const [masterCountries, setMasterCountries] = useState<any>([]);
  const [maxPages, setMaxPages] = useState(1);
  const [page, setPage] = useState(0);
  const [isLoadingMore, setIsLoadingMore] = useState(false);
  const [filter, setFilter] = useState<{
    age: number | undefined;
    ranking: string | undefined;
    country: string | undefined;
  }>({ age: undefined, ranking: undefined, country: undefined });
  const [index, setIndex] = useState(0);
  const routes: Routes[] = [
    { key: 'friends', title: 'My friends' },
    { key: 'received', title: 'Received requests' },
    { key: 'sent', title: 'Sent requests' }
  ];
  const [users, setUsers] = useState<{ [key in 'friends' | 'received' | 'sent']: any[] }>({
    friends: [],
    received: [],
    sent: []
  });
  const { mutateAsync: updateFriendStatus } = usePostUpdateFriendStatusMutation();
  const { mutateAsync: hideShowRequest } = usePostHideShowRequestMutation();

  useEffect(() => {
    if (filter.age || filter.ranking || filter.country) {
      applySort();
    }
  }, [filter]);

  useEffect(() => {
    fetchUsers();
    setFilter({
      age: undefined,
      ranking: undefined,
      country: undefined
    });
  }, [index]);

  useFocusEffect(
    useCallback(() => {
      fetchUsers();
    }, [])
  );

  useEffect(() => {
    const getNextPage = async () => {
      await getMyFriends(
        {
          token,
          type: routes[index].key,
          page,
          sort: filter.ranking,
          age: filter.age,
          country: filter.country
        },
        {
          onSuccess: (data) => {
            setIsLoadingMore(false);
            setUsers((prevState) => {
              return {
                ...prevState,
                [routes[index].key]: [
                  ...prevState[routes[index].key],
                  ...data[routes[index].key].users
                ]
              };
            });
          }
        }
      );
    };
    if (page !== 0) {
      getNextPage();
    }
  }, [page]);

  const fetchUsers = async () => {
    await getMyFriends(
      {
        token,
        type: '',
        page: 0,
        sort: undefined,
        age: undefined,
        country: undefined
      },
      {
        onSuccess: (data) => {
          setUsers({
            friends: data.friends.users,
            received: data.received.users,
            sent: data.sent.users
          });
          setMaxPages(data[routes[index].key].max_pages);
          setMasterCountries(convertData(data[routes[index].key].countries) ?? []);
          setLoading(false);
        }
      }
    );
  };

  const applySort = async () => {
    await getMyFriends(
      {
        token,
        type: routes[index].key,
        page,
        sort: filter.ranking,
        age: filter.age,
        country: filter.country
      },
      {
        onSuccess: (data) => {
          setUsers((prevState) => {
            return {
              ...prevState,
              [routes[index].key]: data[routes[index].key].users
            };
          });
          setMaxPages(data[routes[index].key].max_pages);
          setMasterCountries(convertData(data[routes[index].key].countries) ?? []);
          setLoading(false);
        }
      }
    );
  };

  const convertData = (data: { [key: string]: { country: string; flag: string } }) => {
    let formatedCountries = [{ two: 'all', name: 'ALL', flag: '' }];
    data &&
      formatedCountries.push(
        ...Object.entries(data).map(([key, value]) => ({
          two: key,
          name: value.country,
          flag: value.flag
        }))
      );

    return formatedCountries;
  };

  const handleEndReached = useCallback(() => {
    if (users && page < maxPages && !isLoadingMore && maxPages > 1) {
      setIsLoadingMore(true);
      setPage((prevPage) => prevPage + 1);
    }
  }, [users, page]);

  const handleUpdateFriendStatus = async (status: number, id: number) => {
    await updateFriendStatus(
      { token, id, status },
      {
        onSuccess: () => {
          applySort();
        }
      }
    );
    updateNotificationStatus();
  };

  const handleHideRequest = async (id: number) => {
    await hideShowRequest(
      { token, id, show: 0 },
      {
        onSuccess: () => {
          applySort();
        }
      }
    );
  };

  if (loading) return <Loading />;

  const ListFooter = ({ isLoading }: { isLoading: boolean }) =>
    isLoading ? <ActivityIndicator size="large" color={Colors.DARK_BLUE} /> : null;

  return (
    <PageWrapper>
      <Header
        label={'Friends'}
        rightElement={<FilterButton onPress={() => setModalVisible(!isModalVisible)} />}
      />
      <HorizontalTabView
        index={index}
        setIndex={setIndex}
        routes={routes}
        withNotification={isNotificationActive}
        renderScene={({ route }: { route: Routes }) => (
          <>
            <FlashList
              viewabilityConfig={{
                waitForInteraction: true,
                itemVisiblePercentThreshold: 50,
                minimumViewTime: 1000
              }}
              estimatedItemSize={50}
              data={users[route.key]}
              renderItem={({ item, index }) => (
                <FriendsProfile
                  userId={item.user_id}
                  key={index}
                  index={index}
                  first_name={item.first_name}
                  last_name={item.last_name}
                  avatar={item.avatar}
                  date_of_birth={item.age}
                  homebase_flag={item.flag1}
                  homebase2_flag={item.flag2}
                  score={[
                    item.score_nm,
                    item.score_un,
                    item.score_unp,
                    item.score_dare,
                    item.score_tcc,
                    item.score_deep,
                    item.score_slow,
                    item.score_yes,
                    item.score_kye,
                    item.score_whs,
                    item.score_tbt
                  ]}
                  active_score={
                    confirmedValueRanking
                      ? confirmedValueRanking.value - 1
                      : dataRanking[0].value - 1
                  }
                  tbt_score={item.score_tbt}
                  tbt_rank={item.rank_tbt}
                  badge_tbt={item.badge_tbt}
                  badge_1281={item.badge_1281}
                  badge_un={item.badge_un}
                  badge_un_50={item.badge_un_50}
                  badge_un_100={item.badge_un_100}
                  badge_un_150={item.badge_un_150}
                  auth={item.auth}
                  type={route.key}
                  updateFriendStatus={handleUpdateFriendStatus}
                  status={item.friend_status}
                  friendDbId={item.friend_db_id}
                  hideRequest={handleHideRequest}
                />
              )}
              keyExtractor={(item) => item.user_id.toString()}
              contentContainerStyle={{ paddingBottom: 52, paddingTop: 8 }}
              showsVerticalScrollIndicator={false}
              onEndReached={handleEndReached}
              onEndReachedThreshold={0.2}
              ListFooterComponent={<ListFooter isLoading={isLoadingMore} />}
            />
          </>
        )}
      />

      <FilterModal
        isModalVisible={isModalVisible}
        setModalVisible={(value) => setModalVisible(value)}
        applyFilter={(filterAge, filterRanking, filterCountry) => {
          setConfirmedValueRanking(filterRanking);
          setPage(0);
          setFilter({
            age: filterAge?.value ? +filterAge?.value : undefined,
            ranking: filterRanking?.name,
            country:
              filterCountry?.two && filterCountry?.two !== 'all' ? filterCountry?.two : undefined
          });
          if (!filterAge && !filterRanking && !filterCountry) {
            fetchUsers();
          }
          setModalVisible(false);
        }}
        countriesData={masterCountries}
      />
    </PageWrapper>
  );
};

export default MyFriendsScreen;
