import React, { useState, useEffect, useCallback } from 'react';
import { useAuth } from '../context/useAuth';
import api from '../services/api';
import type { INotification } from '../types';
import { NotificationContext } from './NotificationContextState';

export const NotificationProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
    const { appUser, isSignedIn } = useAuth();
    const [notifications, setNotifications] = useState<INotification[]>([]);
    const [loading, setLoading] = useState(false);

    const fetchNotifications = useCallback(async () => {
        if (!isSignedIn) return;

        try {
            if (notifications.length === 0) setLoading(true);
            const response = await api.get('/notifications');
            setNotifications(response.data);
        } catch (error) {
            console.error('Failed to fetch notifications', error);
        } finally {
            setLoading(false);
        }
    }, [isSignedIn, notifications.length]);

    const markAsRead = async (id: string) => {
        try {
            await api.put(`/notifications/${id}/read`);
            setNotifications(prev => prev.map(n => n._id === id ? { ...n, isRead: true } : n));
        } catch (error) {
            console.error('Failed to mark as read', error);
        }
    };

    const markAllAsRead = async () => {
        try {
            await api.put('/notifications/read-all');
            setNotifications(prev => prev.map(n => ({ ...n, isRead: true })));
        } catch (error) {
            console.error('Failed to mark all as read', error);
        }
    }

    const clearAll = async () => {
        try {
            await api.delete('/notifications/clear-all');
            setNotifications([]);
        } catch (error) {
            console.error('Failed to clear all notifications', error);
        }
    };

    const archiveNotification = async (id: string) => {
        try {
            await api.patch(`/notifications/${id}/archive`);
            setNotifications(prev => prev.filter(n => n._id !== id));
        } catch (error) {
            console.error('Failed to archive notification', error);
        }
    };

    const deleteNotification = async (id: string) => {
        try {
            await api.delete(`/notifications/${id}`);
            setNotifications(prev => prev.filter(n => n._id !== id));
        } catch (error) {
            console.error('Failed to delete notification', error);
        }
    };

    // Polling effect
    useEffect(() => {
        if (isSignedIn) {
            fetchNotifications(); // Initial fetch

            const interval = setInterval(() => {
                fetchNotifications();
            }, 30000); // Poll every 30 seconds

            return () => clearInterval(interval);
        } else {
            setNotifications([]);
        }
    }, [isSignedIn, fetchNotifications]);

    const unreadCount = notifications.filter(n => !n.isRead).length;

    return (
        <NotificationContext.Provider value={{
            notifications,
            unreadCount,
            loading,
            markAsRead,
            markAllAsRead,
            clearAll,
            archiveNotification,
            deleteNotification,
            fetchNotifications
        }}>
            {children}
        </NotificationContext.Provider>
    );
};
