import React, { useCallback, useEffect, useState, useMemo } from "react";
import { View, ActivityIndicator, FlatList, RefreshControl, Pressable } from "react-native";
import { Text } from "@/components/ui/text";
import { ScreenWrapper } from "@/components/ScreenWrapper";
import { StandardHeader } from "@/components/StandardHeader";
import { api } from "@/lib/api";
import { EmptyState } from "@/components/EmptyState";
import { Bell, Clock } from "@/lib/icons";

type NotificationItem = {
  id: string;
  title?: string;
  body?: string;
  icon?: string;
  url?: string;
  sentAt?: string;
  createdAt?: string;
  isSent?: boolean;
};

function formatRelativeTime(dateString: string): string {
  const now = new Date();
  const date = new Date(dateString);
  const diffMs = now.getTime() - date.getTime();
  const diffMins = Math.floor(diffMs / 60000);
  const diffHours = Math.floor(diffMins / 60);
  const diffDays = Math.floor(diffHours / 24);

  if (diffMins < 1) return "Just now";
  if (diffMins < 60) return `${diffMins} min${diffMins > 1 ? "s" : ""} ago`;
  if (diffHours < 24) return `${diffHours} hr${diffHours > 1 ? "s" : ""} ago`;
  if (diffDays === 1) return "Yesterday";
  if (diffDays < 7) return `${diffDays} days ago`;
  return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
}

function getDateGroup(dateString: string): string {
  const now = new Date();
  const date = new Date(dateString);
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  const yesterday = new Date(today);
  yesterday.setDate(yesterday.getDate() - 1);
  const itemDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());

  if (itemDate.getTime() === today.getTime()) return "Today";
  if (itemDate.getTime() === yesterday.getTime()) return "Yesterday";
  if (now.getTime() - itemDate.getTime() < 7 * 86400000) return "This Week";
  return date.toLocaleDateString("en-US", { month: "long", year: "numeric" });
}

type SectionItem = {
  type: "header" | "item";
  key: string;
  item?: NotificationItem;
  isLast?: boolean;
};

export default function NotificationsScreen() {
  const [items, setItems] = useState<NotificationItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);

  const fetchNotifications = useCallback(
    async (pageNum: number, mode: "initial" | "refresh" | "more") => {
      try {
        if (mode === "initial") setLoading(true);
        if (mode === "refresh") setRefreshing(true);
        if (mode === "more") setLoadingMore(true);

        const res = await (api as any).notifications.getAll({
          query: { page: pageNum, limit: 20 },
        });

        const next = (res?.data ?? []) as NotificationItem[];
        if (mode === "more") {
          setItems((prev) => [...prev, ...next]);
        } else {
          setItems(next);
        }

        setHasMore(Boolean(res?.meta?.hasNextPage));
        setPage(pageNum);
      } catch (e) {
        setHasMore(false);
      } finally {
        setLoading(false);
        setRefreshing(false);
        setLoadingMore(false);
      }
    },
    [],
  );

  useEffect(() => {
    fetchNotifications(1, "initial");
  }, [fetchNotifications]);

  const onRefresh = () => fetchNotifications(1, "refresh");
  const onEndReached = () => {
    if (!loading && !loadingMore && hasMore) fetchNotifications(page + 1, "more");
  };

  const grouped = useMemo(() => {
    const groups: Record<string, NotificationItem[]> = {};
    for (const item of items) {
      const dateStr = item.sentAt || item.createdAt;
      const group = dateStr ? getDateGroup(dateStr) : "Other";
      if (!groups[group]) groups[group] = [];
      groups[group].push(item);
    }
    return Object.entries(groups);
  }, [items]);

  const sections = useMemo(() => {
    const data: SectionItem[] = [];
    for (const [title, groupItems] of grouped) {
      data.push({ type: "header", key: `header-${title}` });
      groupItems.forEach((item, idx) => {
        data.push({
          type: "item",
          key: item.id,
          item,
          isLast: idx === groupItems.length - 1,
        });
      });
    }
    return data;
  }, [grouped]);

  const renderSectionHeader = (title: string) => (
    <View className="px-5 pt-5 pb-2">
      <Text className="text-[13px] font-sans-bold text-muted-foreground uppercase tracking-wider">
        {title}
      </Text>
    </View>
  );

  const renderItem = ({ item, isLast }: { item: NotificationItem; isLast: boolean }) => {
    const time = item.sentAt || item.createdAt
      ? formatRelativeTime(item.sentAt || item.createdAt!)
      : "";

    const iconName = item.icon || "bell";

    return (
      <View className={`${!isLast ? "border-b border-border/40" : ""}`}>
        <View className="flex-row items-center px-5 py-3 bg-card">
          {/* Icon */}
          <View className="w-12 h-12 rounded-full bg-primary/10 items-center justify-center flex-shrink-0">
            <Bell size={20} color="white" strokeWidth={2} />
          </View>

          {/* Content */}
          <View className="flex-1 ml-3 min-w-0">
            <Text
              className="text-[14px] font-sans-bold text-foreground"
              numberOfLines={1}
            >
              {item.title || "Notification"}
            </Text>
            {item.body ? (
              <Text
                className="text-muted-foreground text-[13px] font-sans-medium mt-0.5"
                numberOfLines={1}
              >
                {item.body}
              </Text>
            ) : null}
          </View>

          {/* Time + Unread dot */}
          <View className="items-end ml-2 flex-shrink-0">
            {time ? (
              <Text className="text-muted-foreground/60 text-[11px] font-sans-medium">
                {time}
              </Text>
            ) : null}
            <View className="w-2 h-2 rounded-full bg-blue-500 mt-1.5" />
          </View>
        </View>
      </View>
    );
  };

  return (
    <ScreenWrapper className="bg-background">
      <StandardHeader
        showBack
        title="Notifications"
        rightAction="notificationsSettings"
      />

      {loading ? (
        <View className="flex-1 items-center justify-center">
          <ActivityIndicator size="large" color="#E46212" />
        </View>
      ) : (
        <FlatList
          data={sections}
          keyExtractor={(i) => i.key}
          renderItem={({ item }) => {
            if (item.type === "header") {
              return renderSectionHeader(item.key.replace("header-", ""));
            }
            return renderItem({ item: item.item!, isLast: item.isLast! });
          }}
          contentContainerStyle={{ paddingBottom: 32 }}
          onEndReached={onEndReached}
          onEndReachedThreshold={0.4}
          refreshControl={
            <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
          }
          ListEmptyComponent={
            <View className="px-5 py-12">
              <EmptyState
                title="No notifications"
                description="You're all caught up!"
                centered
              />
            </View>
          }
          ListFooterComponent={
            loadingMore ? (
              <View className="py-4">
                <ActivityIndicator size="small" color="#E46212" />
              </View>
            ) : null
          }
        />
      )}
    </ScreenWrapper>
  );
}
