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

import { Colors } from 'src/theme';
import { FlashList, FlashListRef } from '@shopify/flash-list';
import { StoreType, storage } from 'src/storage';
import { FilterButton, FilterModal } from '../../TravellersScreen/Components/FilterModal';
import { RankingDropdown, FilterModalRef } from '../../TravellersScreen/utils/types';
import { dataRanking } from '../../TravellersScreen/utils';
import {
  useGetMyFriendsMutation,
  usePostHideShowRequestMutation,
  usePostUpdateFriendStatusMutation
} from '@api/friends';
import { FriendsProfile } from './FriendsProfile';
import { useFriendsNotificationsStore } from 'src/stores/friendsNotificationsStore';
import { SafeAreaView } from 'react-native-safe-area-context';

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 updateNotificationStatus = useFriendsNotificationsStore(
    (state) => state.updateNotificationStatus
  );
  const isNotificationActive = useFriendsNotificationsStore((state) => state.isNotificationActive);

  const { mutateAsync: getMyFriends } = useGetMyFriendsMutation();
  const [loading, setLoading] = useState(true);
  const filterRef = useRef<FilterModalRef>(null);
  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 [loadingStatus, setLoadingStatus] = useState<string | null>(null);
  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<{
    friends: any[];
    received: any[];
    sent: any[];
    friends_max: number;
    received_max: number;
    sent_max: number;
  }>({
    friends: [],
    friends_max: 1,
    received: [],
    received_max: 1,
    sent: [],
    sent_max: 1
  });
  const { mutateAsync: updateFriendStatus } = usePostUpdateFriendStatusMutation();
  const { mutateAsync: hideShowRequest } = usePostHideShowRequestMutation();

  const flashListRef = useRef<FlashListRef<any> | null>(null);

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

  useEffect(() => {
    setPage(0);
    const currentRouteKey = routes[index].key;
    if (currentRouteKey === 'friends') {
      setMaxPages(users.friends_max);
    } else if (currentRouteKey === 'received') {
      setMaxPages(users.received_max);
    } else if (currentRouteKey === 'sent') {
      setMaxPages(users.sent_max);
    }
    fetchUsers();
    if (flashListRef && flashListRef.current) {
      flashListRef.current?.scrollToOffset({ offset: 0, animated: false });
    }
    setFilter({
      age: undefined,
      ranking: undefined,
      country: undefined
    });
  }, [index]);

  useFocusEffect(
    useCallback(() => {
      setPage(0);
      fetchUsers();
      if (flashListRef && flashListRef.current) {
        flashListRef.current?.scrollToOffset({ offset: 0, animated: false });
      }
    }, [])
  );

  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,
            friends_max: data.friends.max_pages,
            received: data.received.users,
            received_max: data.received.max_pages,
            sent: data.sent.users,
            sent_max: data.sent.max_pages
          });
          setMaxPages(data[routes[index].key].max_pages);
          setMasterCountries(convertData(data[routes[index].key].countries) ?? []);
          setLoading(false);
        }
      }
    );
  };

  const applySort = async () => {
    const resetPage = 0;

    await getMyFriends(
      {
        token,
        type: routes[index].key,
        page: resetPage,
        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) ?? []);
          setPage(resetPage);
          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) => {
    setLoadingStatus(`${status}-${id}`);
    await updateFriendStatus(
      { token, id, status },
      {
        onSuccess: () => {
          applySort();
          setLoadingStatus(null);
        },
        onError: () => {
          setLoadingStatus(null);
        }
      }
    );
    updateNotificationStatus();
  };

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

  if (loading) return <Loading />;

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

  return (
    <SafeAreaView style={{ height: '100%' }} edges={['top']}>
      <View style={{ marginLeft: '5%', marginRight: '5%' }}>
        <Header
          label={'Friends'}
          rightElement={<FilterButton onPress={() => filterRef.current?.toggle()} />}
        />
      </View>

      <View style={{ zIndex: 100 }}>
        <View
          style={{
            position: 'absolute',
            top: 0,
            left: 0,
            width: Dimensions.get('window').width,
            height: Dimensions.get('window').height,
            overflow: 'hidden'
          }}
          pointerEvents="box-none"
        >
          <FilterModal
            ref={filterRef}
            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();
              }
            }}
            countriesData={masterCountries}
          />
        </View>
      </View>

      <HorizontalTabView
        index={index}
        setIndex={setIndex}
        routes={routes}
        withNotification={isNotificationActive}
        maxTabHeight={50}
        renderScene={({ route }: { route: Routes }) => (
          <>
            <FlashList
              ref={flashListRef}
              viewabilityConfig={{
                waitForInteraction: true,
                itemVisiblePercentThreshold: 50,
                minimumViewTime: 1000
              }}
              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_25={item.badge_un_25}
                  badge_un_50={item.badge_un_50}
                  badge_un_75={item.badge_un_75}
                  badge_un_100={item.badge_un_100}
                  badge_un_150={item.badge_un_150}
                  badge_premium={item.badge_premium}
                  auth={item.auth}
                  type={route.key}
                  updateFriendStatus={handleUpdateFriendStatus}
                  status={item.friend_status}
                  friendDbId={item.friend_db_id}
                  hideRequest={handleHideRequest}
                  loadingStatus={loadingStatus}
                />
              )}
              keyExtractor={(item) => item.user_id.toString()}
              contentContainerStyle={{ paddingBottom: 52, paddingTop: 8 }}
              showsVerticalScrollIndicator={false}
              onEndReached={handleEndReached}
              onEndReachedThreshold={0.2}
              ListFooterComponent={<ListFooter isLoading={isLoadingMore} />}
            />
          </>
        )}
      />
    </SafeAreaView>
  );
};

export default MyFriendsScreen;
