'use client';

import { http } from '@/lib/api';
import { useCallback, useEffect, useState } from 'react';

export interface Notification {
    _id: string;
    userId: string;
    title: string;
    message: string;
    category: 'APPOINTMENT' | 'PRESCRIPTION' | 'PAYMENT' | 'SUBSCRIPTION' | 'SYSTEM';
    action: string;
    isRead: boolean;
    readAt?: string;
    referenceId?: string;
    referenceType?: string;
    actionUrl?: string;
    metadata?: Record<string, any>;
    priority: 'low' | 'medium' | 'high';
    createdAt: string;
    updatedAt: string;
}

export interface NotificationResponse {
    notifications: Notification[];
    total: number;
    page: number;
    pages: number;
}

/**
 * Hook for fetching notifications with pagination
 */
export const useNotifications = (autoRefresh: boolean = true, refreshInterval: number = 30000) => {
    const [notifications, setNotifications] = useState<Notification[]>([]);
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [page, setPage] = useState(1);
    const [totalPages, setTotalPages] = useState(0);
    const [hasMore, setHasMore] = useState(false);

    const fetchNotifications = useCallback(async (pageNum: number = 1, limit: number = 20) => {
        setIsLoading(true);
        setError(null);
        try {
            const response = await http.get<{ success: boolean; data: NotificationResponse }>('/notifications', {
                params: { page: pageNum, limit }
            });

            if (response.data.success) {
                if (pageNum === 1) {
                    setNotifications(response.data.data.notifications);
                } else {
                    setNotifications(prev => [...prev, ...response.data.data.notifications]);
                }
                setPage(pageNum);
                setTotalPages(response.data.data.pages);
                setHasMore(pageNum < response.data.data.pages);
            }
        } catch (err: any) {
            setError(err?.response?.data?.error || 'Failed to fetch notifications');
        } finally {
            setIsLoading(false);
        }
    }, []);

    const loadMore = useCallback(() => {
        if (hasMore && !isLoading) {
            fetchNotifications(page + 1);
        }
    }, [page, hasMore, isLoading, fetchNotifications]);

    // Auto-refresh notifications
    useEffect(() => {
        if (!autoRefresh) return;

        fetchNotifications(1);
        const interval = setInterval(() => {
            fetchNotifications(1);
        }, refreshInterval);

        return () => clearInterval(interval);
    }, [autoRefresh, refreshInterval, fetchNotifications]);

    return {
        notifications,
        isLoading,
        error,
        page,
        totalPages,
        hasMore,
        fetchNotifications,
        loadMore,
        refresh: () => fetchNotifications(1)
    };
};

/**
 * Hook for getting unread notification count
 */
export const useUnreadCount = (autoRefresh: boolean = true, refreshInterval: number = 30000) => {
    const [unreadCount, setUnreadCount] = useState(0);
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);

    const fetchUnreadCount = useCallback(async () => {
        setIsLoading(true);
        try {
            const response = await http.get<{ success: boolean; data: { unreadCount: number } }>('/notifications/unread/count');
            if (response.data.success) {
                setUnreadCount(response.data.data.unreadCount);
            }
        } catch (err: any) {
            setError(err?.response?.data?.error || 'Failed to fetch unread count');
        } finally {
            setIsLoading(false);
        }
    }, []);

    // Auto-refresh unread count
    useEffect(() => {
        fetchUnreadCount();
        
        if (!autoRefresh) return;

        const interval = setInterval(fetchUnreadCount, refreshInterval);
        return () => clearInterval(interval);
    }, [autoRefresh, refreshInterval, fetchUnreadCount]);

    return { unreadCount, isLoading, error, refresh: fetchUnreadCount };
};

/**
 * Hook for getting recent notifications (for dashboard)
 */
