import type { PresenceState } from '@chat-app/shared/supabase';
import { useEffect, useState } from 'react';

import {
  createPeerPresenceChannelName,
  getEffectivePresenceState,
  PRESENCE_HEARTBEAT_MS,
} from './presence';
import { supabase } from './supabase';

export interface PeerPresence {
  state: PresenceState;
  statusMessage: string | null;
}

let peerPresenceSubscriptionCounter = 0;

function nextPeerPresenceSubscriptionId(): string {
  peerPresenceSubscriptionCounter += 1;
  return String(peerPresenceSubscriptionCounter);
}

// Subscribe to a single peer's stored presence via Supabase realtime, then
// treat it as live only while one of their devices has checked in recently.
// Returns null until the first profile row arrives, or when userId is undefined.
export function usePeerPresence(userId: string | undefined): PeerPresence | null {
  const [profilePresence, setProfilePresence] = useState<PeerPresence | null>(null);
  const [latestDeviceSeenAt, setLatestDeviceSeenAt] = useState<string | null>(null);
  const [nowMs, setNowMs] = useState(() => Date.now());

  useEffect(() => {
    if (!userId) {
      setProfilePresence(null);
      setLatestDeviceSeenAt(null);
      return;
    }
    const peerUserId = userId;
    let cancelled = false;

    async function refreshLatestDeviceSeenAt() {
      const { data, error } = await supabase
        .from('devices')
        .select('last_seen_at')
        .eq('user_id', peerUserId)
        .order('last_seen_at', { ascending: false })
        .limit(1);
      if (cancelled) return;
      if (error) {
        console.warn('peer latest device lookup failed', error);
        return;
      }
      setLatestDeviceSeenAt(data?.[0]?.last_seen_at ?? null);
      setNowMs(Date.now());
    }

    void supabase
      .from('profiles')
      .select('presence_state, status_message')
      .eq('user_id', peerUserId)
      .maybeSingle()
      .then(({ data }) => {
        if (cancelled || !data) return;
        setProfilePresence({
          state: (data.presence_state as PresenceState | null) ?? 'offline',
          statusMessage: data.status_message ?? null,
        });
      });
    void refreshLatestDeviceSeenAt();
    const heartbeatPoll = window.setInterval(
      () => void refreshLatestDeviceSeenAt(),
      PRESENCE_HEARTBEAT_MS,
    );

    const channelName = createPeerPresenceChannelName(
      peerUserId,
      nextPeerPresenceSubscriptionId(),
    );
    const channel = supabase
      .channel(channelName)
      .on(
        'postgres_changes',
        {
          event: 'UPDATE',
          schema: 'public',
          table: 'profiles',
          filter: 'user_id=eq.' + peerUserId,
        },
        (payload: { new: Record<string, unknown> }) => {
          const nextState = payload.new['presence_state'];
          const nextMsg = payload.new['status_message'];
          setProfilePresence((prev) => {
            const state =
              typeof nextState === 'string'
                ? (nextState as PresenceState)
                : (prev?.state ?? 'offline');
            const statusMessage =
              nextMsg === null
                ? null
                : typeof nextMsg === 'string'
                  ? nextMsg
                  : (prev?.statusMessage ?? null);
            return { state, statusMessage };
          });
        },
      )
      .subscribe();

    return () => {
      cancelled = true;
      window.clearInterval(heartbeatPoll);
      void supabase.removeChannel(channel);
    };
  }, [userId]);

  if (!profilePresence) return null;

  return {
    state: getEffectivePresenceState(profilePresence.state, latestDeviceSeenAt, nowMs),
    statusMessage: profilePresence.statusMessage,
  };
}
