/* eslint-disable no-console */
import { useCallback, useEffect, useState } from 'react';
import { MatrixEvent, Room, RoomStateEvent } from 'matrix-js-sdk';
import { useMatrixClient } from '../../hooks/useMatrixClient';

/** The Matrix state event type for call membership (MSC3401) */
const CALL_MEMBER_EVENT_TYPE = 'org.matrix.msc3401.call.member';

/** Represents an active call member in a room */
export interface CallMember {
  userId: string;
  deviceId: string;
  sessionId: string;
  expiresTs: number;
}

/**
 * Extracts active call members from a room's state events
 * @param room - The Matrix room to check
 * @returns Array of active call members
 */
export function getActiveCallMembers(room: Room): CallMember[] {
  const members: CallMember[] = [];
  const now = Date.now();

  try {
    const stateEvents = room.currentState.getStateEvents(CALL_MEMBER_EVENT_TYPE);
    
    stateEvents.forEach((event) => {
      const content = event.getContent();
      const userId = event.getStateKey();
      
      if (!userId || !content['m.calls']) return;

      const calls = content['m.calls'];
      if (!Array.isArray(calls)) return;

      calls.forEach((call) => {
        const devices = call['m.devices'];
        if (!Array.isArray(devices)) return;

        devices.forEach((device) => {
          const expiresTs = device.expires_ts || 0;
          
          // Check if the call membership is still valid (not expired)
          if (expiresTs > now) {
            members.push({
              userId,
              deviceId: device.device_id,
              sessionId: device.session_id,
              expiresTs,
            });
          }
        });
      });
    });
  } catch (e) {
    console.error('Error reading call member events:', e);
  }

  return members;
}

/**
 * Hook to get the list of users currently in a call in a room
 * @param roomId - The Matrix room ID to monitor
 * @returns Object with call members and whether a call is active
 */
export function useRoomCallMembers(roomId: string) {
  const mx = useMatrixClient();
  const [callMembers, setCallMembers] = useState<CallMember[]>([]);

  const updateCallMembers = useCallback(() => {
    const room = mx.getRoom(roomId);
    if (!room) {
      setCallMembers([]);
      return;
    }

    const members = getActiveCallMembers(room);
    setCallMembers(members);
  }, [mx, roomId]);

  useEffect(() => {
    updateCallMembers();

    // Listen for state event changes
    const handleStateEvent = (event: MatrixEvent) => {
      if (event.getRoomId() === roomId && event.getType() === CALL_MEMBER_EVENT_TYPE) {
        updateCallMembers();
      }
    };

    mx.on(RoomStateEvent.Events, handleStateEvent);

    // Also refresh periodically to handle expired memberships
    const interval = setInterval(updateCallMembers, 30000);

    return () => {
      mx.off(RoomStateEvent.Events, handleStateEvent);
      clearInterval(interval);
    };
  }, [mx, roomId, updateCallMembers]);

  const isCallActive = callMembers.length > 0;
  const myUserId = mx.getUserId();
  const othersInCall = callMembers.filter((m) => m.userId !== myUserId);

  return {
    callMembers,
    isCallActive,
    othersInCall,
    callMemberCount: callMembers.length,
  };
}
