import { type Friendship, listFriendships } from '@chat-app/shared/friends';
import { useCallback, useEffect, useState } from 'react';

import { supabase } from './supabase';

interface FriendshipsState {
  friendships: Friendship[];
  loading: boolean;
  error: string | null;
}

// Subscribes to the `friendships` realtime channel and re-pulls the typed
// list whenever an INSERT/UPDATE/DELETE touches one of the caller's rows.
export function useFriendships(userId: string | undefined): FriendshipsState & {
  refresh: () => Promise<void>;
} {
  const [state, setState] = useState<FriendshipsState>({
    friendships: [],
    loading: true,
    error: null,
  });

  const refresh = useCallback(async () => {
    try {
      const items = await listFriendships(supabase);
      setState({ friendships: items, loading: false, error: null });
    } catch (err: unknown) {
      setState((prev) => ({
        ...prev,
        loading: false,
        error: err instanceof Error ? err.message : 'failed to load friendships',
      }));
    }
  }, []);

  useEffect(() => {
    if (!userId) return;
    void refresh();

    const channel = supabase
      .channel('friendships:' + userId)
      .on('postgres_changes', { event: '*', schema: 'public', table: 'friendships' }, () => {
        void refresh();
      })
      .subscribe();

    // Windows WebView2 throttles background sockets — refresh on wake.
    // Throttled + visibility-only so a normal click into the window does not
    // re-fetch on every focus.
    let lastAwakeRefresh = 0;
    const AWAKE_THROTTLE_MS = 30_000;
    const onAwake = () => {
      if (document.visibilityState !== 'visible') return;
      const now = Date.now();
      if (now - lastAwakeRefresh < AWAKE_THROTTLE_MS) return;
      lastAwakeRefresh = now;
      void refresh();
      try {
        channel.subscribe();
      } catch {
        /* already live */
      }
    };
    document.addEventListener('visibilitychange', onAwake);
    window.addEventListener('online', onAwake);

    return () => {
      document.removeEventListener('visibilitychange', onAwake);
      window.removeEventListener('online', onAwake);
      void supabase.removeChannel(channel);
    };
  }, [userId, refresh]);

  return { ...state, refresh };
}
