import AsyncStorage from "@react-native-async-storage/async-storage";
import * as Notifications from "expo-notifications";
import { useEffect } from "react";
import { Category, categoryKeys } from "types/Category";
import { Item } from "types/Item";

const STORAGE_KEY = "notifications-data";

// Hook: listens for incoming notifications → Item + persists them
export function useNotificationListener(onItems: (items: Item[]) => void) {
	useEffect(() => {
		// Load saved notifications on mount
		(async () => {
			try {
				const saved = await AsyncStorage.getItem(STORAGE_KEY);
				if (saved) {
					const parsed: Item[] = JSON.parse(saved);
					// sort newest first
					onItems(parsed.sort((a, b) => b.timestamp - a.timestamp));
				}
			} catch (e) {
				console.error("Failed to load notifications from storage:", e);
			}
		})();

		// Listen for notification received while app is in foreground
		const receivedSub = Notifications.addNotificationReceivedListener(async (notification) => {
			const item = mapNotificationToItem(notification);
			if (item) {
				await addItem(item, onItems);
			}
		});

		// Listen for when user taps a notification
		const responseSub = Notifications.addNotificationResponseReceivedListener(async (response) => {
			const item = mapNotificationToItem(response.notification);
			if (item) {
				await addItem(item, onItems);
			}
		});

		// Cleanup on unmount
		return () => {
			receivedSub.remove();
			responseSub.remove();
		};
	}, [onItems]);
}

// Convert Expo notification → Item
function mapNotificationToItem(notification: Notifications.Notification): Item | null {
	try {
		const content = notification.request.content;
		const rawCategory = content.data?.category as Category | undefined;
		const category: Category = rawCategory && categoryKeys.includes(rawCategory) ? rawCategory : "home";

		return {
			timestamp: Date.now(), // could use backend timestamp if provided
			category,
			title: content.title ?? "No title",
			info: content.body ?? "No details",
			link: (content.data?.link as string) ?? "",
		};
	} catch (e) {
		console.error("Failed to map notification to Item:", e);
		return null;
	}
}

export { mapNotificationToItem };

// Save a new item into storage and update state
async function addItem(item: Item, onItems: (items: Item[]) => void) {
	try {
		const saved = await AsyncStorage.getItem(STORAGE_KEY);
		const prev: Item[] = saved ? JSON.parse(saved) : [];

		const updated = [item, ...prev].sort((a, b) => b.timestamp - a.timestamp);

		await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(updated));
		onItems(updated);
	} catch (e) {
		console.error("Failed to persist notification:", e);
	}
}
