'use client';

import { createContext, useContext, useState, useCallback, useRef } from 'react';
import { usePolling } from '@client/hooks/usePolling';
import { getOrderStats } from '@client/api/orders';
import { listConversations, type Conversation } from '@client/api/conversations';
import { listBookings } from '@client/api/bookings';
import { useAuth } from './AuthContext';

interface LiveCounts {
  pendingOrders: number;
  pendingBookings: number;
  needsAgentCount: number;
  unreadMessages: number;
}

type AlertListener = (type: 'order' | 'booking', newCount: number, prevCount: number) => void;

interface LiveCountsContextValue extends LiveCounts {
  onAlert: (listener: AlertListener) => () => void;
  refresh: () => Promise<void>;
}

const INITIAL: LiveCounts = { pendingOrders: 0, pendingBookings: 0, needsAgentCount: 0, unreadMessages: 0 };

const LiveCountsContext = createContext<LiveCountsContextValue>({ ...INITIAL, onAlert: () => () => {}, refresh: async () => {} });

export function LiveCountsProvider({ children }: { children: React.ReactNode }) {
  const { restaurantId } = useAuth();
  const [counts, setCounts] = useState<LiveCounts>(INITIAL);
  const prevRef = useRef<LiveCounts>(INITIAL);
  const listenersRef = useRef<Set<AlertListener>>(new Set());
  const firstPollDone = useRef(false);

  const onAlert = useCallback((listener: AlertListener) => {
    listenersRef.current.add(listener);
    return () => { listenersRef.current.delete(listener); };
  }, []);

  const fetchCounts = useCallback(async () => {
    if (!restaurantId) return;
    try {
      const [statsRes, convsRes, bookingsRes] = await Promise.all([
        getOrderStats(),
        listConversations({ limit: '200' }),
        listBookings({ status: 'pending', limit: '1' }),
      ]);
      const pendingOrders = statsRes?.stats?.pendingOrders ?? 0;
      const convs: Conversation[] = convsRes?.conversations ?? [];
      const needsAgentCount = convs.filter(c => c.status === 'human').length;
      const unreadMessages = convs.reduce((sum, c) => sum + (c.unreadCount ?? 0), 0);
      const pendingBookings = bookingsRes?.total ?? 0;

      const prev = prevRef.current;

      if (firstPollDone.current) {
        if (pendingOrders > prev.pendingOrders) {
          listenersRef.current.forEach(fn => fn('order', pendingOrders, prev.pendingOrders));
        }
        if (pendingBookings > prev.pendingBookings) {
          listenersRef.current.forEach(fn => fn('booking', pendingBookings, prev.pendingBookings));
        }
      }

      const next = { pendingOrders, pendingBookings, needsAgentCount, unreadMessages };
      prevRef.current = next;
      firstPollDone.current = true;
      setCounts(next);
    } catch {
    }
  }, [restaurantId]);

  usePolling(fetchCounts, { intervalMs: 30000, enabled: !!restaurantId });

  return (
    <LiveCountsContext.Provider value={{ ...counts, onAlert, refresh: fetchCounts }}>
      {children}
    </LiveCountsContext.Provider>
  );
}

export function useLiveCounts() {
  return useContext(LiveCountsContext);
}
