"use client"

import React, { createContext, useContext, useEffect, useState } from 'react';
import { AdminNotification } from '@/types/admin.types';
import { useNotificationSocket } from '@/hooks/useNotificationSocket';
import { adminApi } from '@/lib/api/admin';

interface AdminNotificationContextType {
  notifications: AdminNotification[];
  unreadCount: number;
  isConnected: boolean;
  refreshNotifications: () => Promise<void>;
  markAsRead: (id: string) => Promise<void>;
  markAllAsRead: () => Promise<void>;
  clearAll: () => Promise<void>;
  removeByReference: (referenceType: string, referenceId: string) => void;
}

const AdminNotificationContext = createContext<AdminNotificationContextType | undefined>(undefined);

export function AdminNotificationProvider({ children }: { children: React.ReactNode }) {
  const [notifications, setNotifications] = useState<AdminNotification[]>([]);
  const [, setIsLoading] = useState(false);
  
  const { 
    isConnected, 
    notificationCounts, 
    onNewNotification, 
    onNotificationRead, 
    onAllNotificationsRead 
  } = useNotificationSocket();

  // Load initial notifications
  const refreshNotifications = async () => {
    try {
      setIsLoading(true);
      const data = await adminApi.getNotifications(false, 100, 0);
      setNotifications(data);
    } catch (error) {
      console.error('Error fetching notifications:', error);
    } finally {
      setIsLoading(false);
    }
  };

  // Mark single notification as read
  const markAsRead = async (id: string) => {
    try {
      await adminApi.markNotificationAsRead(id);
      setNotifications(prev => 
        prev.map(n => n.id === id ? { ...n, is_read: true, read_at: new Date().toISOString() } : n)
      );
    } catch (error) {
      console.error('Error marking notification as read:', error);
      throw error;
    }
  };

  // Mark all notifications as read
  const markAllAsRead = async () => {
    try {
      await adminApi.markAllNotificationsAsRead();
      setNotifications(prev => 
        prev.map(n => ({ ...n, is_read: true, read_at: new Date().toISOString() }))
      );
    } catch (error) {
      console.error('Error marking all notifications as read:', error);
      throw error;
    }
  };

  // Clear all notifications from UI (after marking as read server-side)
  const clearAll = async () => {
    await markAllAsRead();
    setNotifications([]);
  };

  // Remove notifications tied to a specific backend reference (e.g., feature/template id)
  const removeByReference = (referenceType: string, referenceId: string) => {
    setNotifications(prev => prev.filter(n => !(n.reference_type === referenceType && n.reference_id === referenceId)));
  };

  // Set up WebSocket event handlers
  useEffect(() => {
    onNewNotification((notification: AdminNotification) => {
      setNotifications(prev => [notification, ...prev]);
    });

    onNotificationRead(({ id }: { id: string }) => {
      setNotifications(prev => 
        prev.map(n => n.id === id ? { ...n, is_read: true, read_at: new Date().toISOString() } : n)
      );
    });

    onAllNotificationsRead(() => {
      setNotifications(prev => 
        prev.map(n => ({ ...n, is_read: true, read_at: new Date().toISOString() }))
      );
    });
  }, [onNewNotification, onNotificationRead, onAllNotificationsRead]);

  // Load notifications on mount
  useEffect(() => {
    refreshNotifications();
  }, []);

  // When socket connects (e.g., navigating to admin), refresh to include any
  // notifications created before the connection was established
  useEffect(() => {
    if (isConnected) {
      refreshNotifications();
    }
  }, [isConnected]);

  const value: AdminNotificationContextType = {
    notifications,
    unreadCount: notificationCounts.unread > 0
      ? notificationCounts.unread
      : notifications.reduce((acc, n) => acc + (n.is_read ? 0 : 1), 0),
    isConnected,
    refreshNotifications,
    markAsRead,
    markAllAsRead,
    clearAll,
    removeByReference,
  };

  return (
    <AdminNotificationContext.Provider value={value}>
      {children}
    </AdminNotificationContext.Provider>
  );
}

export function useAdminNotifications() {
  const context = useContext(AdminNotificationContext);
  if (context === undefined) {
    throw new Error('useAdminNotifications must be used within an AdminNotificationProvider');
  }
  return context;
}
