"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import { createClient } from "@/lib/supabase/client";
import type { Notification } from "@/lib/types";
import type { RealtimeChannel } from "@supabase/supabase-js";

interface UseNotificationsOptions {
  limit?: number;
  unreadOnly?: boolean;
}

interface UseNotificationsReturn {
  notifications: Notification[];
  unreadCount: number;
  loading: boolean;
  error: Error | null;
  markAsRead: (id: string) => Promise<void>;
  markAllAsRead: () => Promise<void>;
  refetch: () => Promise<void>;
}

/**
 * Hook to fetch and manage notifications from Supabase
 * 
 * Features:
 * - Fetches notifications for the current user
 * - Real-time updates via Supabase subscriptions
 * - Mark individual or all notifications as read
 * - Unread count tracking
 * 
 * @example
 * ```tsx
 * const { notifications, unreadCount, markAsRead } = useNotifications({ limit: 10 });
 * ```
 */
export function useNotifications(options: UseNotificationsOptions = {}): UseNotificationsReturn {
  const { limit = 50, unreadOnly = false } = options;
  const [notifications, setNotifications] = useState<Notification[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);
  const [userId, setUserId] = useState<string | null>(null);
  const channelRef = useRef<RealtimeChannel | null>(null);
  const supabase = createClient();

  const fetchNotifications = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);

      const { data: { user }, error: authError } = await supabase.auth.getUser();
      if (authError) {
        throw new Error(`Auth error: ${authError.message}`);
      }
      
      if (!user) {
        setNotifications([]);
        setUserId(null);
        setLoading(false);
        return;
      }

      setUserId(user.id);

      let query = supabase
        .from("notifications")
        .select("id, profile_id, type, title, body, data, read, created_at")
        .eq("profile_id", user.id)
        .order("created_at", { ascending: false });

      if (unreadOnly) {
        query = query.eq("read", false);
      }

      if (limit) {
        query = query.limit(limit);
      }

      const { data, error: fetchError } = await query;

      if (fetchError) {
        throw new Error(fetchError.message);
      }

      setNotifications((data as Notification[]) ?? []);
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : "Failed to fetch notifications";
      console.error("Notifications fetch error:", errorMessage);
      setError(new Error(errorMessage));
    } finally {
      setLoading(false);
    }
  }, [supabase, limit, unreadOnly]);

  // Calculate unread count from notifications
  const unreadCount = notifications.filter((n) => !n.read).length;

  // Mark a single notification as read
  const markAsRead = useCallback(async (id: string) => {
    try {
      const { error: updateError } = await supabase
        .from("notifications")
        .update({ read: true })
        .eq("id", id);

      if (updateError) {
        throw new Error(updateError.message);
      }

      // Optimistically update local state
      setNotifications((prev) =>
        prev.map((n) => (n.id === id ? { ...n, read: true } : n))
      );
    } catch (err) {
      throw err;
    }
  }, [supabase]);

  // Mark all notifications as read
  const markAllAsRead = useCallback(async () => {
    try {
      const { data: { user } } = await supabase.auth.getUser();
      if (!user) return;

      const { error: updateError } = await supabase
        .from("notifications")
        .update({ read: true })
        .eq("profile_id", user.id)
        .eq("read", false);

      if (updateError) {
        throw new Error(updateError.message);
      }

      // Optimistically update local state
      setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));
    } catch (err) {
      throw err;
    }
  }, [supabase]);

  // Refetch notifications
  const refetch = useCallback(async () => {
    await fetchNotifications();
  }, [fetchNotifications]);

  // Initial fetch
  useEffect(() => {
    fetchNotifications();
  }, [fetchNotifications]);

  // TODO: Re-enable real-time updates when needed
  // For now, we'll rely on manual refresh to avoid WebSocket connection issues
  // 
  // Future enhancement: Add real-time subscriptions for notifications
  // when the app scales and needs instant notification delivery

  return {
    notifications,
    unreadCount,
    loading,
    error,
    markAsRead,
    markAllAsRead,
    refetch,
  };
}

/**
 * Hook to get only the unread notification count
 * Lightweight version for header/badge use
 * 
 * @example
 * ```tsx
 * const { count } = useUnreadCount();
 * ```
 */
export function useUnreadCount(): { count: number; loading: boolean; error: Error | null } {
  const [count, setCount] = useState(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);
  const [userId, setUserId] = useState<string | null>(null);
  const channelRef = useRef<RealtimeChannel | null>(null);
  const supabase = createClient();

  const fetchCount = useCallback(async () => {
    try {
      const { data: { user }, error: authError } = await supabase.auth.getUser();
      if (authError) {
        throw new Error(`Auth error: ${authError.message}`);
      }
      
      if (!user) {
        setCount(0);
        setUserId(null);
        setLoading(false);
        return;
      }

      setUserId(user.id);

      const { count: unreadCount, error: countError } = await supabase
        .from("notifications")
        .select("*", { count: "exact", head: true })
        .eq("profile_id", user.id)
        .eq("read", false);

      if (countError) {
        throw new Error(countError.message);
      }

      setCount(unreadCount ?? 0);
      setError(null);
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : "Failed to fetch unread count";
      console.error("Unread count fetch error:", errorMessage);
      setError(new Error(errorMessage));
    } finally {
      setLoading(false);
    }
  }, [supabase]);

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

  // TODO: Re-enable real-time updates when needed
  // For now, we'll rely on periodic refresh to avoid WebSocket connection issues

  return { count, loading, error };
}
