import { useEffect, useRef, useState } from 'react';
import {
  Room,
  RoomEvent,
  RemoteParticipant,
  RemoteTrack,
  createLocalTracks,
} from 'livekit-client';
import { Button, SimpleGrid, Stack, Text, Loader, Paper, Group } from '@mantine/core';
import { VUMeter } from '@/components/VUMeter';

interface LiveKitRoomProps {
  tokenUrl: string;
  roomName: string;
  userName: string;
}

interface VideoTile {
  id: string;
  element: HTMLVideoElement;
}

export function LiveKitRoom({ tokenUrl, roomName, userName }: LiveKitRoomProps) {
  const [room, setRoom] = useState<Room | null>(null);
  const [connecting, setConnecting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [videos, setVideos] = useState<VideoTile[]>([]);
  const localVideoRef = useRef<HTMLVideoElement>(null);
  const audioAnalyzers = useRef<Record<string, AnalyserNode>>({});
  const audioContexts = useRef<Record<string, AudioContext>>({});

  function createVUMeter(stream: MediaStream, id: string) {
    const audioContext = new AudioContext();
    const source = audioContext.createMediaStreamSource(stream);
    const analyser = audioContext.createAnalyser();
    analyser.fftSize = 512;
    analyser.smoothingTimeConstant = 0.7;
    source.connect(analyser);
    audioContexts.current[id] = audioContext;
    audioAnalyzers.current[id] = analyser;
  }

  async function joinRoom() {
    try {
      setConnecting(true);
      setError(null);

      const res = await fetch(`${tokenUrl}?room=${roomName}&user=${userName}`);
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const { token } = await res.json();

      const r = new Room();
      setRoom(r);

      r.on(RoomEvent.ParticipantConnected, (p) =>
        console.log(`🟢 ${p.identity} se unió`),
      );
      r.on(RoomEvent.ParticipantDisconnected, (p) => {
        console.log(`🔴 ${p.identity} salió`);
        removeParticipantVideo(p.identity);
      });

      r.on(RoomEvent.TrackSubscribed, (track: RemoteTrack, pub, participant: RemoteParticipant) => {
        if (track.kind === 'video') {
          const videoEl = track.attach();
          videoEl.style.width = '100%';
          videoEl.style.height = '100%';
          videoEl.style.objectFit = 'cover';
          addParticipantVideo(participant.identity, videoEl);
        } else if (track.kind === 'audio') {
          const stream = new MediaStream([track.mediaStreamTrack]);
          createVUMeter(stream, participant.identity);
          track.attach();
        }
      });

      await r.connect('ws://192.168.1.131:7880', token);

      const localTracks = await createLocalTracks({ audio: true, video: true });
      for (const track of localTracks) {
        await r.localParticipant.publishTrack(track);
        if (track.kind === 'video' && localVideoRef.current) {
          const el = track.attach();
          el.muted = true;
          el.playsInline = true;
          el.autoplay = true;
          el.style.width = '100%';
          el.style.height = '100%';
          el.style.objectFit = 'cover';
          localVideoRef.current.srcObject = el.srcObject;
        } else if (track.kind === 'audio') {
          const stream = new MediaStream([track.mediaStreamTrack]);
          createVUMeter(stream, 'Tú');
        }
      }
    } catch (err: any) {
      setError(err.message || 'Error al conectar');
    } finally {
      setConnecting(false);
    }
  }

  function addParticipantVideo(id: string, element: HTMLVideoElement) {
    setVideos((prev) => (prev.find((v) => v.id === id) ? prev : [...prev, { id, element }]));
  }

  function removeParticipantVideo(id: string) {
    setVideos((prev) => prev.filter((v) => v.id !== id));
  }

  function leaveRoom() {
    room?.disconnect();
    for (const ctx of Object.values(audioContexts.current)) ctx.close();
    setRoom(null);
    setVideos([]);
  }

  useEffect(() => {
    return () => {
      room?.disconnect();
      for (const ctx of Object.values(audioContexts.current)) ctx.close();
    };
  }, [room]);

  return (
    <Stack align="center" spacing="sm" p="sm">
      <Text fw={600} size="lg">
        LiveKit Sala: {roomName}
      </Text>

      {error && <Text c="red">{error}</Text>}

      {!room && !connecting && (
        <Button onClick={joinRoom} variant="filled" color="blue">
          Unirme a la sala
        </Button>
      )}

      {connecting && <Loader />}

      {room && (
        <>
          <Group>
            <Button onClick={leaveRoom} color="red" variant="light" size="xs">
              Salir
            </Button>
          </Group>

          {/* ✅ Rejilla más densa con VU Meter */}
          <SimpleGrid
            cols={{ base: 2, sm: 3, md: 4, lg: 5 }}
            spacing="xs"
            style={{
              width: '100%',
              maxWidth: 1400,
              gridAutoRows: '140px',
            }}
          >
            {/* 📹 Video local */}
            <Paper
              shadow="sm"
              p={2}
              radius="md"
              style={{
                height: 140,
                display: 'flex',
                flexDirection: 'column',
                justifyContent: 'space-between',
              }}
            >
              <Text ta="center" size="xs" fw={500}>
                Tú ({userName})
              </Text>
              <div
                style={{
                  width: '100%',
                  height: '100%',
                  overflow: 'hidden',
                  borderRadius: 6,
                  position: 'relative',
                }}
              >
                <video
                  ref={localVideoRef}
                  autoPlay
                  muted
                  playsInline
                  style={{
                    width: '100%',
                    height: '100%',
                    objectFit: 'cover',
                  }}
                />
                <div
                  style={{
                    position: 'absolute',
                    bottom: 4,
                    left: 4,
                    right: 4,
                    height: 8,
                  }}
                >
                  <VUMeter analyser={audioAnalyzers.current['Tú']} />
                </div>
              </div>
            </Paper>

            {/* 👥 Participantes remotos */}
            {videos.map((v) => (
        <Paper
          shadow="sm"
          p={2}
          radius="md"
          style={{
            height: 180,
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            justifyContent: 'flex-start',
          }}
        >
          {/* Nombre */}
          <Text ta="center" size="xs" fw={500} mb={2}>
            {v.id}
          </Text>

          {/* Video */}
          <div
            style={{
              width: '100%',
              flexGrow: 1,
              overflow: 'hidden',
              borderRadius: 6,
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
            }}
          >
            {v.element}
          </div>

          {/* 👇 VU Meter totalmente debajo */}
          <div
            style={{
              marginTop: 6,
              width: '90%',
              height: 10,
              flexShrink: 0,
            }}
          >
            <VUMeter analyser={audioAnalyzers.current[v.id]} color="blue" />
          </div>
        </Paper>
            ))}
          </SimpleGrid>
        </>
      )}
    </Stack>
  );
}
