import { useEffect } from 'react';
import { useAtomValue } from 'jotai';
import { CallEmbed } from '../plugins/call';
import { settingsAtom } from '../state/settings';
import { useStateEvent } from './useStateEvent';
import { StateEvent } from '../../types/matrix/room';
import { buildQualityPayload, RoomQualityContent } from '../utils/callQuality';

/**
 * [P5-31] Apply the user's call quality settings (clamped by any room-level
 * cap) to the Element Call fork via the `io.lotus.set_quality` widget action.
 *
 * The fork stores the settings and re-applies them on every (re)publish and
 * reconnect, so we only need to (re)send when the payload changes or the widget
 * becomes ready — no need to poll the track lifecycle here.
 */
export function useCallQuality(embed: CallEmbed): void {
  const { callAudioBitrate, screenshareBitrate, screenshareFramerate } = useAtomValue(settingsAtom);

  const roomQualityEvent = useStateEvent(embed.room, StateEvent.LotusRoomQuality);
  const roomCaps = roomQualityEvent?.getContent<RoomQualityContent>();

  // Depend on the primitive cap values (not the event object) so re-renders
  // don't resend needlessly.
  const audioCap = roomCaps?.audio_max_kbps;
  const ssCap = roomCaps?.screenshare_max_kbps;
  const fpsCap = roomCaps?.screenshare_max_fps;

  useEffect(() => {
    const payload = buildQualityPayload(
      { callAudioBitrate, screenshareBitrate, screenshareFramerate },
      { audio_max_kbps: audioCap, screenshare_max_kbps: ssCap, screenshare_max_fps: fpsCap },
    );
    const send = (): void => embed.control.setQuality(payload);
    // Send now (settings are sticky fork-side even if tracks aren't up yet) and
    // again once the widget signals ready, in case the transport wasn't up.
    send();
    const off = embed.onReady(send);
    return off;
  }, [embed, callAudioBitrate, screenshareBitrate, screenshareFramerate, audioCap, ssCap, fpsCap]);
}
