import { useEffect, useEffectEvent, useRef } from 'react';
import beepSound from '../../assets/sounds/beep.wav';
import type { Network, Particle, StreamProperties } from '@/api/types';
import { apiClient } from '@/api/client';
import { useAuthStore } from '@/stores/auth-store';
import { useAutoplayStore } from '@/stores/autoplay-store';
import { resolveHumanDisplay } from '@/lib/humans';
import { logError } from '@/lib/errors';
import { platform } from '@/lib/platform';

/**
 * Triggers autoplay when a stream's latest child changes to a new media particle.
 * Plays a beep sound for new text particles from other users.
 * Sends autoplay data to the separate autoplay window via IPC.
 */
export function useStreamAutoplay(
  latestChild: Particle | null,
  streamParticle: Particle & { type: 'stream'; properties: StreamProperties },
  networkId: string,
  network: Network | undefined,
) {
  const userId = useAuthStore((s) => s.user?.id) ?? '';
  const settledIdRef = useRef<string | undefined>(undefined);

  // The autoplay action reads the latest userId/network/stream/networkId at the
  // moment a new child settles, without making any of them a reactive trigger —
  // the only thing that should fire this is a change in the latest child's id.
  const onNewLatestChild = useEffectEvent((child: Particle) => {
    if (child.created_by_human_id === userId) return;

    if (useAutoplayStore.getState().muted) return;

    if (child.type === 'text') {
      // Browser autoplay policy can block this before user interaction; that's
      // fine — the beep is a nice-to-have, not a critical signal.
      new Audio(beepSound)
        .play()
        .catch((err) => logError(err, { scope: 'autoplay.beep' }));
      return;
    }

    if (child.type !== 'media') return;

    const { displayName, initials } = resolveHumanDisplay(
      child.created_by_human_id,
      network?.humans,
    );

    apiClient
      .getParticleDownloadUrl(child.properties.object_id)
      .then((downloadUrl) => {
        platform.autoplay.play({
          particleId: child.id,
          streamId: streamParticle.id,
          networkId,
          downloadUrl,
          mimeType: child.properties.mime_type,
          durationMs: child.properties.duration_ms,
          senderName: displayName,
          senderInitials: initials,
        });
      })
      .catch((err) =>
        logError(err, { scope: 'autoplay.fetchUrl', particleId: child.id }),
      );
  });

  useEffect(() => {
    if (!latestChild) return;

    // First real value: record as baseline, don't autoplay
    if (settledIdRef.current === undefined) {
      settledIdRef.current = latestChild.id;
      return;
    }

    if (latestChild.id === settledIdRef.current) return;
    settledIdRef.current = latestChild.id;

    onNewLatestChild(latestChild);
  }, [latestChild]);
}
