import BorderBottomItemVertical from "@/components/borderBottomItemVertical";
import SkeletonTwoItem from "@/components/skeletonTwoItem";
import Text from "@/components/Text";
import { ColorsStatus } from "@/constants/ColorsStatus";
import Styles from "@/constants/Styles";
import { apiGetNotification, apiReadOneNotification } from "@/lib/api";
import { setUpdateNotification } from "@/lib/notificationSlice";
import { pushToPage } from "@/lib/pushToPage";
import { useAuthSession } from "@/providers/AuthProvider";
import { useTheme } from "@/providers/ThemeProvider";
import { Feather } from "@expo/vector-icons";
import { useInfiniteQuery, useQueryClient } from "@tanstack/react-query";
import { useEffect, useMemo, useState } from "react";
import { RefreshControl, SafeAreaView, View, VirtualizedList } from "react-native";
import { useDispatch, useSelector } from "react-redux";

type Props = {
   id: string
   title: string
   desc: string
   category: string
   idContent: string
   isRead: boolean
   createdAt: string
}

export default function Notification() {
   const { token, decryptToken } = useAuthSession()
   const { colors } = useTheme();
   const queryClient = useQueryClient()
   const dispatch = useDispatch()
   const updateNotification = useSelector((state: any) => state.notificationUpdate)
   const [refreshing, setRefreshing] = useState(false)

   // TanStack Query for Notifications with Infinite Scroll
   const {
      data,
      fetchNextPage,
      hasNextPage,
      isFetchingNextPage,
      isLoading,
      refetch
   } = useInfiniteQuery({
      queryKey: ['notifications'],
      queryFn: async ({ pageParam = 1 }) => {
         const hasil = await decryptToken(String(token?.current))
         const response = await apiGetNotification({ user: hasil, page: pageParam })
         return response;
      },
      initialPageParam: 1,
      getNextPageParam: (lastPage, allPages) => {
         return lastPage.data.length > 0 ? allPages.length + 1 : undefined;
      },
      enabled: !!token?.current,
      staleTime: 0,
   })

   // Flatten pages into a single data array
   const flatData = useMemo(() => {
      return data?.pages.flatMap(page => page.data) || [];
   }, [data])

   // Refetch when manual update state changes
   useEffect(() => {
      refetch()
   }, [updateNotification, refetch])

   const handleRefresh = async () => {
      setRefreshing(true)
      await queryClient.invalidateQueries({ queryKey: ['notifications'] })
      setRefreshing(false)
   };

   const loadMoreData = () => {
      if (hasNextPage && !isFetchingNextPage) {
         fetchNextPage()
      }
   };

   async function handleReadNotification(id: string, category: string, idContent: string) {
      try {
         const hasil = await decryptToken(String(token?.current))
         const response = await apiReadOneNotification({ user: hasil, id: id })
         await queryClient.invalidateQueries({ queryKey: ['notifications'] })
         pushToPage(category, idContent)
         dispatch(setUpdateNotification(!updateNotification))
      } catch (error) {
         console.error(error)
      }
   }

   const arrSkeleton = [0, 1, 2, 3, 4]

   const getItem = (_data: unknown, index: number): Props => ({
      id: flatData[index]?.id,
      title: flatData[index]?.title,
      desc: flatData[index]?.desc,
      category: flatData[index]?.category,
      idContent: flatData[index]?.idContent,
      isRead: flatData[index]?.isRead,
      createdAt: flatData[index]?.createdAt,
   });

   return (
      <SafeAreaView style={[Styles.flex1, { backgroundColor: colors.background }]}>
         <View style={[Styles.p15]}>
            {
               isLoading ?
                  arrSkeleton.map((item, index) => {
                     return (
                        <SkeletonTwoItem key={index} />
                     )
                  })
                  :
                  flatData.length > 0 ?
                     <VirtualizedList
                        data={flatData}
                        getItemCount={() => flatData.length}
                        getItem={getItem}
                        renderItem={({ item, index }: { item: Props, index: number }) => {
                           return (
                              <BorderBottomItemVertical
                                 borderType="bottom"
                                 icon={
                                    <View style={[Styles.iconContent, item.isRead && ColorsStatus.secondary]}>
                                       <Feather name="bell" size={25} color="black" />
                                    </View>
                                 }
                                 title={item.title}
                                 rightTopInfo={item.createdAt}
                                 desc={item.desc}
                                 textColor={item.isRead ? 'gray' : colors.text}
                                 onPress={() => {
                                    handleReadNotification(item.id, item.category, item.idContent)
                                 }}
                                 bgColor={'transparent'}
                              />
                           )
                        }}
                        keyExtractor={(item, index) => String(index)}
                        onEndReached={loadMoreData}
                        onEndReachedThreshold={0.5}
                        showsVerticalScrollIndicator={false}
                        refreshControl={
                           <RefreshControl
                              refreshing={refreshing}
                              onRefresh={handleRefresh}
                              tintColor={colors.icon}
                           />
                        }
                     />
                     :
                     <Text style={[Styles.textDefault, Styles.textCenter, { color: colors.dimmed }]}>Tidak ada data</Text>
            }
         </View>
      </SafeAreaView>
   )
}