import AppText from "@/components/ui/app-text";
import BackButtonTitle from "@/components/ui/BackButtonTitle";
import { privateInstance } from "@/configs/axiosConfig";
import { getQueryClient } from "@/configs/query-client";
import { useGetQuery } from "@/hooks/mutate/useGetQuery";
import { useColor } from "@/hooks/useColor";
import { useTranslations } from "@/providers/TranslationProviders";
import { showToast } from "@/utils/toast";
import { BellIcon, BellSlashIcon, CheckIcon, ChecksIcon, ClockIcon } from "phosphor-react-native";
import { useCallback, useEffect, useState } from "react";
import { ActivityIndicator, FlatList, Pressable, RefreshControl, Text, View } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";

interface Notification {
  id: string;
  title: string;
  data: string;
  read_at: string | null;
  created_at: string;
}

export default function NotificationsScreen() {
  const { tran, translateNumber } = useTranslations();
  const { primary } = useColor();
  const [page, setPage] = useState(1);
  const [items, setItems] = useState<Notification[]>([]);
  const [hasMore, setHasMore] = useState(true);
  const [markingAll, setMarkingAll] = useState(false);
  const [markingIds, setMarkingIds] = useState<Set<string>>(new Set());

  const {
    data: notifData,
    isFetching,
    refetch,
  } = useGetQuery({
    url: `/client/notifications?page=${page}`,
    queryKey: ["notifications", page],
  });

  useEffect(() => {
    if (notifData?.data) {
      if (page === 1) {
        setItems(notifData.data);
      } else {
        setItems((prev) => {
          const existingIds = new Set(prev.map((i) => i.id));
          const newItems = notifData.data.filter((i: Notification) => !existingIds.has(i.id));
          return [...prev, ...newItems];
        });
      }
      setHasMore(notifData.current_page < notifData.last_page);
    }
  }, [notifData, page]);

  const onRefresh = useCallback(() => {
    setPage(1);
    refetch();
  }, [refetch]);

  const loadMore = () => {
    if (!isFetching && hasMore) {
      setPage((prev) => prev + 1);
    }
  };

  const formatTimeAgo = (dateStr: string) => {
    const now = new Date();
    const date = new Date(dateStr);
    const diff = Math.floor((now.getTime() - date.getTime()) / 1000);

    if (diff < 60) return tran("Just now");
    if (diff < 3600) return `${Math.floor(diff / 60)} ${tran("min ago")}`;
    if (diff < 86400) return `${Math.floor(diff / 3600)} ${tran("hr ago")}`;
    if (diff < 604800) return `${Math.floor(diff / 86400)} ${tran("days ago")}`;

    return date.toLocaleDateString("en-US", {
      month: "short",
      day: "numeric",
      year: "numeric",
    });
  };

  const handleMarkAsRead = async (id: string) => {
    setMarkingIds((prev) => new Set(prev).add(id));
    try {
      await privateInstance.put(`/client/notifications/${id}`);
      setItems((prev) => prev.map((n) => (n.id === id ? { ...n, read_at: new Date().toISOString() } : n)));
      getQueryClient().invalidateQueries({
        queryKey: ["notifications"],
      });
    } catch (err) {
      console.warn("Failed to mark as read", err);
    } finally {
      setMarkingIds((prev) => {
        const next = new Set(prev);
        next.delete(id);
        return next;
      });
    }
  };

  const handleMarkAllAsRead = async () => {
    setMarkingAll(true);
    try {
      await privateInstance.put("/client/notifications");
      setItems((prev) =>
        prev.map((n) => ({
          ...n,
          read_at: n.read_at || new Date().toISOString(),
        })),
      );
      getQueryClient().invalidateQueries({
        queryKey: ["notifications"],
      });
      showToast({
        type: "success",
        text: tran("All notifications marked as read"),
      });
    } catch (err) {
      console.warn("Failed to mark all as read", err);
    } finally {
      setMarkingAll(false);
    }
  };

  const unreadCount = items.filter((n) => !n.read_at).length;

  return (
    <View className="bg-white flex-1">
      <SafeAreaView className="flex-1">
        <View className="px-4">
          <BackButtonTitle title={tran("Notifications")} />
        </View>

        <FlatList
          data={items}
          keyExtractor={(item, idx) => `notif-${item.id ?? idx}-${idx}`}
          showsVerticalScrollIndicator={false}
          onEndReached={loadMore}
          onEndReachedThreshold={0.5}
          refreshControl={<RefreshControl refreshing={isFetching && page === 1} onRefresh={onRefresh} />}
          ListHeaderComponent={
            <View className="px-4 pt-4 pb-2">
              {/* Unread Badge & Mark All */}
              <View className="flex-row justify-between items-center mb-4">
                <View className="flex-row items-center gap-2">
                  <BellIcon size={18} color={primary.base} weight="fill" />
                  <AppText className="font-manrope-bold text-slate-900">{unreadCount > 0 ? `${translateNumber(unreadCount)} ${tran("unread")}` : tran("All caught up!")}</AppText>
                </View>

                {unreadCount > 0 && (
                  <Pressable onPress={handleMarkAllAsRead} disabled={markingAll} className="flex-row items-center gap-1.5 px-3 py-2 rounded-xl" style={{ backgroundColor: primary[5] }}>
                    {markingAll ? <ActivityIndicator size="small" color={primary.base} /> : <View pointerEvents="none"><ChecksIcon size={16} color={primary.base} weight="bold" /></View>}
                    <Text className="text-xs font-manrope-bold" style={{ color: primary.base }}>
                      {tran("Mark All Read")}
                    </Text>
                  </Pressable>
                )}
              </View>
            </View>
          }
          renderItem={({ item }) => {
            const isUnread = !item.read_at;
            const isMarking = markingIds.has(item.id);

            return (
              <Pressable
                onPress={() => {
                  if (isUnread && !isMarking) {
                    handleMarkAsRead(item.id);
                  }
                }}
                className="mx-4 mb-3 p-4 rounded-[24px] border"
                style={{
                  backgroundColor: isUnread ? primary[5] : "#fff",
                  borderColor: isUnread ? primary[10] : "#f1f5f9",
                }}
              >
                <View className="flex-row items-start gap-3">
                  {/* Icon */}
                  <View
                    className="size-10 rounded-full items-center justify-center mt-0.5"
                    style={{
                      backgroundColor: isUnread ? primary[10] : "#f1f5f9",
                    }}
                  >
                    <BellIcon size={18} color={isUnread ? primary.base : "#94a3b8"} weight={isUnread ? "fill" : "regular"} />
                  </View>

                  {/* Content */}
                  <View className="flex-1">
                    <View className="flex-row items-start justify-between gap-2">
                      <AppText className={`flex-1 ${isUnread ? "font-manrope-bold text-slate-900" : "font-manrope-semibold text-slate-600"}`}>{item.title || tran("Notification")}</AppText>

                      {isUnread && (
                        <View className="flex-row items-center gap-1">
                          {isMarking ? (
                            <ActivityIndicator size="small" color={primary.base} />
                          ) : (
                            <View
                              className="size-2.5 rounded-full"
                              style={{
                                backgroundColor: primary.base,
                              }}
                            />
                          )}
                        </View>
                      )}

                      {!isUnread && <CheckIcon size={14} color="#94a3b8" weight="bold" />}
                    </View>

                    <AppText className="text-slate-500 text-xs font-manrope mt-1 leading-5">{item.data}</AppText>

                    <View className="flex-row items-center gap-1 mt-2">
                      <ClockIcon size={12} color="#94a3b8" weight="regular" />
                      <Text className="text-[10px] text-slate-400 font-manrope-medium">{formatTimeAgo(item.created_at)}</Text>
                    </View>
                  </View>
                </View>
              </Pressable>
            );
          }}
          ListEmptyComponent={
            !isFetching ? (
              <View className="items-center justify-center py-24 opacity-40">
                <BellSlashIcon size={56} color="#94a3b8" />
                <AppText className="mt-4 font-manrope-bold text-slate-400">{tran("No notifications")}</AppText>
                <AppText className="text-xs text-slate-400 font-manrope mt-1">{tran("You're all caught up!")}</AppText>
              </View>
            ) : null
          }
          ListFooterComponent={isFetching && page > 1 ? <ActivityIndicator style={{ margin: 16 }} color={primary.base} /> : null}
        />
      </SafeAreaView>
    </View>
  );
}
