import { useEffect, useRef } from 'react';
import { Track } from 'livekit-client';
import type { Participant, TrackPublication, Room } from 'livekit-client';
import { useVoiceStore } from '../stores/voice.ts';

function VideoTile({ participant, isLocal, room }: { participant: Participant; isLocal: boolean; room: Room }) {
  const videoRef = useRef<HTMLVideoElement>(null);

  useEffect(() => {
    const el = videoRef.current;
    if (!el) return;

    let pub: TrackPublication | undefined;

    const attachTrack = () => {
      pub = participant.getTrackPublication(Track.Source.Camera);

      if (pub?.track && el) {
        pub.track.attach(el);
        el.muted = isLocal;
        el.play().catch(() => {});
      }
    };

    const detachTrack = () => {
      if (pub?.track && el) {
        pub.track.detach(el);
      }
    };

    attachTrack();

    // Listen for track publications changing on this participant via room events
    const handlePublished = (pub: TrackPublication) => {
      pub.track?.attach(el);
      el.play().catch(() => {});
    };
    room.on('trackPublished' as any, handlePublished);

    return () => {
      detachTrack();
      room.off('trackPublished' as any, handlePublished);
    };
  }, [participant, isLocal, room]);

  const username = participant.name || participant.identity;

  return (
    <div className="relative bg-gb-bg rounded-sm overflow-hidden border border-gb-bg-t aspect-video flex items-center justify-center">
      <video
        ref={videoRef}
        className="absolute inset-0 w-full h-full object-cover"
        autoPlay
        playsInline
      />
      <div className="absolute bottom-1 left-1 text-xxs text-gb-fg-s bg-gb-bg/70 px-1 py-0.5 rounded-sm">
        {username}{isLocal ? ' (you)' : ''}
      </div>
    </div>
  );
}

export function VideoGrid() {
  const room = useVoiceStore((s) => s._room);
  const isVideoOn = useVoiceStore((s) => s.isVideoOn);

  if (!room || !isVideoOn) return null;

  const participants: Participant[] = [
    room.localParticipant,
    ...Array.from(room.remoteParticipants.values()),
  ];

  const hasCam = participants.filter((p) => {
    const pub = p.getTrackPublication(Track.Source.Camera);
    return pub && !pub.isMuted;
  });

  if (hasCam.length === 0) return null;

  return (
    <div className="px-3 py-1.5 border-b border-gb-bg-t">
      <div className="text-xxs text-gb-fg-f mb-1">
        ── video [{hasCam.length}] ──
      </div>
      <div
        className={`grid gap-1 ${
          hasCam.length <= 2
            ? 'grid-cols-2'
            : hasCam.length <= 4
              ? 'grid-cols-2'
              : 'grid-cols-3'
        }`}
      >
        {participants.map((p) => (
          <VideoTile
            key={p.identity}
            participant={p}
            isLocal={p.identity === room.localParticipant.identity}
            room={room}
          />
        ))}
      </div>
    </div>
  );
}
