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, source }: { participant: Participant; isLocal: boolean; room: Room; source: Track.Source }) {
  const videoRef = useRef<HTMLVideoElement>(null);

  useEffect(() => {
    const el = videoRef.current;
    if (!el) return;
    let pub: TrackPublication | undefined;

    const attachTrack = () => {
      pub = participant.getTrackPublication(source);
      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();

    const handleSubscribed = (track: Track, publication: TrackPublication, trackParticipant: Participant) => {
      if (trackParticipant.identity === participant.identity && publication.source === source) {
        track.attach(el);
        el.muted = isLocal;
        el.play().catch(() => {});
      }
    };

    room.on('trackSubscribed' as any, handleSubscribed);
    return () => {
      detachTrack();
      room.off('trackSubscribed' as any, handleSubscribed);
    };
  }, [participant, isLocal, room, source]);

  const username = participant.name || participant.identity;
  const isScreen = source === Track.Source.ScreenShare;

  return (
    <div className={`relative bg-gb-bg rounded-sm overflow-hidden border ${isScreen ? 'border-gb-aqua' : 'border-gb-bg-t'} w-full h-full flex items-center justify-center`}>
      <video
        ref={videoRef}
        className={`${isScreen ? 'w-full h-full' : 'absolute inset-0 w-full h-full'} object-contain`}
        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">
        {isScreen ? '🖥 ' : ''}{username}{isLocal ? ' (you)' : ''}
      </div>
    </div>
  );
}

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

  if (!room) return null;

  const getLiveKitParticipant = (identity: string) => {
    if (identity === room.localParticipant.identity) return room.localParticipant;
    return room.remoteParticipants.get(identity);
  };

  const camParticipants = voiceParticipants.filter((p) => p.hasVideo);
  const screenParticipants = voiceParticipants.filter((p) => p.isScreenSharing);

  if (camParticipants.length === 0 && screenParticipants.length === 0) return null;

  const hasScreen = screenParticipants.length > 0;
  // ponytail: grid layout for cameras; screen share gets the remaining space
  const camCols = camParticipants.length <= 1 ? 1 : camParticipants.length <= 4 ? 2 : 3;

  return (
    <div className="flex-1 min-h-0 flex flex-col px-2 py-1 gap-1">
      {/* Screen shares */}
      {hasScreen && screenParticipants.map((vp) => {
        const p = getLiveKitParticipant(vp.identity);
        if (!p) return null;
        return (
          <div key={`screen-${p.identity}`} className="flex-1 min-h-0">
            <VideoTile
              participant={p}
              isLocal={p.identity === room.localParticipant.identity}
              room={room}
              source={Track.Source.ScreenShare}
            />
          </div>
        );
      })}

      {/* Camera grid */}
      {camParticipants.length > 0 && (
        <div
          className={`${hasScreen ? 'shrink-0 h-[25%]' : 'flex-1'} grid gap-1`}
          style={{ gridTemplateColumns: `repeat(${camCols}, 1fr)` }}
        >
          {camParticipants.map((vp) => {
            const p = getLiveKitParticipant(vp.identity);
            if (!p) return null;
            return (
              <div key={p.identity} className="min-h-0">
                <VideoTile
                  participant={p}
                  isLocal={p.identity === room.localParticipant.identity}
                  room={room}
                  source={Track.Source.Camera}
                />
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}