export const useRecentNotifications = (limit: number = 10, autoRefresh: boolean = true, refreshInterval: number = 30000) => {
    const [notifications, setNotifications] = useState<Notification[]>([]);
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);

    const fetchRecent = useCallback(async () => {
        setIsLoading(true);
        try {
            const response = await http.get<{ success: boolean; data: Notification[] }>('/notifications/recent', {
                params: { limit }
            });
            if (response.data.success) {
                setNotifications(response.data.data);
            }
        } catch (err: any) {
            setError(err?.response?.data?.error || 'Failed to fetch recent notifications');
        } finally {
            setIsLoading(false);
        }
    }, [limit]);

    useEffect(() => {
        fetchRecent();
        
        if (!autoRefresh) return;

        const interval = setInterval(fetchRecent, refreshInterval);
        return () => clearInterval(interval);
    }, [autoRefresh, refreshInterval, fetchRecent]);

    return { notifications, isLoading, error, refresh: fetchRecent };
};

/**
 * Hook for marking notifications as read/unread
 */
export const useNotificationActions = () => {
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);

    const markAsRead = useCallback(async (notificationId: string): Promise<Notification | null> => {
        setIsLoading(true);
        setError(null);
        try {
            const response = await http.put<{ success: boolean; data: Notification }>(`/notifications/${notificationId}/read`);
            if (response.data.success) {
                return response.data.data;
            }
            return null;
        } catch (err: any) {
            const errorMsg = err?.response?.data?.error || 'Failed to mark as read';
            setError(errorMsg);
            return null;
        } finally {
            setIsLoading(false);
        }
    }, []);

    const markAsUnread = useCallback(async (notificationId: string): Promise<Notification | null> => {
        setIsLoading(true);
        setError(null);
        try {
            const response = await http.put<{ success: boolean; data: Notification }>(`/notifications/${notificationId}/unread`);
            if (response.data.success) {
                return response.data.data;
            }
            return null;
        } catch (err: any) {
            const errorMsg = err?.response?.data?.error || 'Failed to mark as unread';
            setError(errorMsg);
            return null;
        } finally {
            setIsLoading(false);
        }
    }, []);

    const markAllAsRead = useCallback(async (): Promise<boolean> => {
        setIsLoading(true);
        setError(null);
        try {
            const response = await http.post<{ success: boolean }>('/notifications/mark-all/read');
            if (response.data.success) {
                return true;
            }
            return false;
        } catch (err: any) {
            const errorMsg = err?.response?.data?.error || 'Failed to mark all as read';
            setError(errorMsg);
            return false;
        } finally {
            setIsLoading(false);
        }
    }, []);

    const deleteNotification = useCallback(async (notificationId: string): Promise<boolean> => {
        setIsLoading(true);
        setError(null);
        try {
            const response = await http.delete<{ success: boolean }>(`/notifications/${notificationId}`);
            if (response.data.success) {
                return true;
            }
            return false;
        } catch (err: any) {
            const errorMsg = err?.response?.data?.error || 'Failed to delete notification';
            setError(errorMsg);
            return false;
        } finally {
            setIsLoading(false);
        }
    }, []);

    const deleteAllNotifications = useCallback(async (): Promise<boolean> => {
        setIsLoading(true);
        setError(null);
        try {
            const response = await http.delete<{ success: boolean }>('/notifications');
            if (response.data.success) {
                return true;
            }
            return false;
        } catch (err: any) {
            const errorMsg = err?.response?.data?.error || 'Failed to delete notifications';
            setError(errorMsg);
            return false;
        } finally {
            setIsLoading(false);
        }
    }, []);

    return {
        markAsRead,
        markAsUnread,
        markAllAsRead,
        deleteNotification,
        deleteAllNotifications,
        isLoading,
        error
    };
};

/**
 * Hook for getting notification history for a specific reference
 */
export const useNotificationHistory = (referenceId: string, referenceType: string) => {
    const [notifications, setNotifications] = useState<Notification[]>([]);
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);

    const fetchHistory = useCallback(async () => {
        if (!referenceId || !referenceType) return;

        setIsLoading(true);
        try {
            const response = await http.get<{ success: boolean; data: Notification[] }>(
                `/notifications/history/${referenceId}/${referenceType}`
            );
            if (response.data.success) {
                setNotifications(response.data.data);
            }
        } catch (err: any) {
            setError(err?.response?.data?.error || 'Failed to fetch notification history');
        } finally {
            setIsLoading(false);
        }
    }, [referenceId, referenceType]);

    useEffect(() => {
        fetchHistory();
    }, [fetchHistory]);

    return { notifications, isLoading, error, refresh: fetchHistory };
};
