import { browser } from '$app/environment';
import { client } from '$lib/graphql/client';
import {
	UNREAD_MESSAGE_COUNT_QUERY,
	type UnreadMessageCountQueryResult
} from '$lib/graphql/queries/messaging';
import {
	MY_UNREAD_NOTIFICATION_COUNT_QUERY,
	type MyUnreadNotificationCountQueryResult
} from '$lib/graphql/queries/notifications';

const POLL_INTERVAL = 30000; // 30 seconds

function createUnreadCountsStore() {
	let messageCount = $state(0);
	let notificationCount = $state(0);
	let isPolling = $state(false);
	let pollIntervalId: ReturnType<typeof setInterval> | null = null;

	const totalCount = $derived(messageCount + notificationCount);
	const hasUnread = $derived(totalCount > 0);

	/**
	 * Fetch current unread counts from the server
	 */
	async function fetchCounts(): Promise<void> {
		if (!browser) return;

		try {
			const [messageResult, notificationResult] = await Promise.all([
				client.query<UnreadMessageCountQueryResult>({
					query: UNREAD_MESSAGE_COUNT_QUERY,
					fetchPolicy: 'network-only'
				}),
				client.query<MyUnreadNotificationCountQueryResult>({
					query: MY_UNREAD_NOTIFICATION_COUNT_QUERY,
					fetchPolicy: 'network-only'
				})
			]);

			if (messageResult.data) {
				messageCount = messageResult.data.unreadMessageCount;
			}
			if (notificationResult.data) {
				notificationCount = notificationResult.data.myUnreadNotificationCount;
			}
		} catch (error) {
			console.warn('Failed to fetch unread counts:', error);
		}
	}

	/**
	 * Start polling for unread counts
	 */
	function startPolling(): void {
		if (!browser || isPolling) return;

		isPolling = true;

		// Fetch immediately
		fetchCounts();

		// Set up interval
		pollIntervalId = setInterval(() => {
			fetchCounts();
		}, POLL_INTERVAL);
	}

	/**
	 * Stop polling for unread counts
	 */
	function stopPolling(): void {
		if (pollIntervalId) {
			clearInterval(pollIntervalId);
			pollIntervalId = null;
		}
		isPolling = false;
	}

	/**
	 * Increment message count (optimistic update)
	 */
	function incrementMessages(by = 1): void {
		messageCount = Math.max(0, messageCount + by);
	}

	/**
	 * Decrement message count (optimistic update)
	 */
	function decrementMessages(by = 1): void {
		messageCount = Math.max(0, messageCount - by);
	}

	/**
	 * Clear all message counts
	 */
	function clearMessages(): void {
		messageCount = 0;
	}

	/**
	 * Increment notification count (optimistic update)
	 */
	function incrementNotifications(by = 1): void {
		notificationCount = Math.max(0, notificationCount + by);
	}

	/**
	 * Decrement notification count (optimistic update)
	 */
	function decrementNotifications(by = 1): void {
		notificationCount = Math.max(0, notificationCount - by);
	}

	/**
	 * Clear all notification counts
	 */
	function clearNotifications(): void {
		notificationCount = 0;
	}

	/**
	 * Reset all counts
	 */
	function reset(): void {
		messageCount = 0;
		notificationCount = 0;
	}

	/**
	 * Format count for display (caps at 99+)
	 */
	function formatCount(count: number): string {
		if (count <= 0) return '';
		if (count > 99) return '99+';
		return count.toString();
	}

	return {
		get messageCount() {
			return messageCount;
		},
		get notificationCount() {
			return notificationCount;
		},
		get totalCount() {
			return totalCount;
		},
		get hasUnread() {
			return hasUnread;
		},
		get isPolling() {
			return isPolling;
		},
		get formattedMessageCount() {
			return formatCount(messageCount);
		},
		get formattedNotificationCount() {
			return formatCount(notificationCount);
		},
		get formattedTotalCount() {
			return formatCount(totalCount);
		},
		fetchCounts,
		startPolling,
		stopPolling,
		incrementMessages,
		decrementMessages,
		clearMessages,
		incrementNotifications,
		decrementNotifications,
		clearNotifications,
		reset
	};
}

export const unreadCounts = createUnreadCountsStore();
