import React, { useEffect, useRef, useState, useMemo, Suspense } from 'react';
import { useParams, useNavigate } from 'react-router-dom';

interface ErrorBoundaryProps {
  children: React.ReactNode;
  fallback: React.ReactNode;
}

interface ErrorBoundaryState {
  hasError: boolean;
}

class ModelErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  componentDidCatch(error: any, errorInfo: any) {
    console.error("🚨 [ModelErrorBoundary] Falha de renderização/rede no modelo:", error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return this.props.fallback;
    }
    return this.props.children;
  }
}
import { Canvas, useFrame } from '@react-three/fiber';
import { OrbitControls, Text, useGLTF } from '@react-three/drei';
import * as THREE from 'three';
import { supabase } from '@/integrations/supabase/client';
import { useModelStore } from '@/stores/useModelStore';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Checkbox } from '@/components/ui/checkbox';
import { toast } from 'sonner';
import {
  Users, MessageSquare, Mic, MicOff, Home, Send,
  ArrowRight, ChevronLeft, ChevronRight, Share2, LogOut,
  RotateCw, Award, ShieldAlert
} from 'lucide-react';

// Interfaces tipadas para evitar any
interface AvatarPreset {
  id: number;
  name: string;
  desc: string;
  color: string;
}

interface PresentationState {
  rotation: number[];
  scale: number;
  sectionEnabled: boolean;
  sectionAxis: string;
  sectionLevel: number;
  sectionInvert: boolean;
}

interface PeerData {
  username: string;
  avatarId: number;
  chairId: string;
  role: string;
  cargo: string;
  empresa: string;
  presence_ref: string;
}

// --- Configurações da Mesa de Reunião ---
const CHAIRS = [
  { id: '1', name: 'Assento 1', pos: [-1.2, 0.95, -1.45], lookAt: [0, 0.95, 0] },
  { id: '2', name: 'Assento 2', pos: [-0.4, 0.95, -1.45], lookAt: [0, 0.95, 0] },
  { id: '3', name: 'Assento 3', pos: [0.4, 0.95, -1.45], lookAt: [0, 0.95, 0] },
  { id: '4', name: 'Assento 4', pos: [1.2, 0.95, -1.45], lookAt: [0, 0.95, 0] },
  { id: '5', name: 'Assento 5', pos: [1.2, 0.95, 1.45], lookAt: [0, 0.95, 0] },
  { id: '6', name: 'Assento 6', pos: [0.4, 0.95, 1.45], lookAt: [0, 0.95, 0] },
  { id: '7', name: 'Assento 7', pos: [-0.4, 0.95, 1.45], lookAt: [0, 0.95, 0] },
  { id: '8', name: 'Assento 8', pos: [-1.2, 0.95, 1.45], lookAt: [0, 0.95, 0] },
];

const AVATAR_PRESETS: AvatarPreset[] = [
  { id: 1, name: 'Cyber', desc: 'Cabelo curto preto e óculos vermelhos', color: '#ef4444' },
  { id: 2, name: 'Classic', desc: 'Pele média com Cabelo castanho clássico', color: '#b45309' },
  { id: 3, name: 'Goldie', desc: 'Cabelo loiro longo com olhos azuis expressivos', color: '#eab308' },
  { id: 4, name: 'Sporty', desc: 'Boné azul virado para trás e sorriso aberto', color: '#3b82f6' },
  { id: 5, name: 'Ginger', desc: 'Cabelo ruivo longo ondulado e expressivo', color: '#f97316' },
  { id: 6, name: 'Sleek', desc: 'Pele parda com cabelo curto liso lateral', color: '#10b981' },
  { id: 7, name: 'Beard', desc: 'Careca estilosa com barba e bigode', color: '#78350f' },
  { id: 8, name: 'Sun', desc: 'Cabelo raspado e óculos escuros pretos', color: '#1e293b' },
  { id: 9, name: 'Synth', desc: 'Cabelo roxo ondulado moderno', color: '#a855f7' },
  { id: 10, name: 'Straw', desc: 'Chapéu de palha do campo clássico', color: '#ca8a04' },
];

const SKIN_COLORS = ['#fed7aa', '#fdba74', '#f59e0b', '#d97706', '#9a3412', '#ffedd5'];

// Classes Tailwind estáticas para evitar inline styles no list view dos avatares
const getAvatarBgClass = (avatarId: number): string => {
  const classes = [
    'bg-red-500/20 text-red-400',
    'bg-amber-800/20 text-amber-500',
    'bg-yellow-500/20 text-yellow-400',
    'bg-blue-500/20 text-blue-400',
    'bg-orange-500/20 text-orange-400',
    'bg-emerald-500/20 text-emerald-400',
    'bg-amber-900/20 text-amber-600',
    'bg-slate-700/20 text-slate-400',
    'bg-purple-500/20 text-purple-400',
    'bg-yellow-600/20 text-yellow-500'
  ];
  return classes[(avatarId - 1) % 10] || classes[0];
};

// --- Subcomponentes 3D ---

// Avatar estilo Mii (Nintendo Wii) - Versão Melhorada (Mais Feliz e Expressivo)
function MiiAvatar({ avatarId, username, isTalking, scale = 1, ...props }: { avatarId: number; username: string; isTalking?: boolean; scale?: number } & Record<string, unknown>) {
  const groupRef = useRef<THREE.Group>(null);
  
  const mii = useMemo(() => {
    const skin = SKIN_COLORS[(avatarId - 1) % SKIN_COLORS.length];
    return {
      skin,
      hairColor: avatarId === 3 ? '#eab308' : avatarId === 9 ? '#a855f7' : avatarId === 5 ? '#f97316' : '#27272a',
      hasGlasses: avatarId === 1 || avatarId === 8,
      glassesColor: avatarId === 8 ? '#18181b' : '#ef4444',
      hasCap: avatarId === 4,
      capColor: '#3b82f6',
      hasHat: avatarId === 10,
      hatColor: '#b45309',
      hairStyle: avatarId === 7 ? 'bald' : (avatarId === 9 ? 'modern' : (avatarId % 3 === 0 ? 'long' : 'short')),
      beard: avatarId === 7,
    };
  }, [avatarId]);

  useFrame((state) => {
    if (groupRef.current && props.position && Array.isArray(props.position) && props.position.length >= 2) {
      groupRef.current.position.y = (props.position[1] as number) + Math.sin(state.clock.getElapsedTime() * 2 + avatarId) * 0.012;
    }
  });

  const positionVector = useMemo(() => {
    if (props.position && Array.isArray(props.position)) {
      return new THREE.Vector3(props.position[0] as number, props.position[1] as number, props.position[2] as number);
    }
    return new THREE.Vector3(0, 0, 0);
  }, [props.position]);

  const rotationEuler = useMemo(() => {
    if (props.rotation && Array.isArray(props.rotation)) {
      return new THREE.Euler(props.rotation[0] as number, props.rotation[1] as number, props.rotation[2] as number);
    }
    return new THREE.Euler(0, 0, 0);
  }, [props.rotation]);

  return (
    <group ref={groupRef} position={positionVector} rotation={rotationEuler} scale={scale}>
      {/* Balão de Nome acima da cabeça */}
      <group position={[0, 0.28, 0]}>
        <mesh position={[0, 0, -0.001]}>
          <planeGeometry args={[0.22, 0.05]} />
          <meshBasicMaterial color="#0f172a" transparent opacity={0.7} />
        </mesh>
        <Text fontSize={0.024} color="#ffffff" anchorX="center" anchorY="middle" fontWeight="bold">
          {username}
        </Text>
      </group>

      {/* Indicador de Fala (anel pulsante) */}
      {isTalking && (
        <mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, 0.12, 0]}>
          <ringGeometry args={[0.13, 0.15, 32]} />
          <meshBasicMaterial color="#3b82f6" transparent opacity={0.6 + Math.sin(Date.now() * 0.01) * 0.3} side={THREE.DoubleSide} />
        </mesh>
      )}

      {/* CABEÇA AVATAR (Esfera ovalada de pele) */}
      <mesh position={[0, 0.1, 0]} scale={[1, 1.15, 1]}>
        <sphereGeometry args={[0.08, 32, 32]} />
        <meshStandardMaterial color={mii.skin} roughness={0.6} />
      </mesh>

      {/* CABELO MELHORADO */}
      {mii.hairStyle === 'short' && (
        <group>
          {/* Topo do cabelo */}
          <mesh position={[0, 0.15, -0.015]} scale={[1.05, 0.8, 1.05]}>
            <sphereGeometry args={[0.08, 16, 16]} />
            <meshStandardMaterial color={mii.hairColor} roughness={0.8} />
          </mesh>
          {/* Costeletas laterais */}
          <mesh position={[-0.078, 0.11, 0.02]} scale={[0.2, 0.5, 0.4]}>
            <sphereGeometry args={[0.03, 8, 8]} />
            <meshStandardMaterial color={mii.hairColor} roughness={0.8} />
          </mesh>
          <mesh position={[0.078, 0.11, 0.02]} scale={[0.2, 0.5, 0.4]}>
            <sphereGeometry args={[0.03, 8, 8]} />
            <meshStandardMaterial color={mii.hairColor} roughness={0.8} />
          </mesh>
        </group>
      )}

      {mii.hairStyle === 'long' && (
        <group>
          {/* Cabelo Superior */}
          <mesh position={[0, 0.16, -0.01]} scale={[1.05, 0.7, 1.05]}>
            <sphereGeometry args={[0.08, 16, 16]} />
            <meshStandardMaterial color={mii.hairColor} roughness={0.8} />
          </mesh>
          {/* Franja frontal */}
          <mesh position={[0, 0.16, 0.045]} scale={[1.3, 0.3, 0.4]} rotation={[0.1, 0, 0]}>
            <sphereGeometry args={[0.04, 16, 16]} />
            <meshStandardMaterial color={mii.hairColor} roughness={0.8} />
          </mesh>
          {/* Costeletas longas */}
          <mesh position={[-0.076, 0.05, 0.01]} scale={[0.3, 1.6, 0.6]}>
            <sphereGeometry args={[0.038, 16, 16]} />
            <meshStandardMaterial color={mii.hairColor} roughness={0.8} />
          </mesh>
          <mesh position={[0.076, 0.05, 0.01]} scale={[0.3, 1.6, 0.6]}>
            <sphereGeometry args={[0.038, 16, 16]} />
            <meshStandardMaterial color={mii.hairColor} roughness={0.8} />
          </mesh>
        </group>
      )}

      {mii.hairStyle === 'modern' && (
        <group>
          {/* Cabelo Superior */}
          <mesh position={[0, 0.16, -0.01]} scale={[1.05, 0.7, 1.05]}>
            <sphereGeometry args={[0.08, 16, 16]} />
            <meshStandardMaterial color={mii.hairColor} roughness={0.8} />
          </mesh>
          {/* Topete Moderno */}
          <mesh position={[0, 0.19, 0.02]} rotation={[-0.3, 0, 0]} scale={[0.8, 1.2, 0.8]}>
            <coneGeometry args={[0.04, 0.08, 4]} />
            <meshStandardMaterial color={mii.hairColor} roughness={0.8} />
          </mesh>
          {/* Costeletas */}
          <mesh position={[-0.076, 0.09, 0.01]} scale={[0.3, 1.0, 0.5]}>
            <sphereGeometry args={[0.03, 8, 8]} />
            <meshStandardMaterial color={mii.hairColor} roughness={0.8} />
          </mesh>
          <mesh position={[0.076, 0.09, 0.01]} scale={[0.3, 1.0, 0.5]}>
            <sphereGeometry args={[0.03, 8, 8]} />
            <meshStandardMaterial color={mii.hairColor} roughness={0.8} />
          </mesh>
        </group>
      )}

      {/* BONÉ */}
      {mii.hasCap && (
        <group position={[0, 0.17, 0.01]}>
          {/* Copa do Boné */}
          <mesh scale={[1.05, 0.65, 1.05]}>
            <sphereGeometry args={[0.08, 16, 16]} />
            <meshStandardMaterial color={mii.capColor} roughness={0.5} />
          </mesh>
          {/* Aba do Boné */}
          <mesh position={[0, 0, -0.08]} rotation={[0.1, 0, 0]}>
            <boxGeometry args={[0.11, 0.008, 0.08]} />
            <meshStandardMaterial color={mii.capColor} roughness={0.5} />
          </mesh>
        </group>
      )}

      {/* CHAPÉU DE PALHA */}
      {mii.hasHat && (
        <group position={[0, 0.17, 0]}>
          {/* Copa do Chapéu */}
          <mesh>
            <cylinderGeometry args={[0.055, 0.065, 0.05, 16]} />
            <meshStandardMaterial color={mii.hatColor} roughness={0.8} />
          </mesh>
          {/* Aba do Chapéu */}
          <mesh position={[0, -0.02, 0]}>
            <cylinderGeometry args={[0.12, 0.12, 0.006, 16]} />
            <meshStandardMaterial color={mii.hatColor} roughness={0.8} />
          </mesh>
        </group>
      )}

      {/* OLHOS MELHORADOS (Mais expressivos e com brilho) */}
      <group position={[-0.028, 0.11, 0.07]} rotation={[0.08, -0.15, 0]}>
        <mesh>
          <sphereGeometry args={[0.011, 16, 16]} />
          <meshBasicMaterial color="#111827" />
        </mesh>
        <mesh position={[0.004, 0.004, 0.008]}>
          <sphereGeometry args={[0.004, 8, 8]} />
          <meshBasicMaterial color="#ffffff" />
        </mesh>
      </group>
      
      <group position={[0.028, 0.11, 0.07]} rotation={[0.08, 0.15, 0]}>
        <mesh>
          <sphereGeometry args={[0.011, 16, 16]} />
          <meshBasicMaterial color="#111827" />
        </mesh>
        <mesh position={[0.004, 0.004, 0.008]}>
          <sphereGeometry args={[0.004, 8, 8]} />
          <meshBasicMaterial color="#ffffff" />
        </mesh>
      </group>

      {/* SOBRANCELHAS */}
      <mesh position={[-0.028, 0.128, 0.072]} rotation={[0.05, -0.15, 0.08]}>
        <boxGeometry args={[0.028, 0.005, 0.005]} />
        <meshBasicMaterial color="#18181b" />
      </mesh>
      <mesh position={[0.028, 0.128, 0.072]} rotation={[0.05, 0.15, -0.08]}>
        <boxGeometry args={[0.028, 0.005, 0.005]} />
        <meshBasicMaterial color="#18181b" />
      </mesh>

      {/* NARIZ */}
      <mesh position={[0, 0.09, 0.076]} scale={[1, 1.2, 1.2]}>
        <sphereGeometry args={[0.008, 8, 8]} />
        <meshStandardMaterial color={mii.skin} roughness={0.6} />
      </mesh>

      {/* BOCHECHAS ROSADAS (Deixa o avatar super amigável e feliz) */}
      <mesh position={[-0.042, 0.08, 0.071]} scale={[1, 0.6, 0.2]}>
        <sphereGeometry args={[0.01, 16, 16]} />
        <meshBasicMaterial color="#f43f5e" transparent opacity={0.5} />
      </mesh>
      <mesh position={[0.042, 0.08, 0.071]} scale={[1, 0.6, 0.2]}>
        <sphereGeometry args={[0.01, 16, 16]} />
        <meshBasicMaterial color="#f43f5e" transparent opacity={0.5} />
      </mesh>

      {/* BOCA FELIZ E SORRIDENTE (Sem aparência de triste) */}
      <mesh position={[0, 0.062, 0.073]} rotation={[0, 0, Math.PI]}>
        <torusGeometry args={[0.014, 0.003, 8, 24, Math.PI]} />
        <meshBasicMaterial color="#b91c1c" />
      </mesh>

      {/* BARBA E BIGODE */}
      {mii.beard && (
        <group>
          <mesh position={[0, 0.075, 0.075]}>
            <boxGeometry args={[0.04, 0.006, 0.005]} />
            <meshBasicMaterial color="#713f12" />
          </mesh>
          <mesh position={[0, 0.045, 0.072]} scale={[1.2, 1, 1]}>
            <sphereGeometry args={[0.015, 8, 8]} />
            <meshStandardMaterial color="#713f12" roughness={0.8} />
          </mesh>
        </group>
      )}

      {/* ÓCULOS */}
      {mii.hasGlasses && (
        <group position={[0, 0.11, 0.072]}>
          <mesh position={[-0.028, 0, 0.002]}>
            <ringGeometry args={[0.016, 0.019, 16]} />
            <meshBasicMaterial color={mii.glassesColor} />
          </mesh>
          <mesh position={[0.028, 0, 0.002]}>
            <ringGeometry args={[0.016, 0.019, 16]} />
            <meshBasicMaterial color={mii.glassesColor} />
          </mesh>
          <mesh position={[0, 0, 0.002]}>
            <boxGeometry args={[0.028, 0.004, 0.002]} />
            <meshBasicMaterial color={mii.glassesColor} />
          </mesh>
        </group>
      )}
    </group>
  );
}

// Carregador e Escalador Inteligente da Maquete Holográfica
function HologramModel({ model, presentationState }: { model: { url: string }; presentationState: PresentationState }) {
  const { scene } = useGLTF(model.url);
  const clone = useMemo(() => scene.clone(), [scene]);
  const groupRef = useRef<THREE.Group>(null);

  // Calcula escala de aproximadamente 1 metro para caber na mesa
  useEffect(() => {
    if (!groupRef.current) return;
    const box = new THREE.Box3().setFromObject(clone);
    const size = new THREE.Vector3();
    box.getSize(size);
    const maxDim = Math.max(size.x, size.y, size.z);
    
    if (maxDim > 0) {
      const targetSize = 0.95;
      const scaleFactor = targetSize / maxDim;
      groupRef.current.scale.setScalar(scaleFactor);
      const center = new THREE.Vector3();
      box.getCenter(center);
      clone.position.copy(center).multiplyScalar(-scaleFactor);
      clone.position.y += 0.02;
    }
  }, [clone]);

  // Aplica transformações de Rotação e Escala compartilhadas
  useFrame(() => {
    if (groupRef.current && presentationState) {
      const { rotation, scale } = presentationState;
      if (rotation) {
        groupRef.current.rotation.x = rotation[0];
        groupRef.current.rotation.y = rotation[1];
        groupRef.current.rotation.z = rotation[2];
      }
      if (scale) {
        const box = new THREE.Box3().setFromObject(clone);
        const size = new THREE.Vector3();
        box.getSize(size);
        const maxDim = Math.max(size.x, size.y, size.z);
        if (maxDim > 0) {
          const baseScale = 0.95 / maxDim;
          groupRef.current.scale.setScalar(baseScale * scale);
        }
      }
    }
  });

  // Aplica Planos de Corte (clippingPlanes) nos materiais
  useEffect(() => {
    if (!clone || !presentationState) return;
    const { sectionEnabled, sectionAxis, sectionLevel, sectionInvert } = presentationState;

    if (!sectionEnabled) {
      clone.traverse((obj) => {
        if (obj instanceof THREE.Mesh) {
          const mats = Array.isArray(obj.material) ? obj.material : [obj.material];
          mats.forEach((mat) => {
            if (mat) {
              mat.clippingPlanes = [];
              mat.needsUpdate = true;
            }
          });
        }
      });
      return;
    }

    const normal = new THREE.Vector3();
    if (sectionAxis === 'x') normal.set(sectionInvert ? -1 : 1, 0, 0);
    else if (sectionAxis === 'y') normal.set(0, sectionInvert ? -1 : 1, 0);
    else if (sectionAxis === 'z') normal.set(0, 0, sectionInvert ? -1 : 1);

    const plane = new THREE.Plane(normal, sectionLevel);

    clone.traverse((obj) => {
      if (obj instanceof THREE.Mesh) {
        const mats = Array.isArray(obj.material) ? obj.material : [obj.material];
        mats.forEach((mat) => {
          if (mat) {
            mat.clippingPlanes = [plane];
            mat.clipShadows = true;
            mat.needsUpdate = true;
          }
        });
      }
    });

  }, [clone, presentationState]);

  return (
    <group ref={groupRef}>
      <primitive object={clone} />
    </group>
  );
}

// Cenário da Sala de Reunião Clara
function ThreeMeetingRoomScene({ currentActiveModel, presentationState }: { currentActiveModel: { url: string; fileName: string } | null; presentationState: PresentationState }) {
  const tableGeom = useMemo(() => {
    // Geometria da mesa em U
    const shape = new THREE.Shape();
    shape.moveTo(-1.6, -1.1);
    shape.lineTo(1.6, -1.1);
    shape.quadraticCurveTo(1.9, -1.1, 1.9, -0.8);
    shape.lineTo(1.9, 0.8);
    shape.quadraticCurveTo(1.9, 1.1, 1.6, 1.1);
    shape.lineTo(-1.6, 1.1);
    shape.quadraticCurveTo(-1.9, 1.1, -1.9, 0.8);
    shape.lineTo(-1.9, -0.8);
    shape.quadraticCurveTo(-1.9, -1.1, -1.6, -1.1);

    const hole = new THREE.Path();
    hole.absellipse(0, 0, 0.9, 0.45, 0, Math.PI * 2, true);
    shape.holes.push(hole);

    return new THREE.ExtrudeGeometry(shape, { depth: 0.06, bevelEnabled: true, bevelThickness: 0.01, bevelSize: 0.01, bevelSegments: 3 });
  }, []);

  return (
    <group>
      {/* Piso Clara */}
      <mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, 0, 0]}>
        <planeGeometry args={[12, 8]} />
        <meshStandardMaterial color="#e2e8f0" roughness={0.4} metalness={0.1} />
      </mesh>
      
      {/* Tapete Central */}
      <mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, 0.001, 0]}>
        <planeGeometry args={[4.8, 3.2]} />
        <meshStandardMaterial color="#94a3b8" roughness={0.7} />
      </mesh>

      {/* Paredes Claras */}
      <mesh position={[0, 2, -4]}>
        <planeGeometry args={[12, 4]} />
        <meshStandardMaterial color="#f1f5f9" roughness={0.9} />
      </mesh>
      {/* Janelas Panorâmicas */}
      <mesh position={[-6, 2, 0]} rotation={[0, Math.PI / 2, 0]}>
        <planeGeometry args={[8, 4]} />
        <meshStandardMaterial color="#bae6fd" roughness={0.1} emissive="#bae6fd" emissiveIntensity={0.4} />
      </mesh>
      <mesh position={[6, 2, 0]} rotation={[0, -Math.PI / 2, 0]}>
        <planeGeometry args={[8, 4]} />
        <meshStandardMaterial color="#bae6fd" roughness={0.1} emissive="#bae6fd" emissiveIntensity={0.4} />
      </mesh>

      {/* Mesa Elíptica em U (Madeira Mel Carvalho Clara) */}
      <group position={[0, 0.8, 0]} rotation={[Math.PI / 2, 0, 0]}>
        <mesh geometry={tableGeom}>
          <meshStandardMaterial color="#d97706" roughness={0.2} metalness={0.1} />
        </mesh>
      </group>

      {/* Pés da mesa (Cromados) */}
      {[-1.3, 1.3].map((x) =>
        [-0.7, 0.7].map((z) => (
          <mesh key={`${x}-${z}`} position={[x, 0.4, z]}>
            <cylinderGeometry args={[0.035, 0.035, 0.8]} />
            <meshStandardMaterial color="#d4d4d8" metalness={0.9} roughness={0.1} />
          </mesh>
        ))
      )}

      {/* Projetor de Holograma (Centro da mesa) */}
      <group position={[0, 0.78, 0]}>
        <mesh rotation={[-Math.PI / 2, 0, 0]}>
          <cylinderGeometry args={[0.26, 0.28, 0.05, 32]} />
          <meshStandardMaterial color="#1e293b" metalness={0.8} roughness={0.2} />
        </mesh>
        <mesh position={[0, 0.026, 0]} rotation={[-Math.PI / 2, 0, 0]}>
          <ringGeometry args={[0, 0.22, 32]} />
          <meshBasicMaterial color="#0ea5e9" transparent opacity={0.7} />
        </mesh>
        <mesh position={[0, 0.45, 0]}>
          <cylinderGeometry args={[0.28, 0.2, 0.9, 32, 1, true]} />
          <meshBasicMaterial color="#0ea5e9" transparent opacity={0.15} side={THREE.DoubleSide} />
        </mesh>
        
        {/* Modelo 3D da Maquete Holográfica */}
        <group position={[0, 0.45, 0]}>
          <ModelErrorBoundary fallback={
            // Se falhar ao carregar o modelo (ex: blob local do host inacessível por convidados), renderiza o holograma geométrico
            <group rotation={[0, Date.now() * 0.00012, 0]}>
              <mesh position={[0, 0, 0]}>
                <octahedronGeometry args={[0.22]} />
                <meshStandardMaterial color="#f43f5e" transparent opacity={0.7} wireframe emissive="#f43f5e" emissiveIntensity={0.5} />
              </mesh>
              <mesh position={[0, -0.15, 0]}>
                <boxGeometry args={[0.3, 0.02, 0.3]} />
                <meshStandardMaterial color="#ef4444" transparent opacity={0.4} />
              </mesh>
            </group>
          }>
            <Suspense fallback={
              <mesh>
                <sphereGeometry args={[0.1, 16, 16]} />
                <meshBasicMaterial color="#00f5ff" wireframe />
              </mesh>
            }>
              {currentActiveModel ? (
                <HologramModel model={currentActiveModel} presentationState={presentationState} />
              ) : (
                // Holograma Padrão Geométrico se não houver maquete carregada
                <group rotation={[0, Date.now() * 0.00012, 0]}>
                  <mesh position={[0, 0, 0]}>
                    <octahedronGeometry args={[0.22]} />
                    <meshStandardMaterial color="#0ea5e9" transparent opacity={0.7} wireframe emissive="#0ea5e9" emissiveIntensity={0.5} />
                  </mesh>
                  <mesh position={[0, 0, 0]} rotation={[0, Math.PI / 4, 0]}>
                    <boxGeometry args={[0.25, 0.04, 0.25]} />
                    <meshStandardMaterial color="#3b82f6" transparent opacity={0.4} emissive="#3b82f6" emissiveIntensity={0.2} />
                  </mesh>
                </group>
              )}
            </Suspense>
          </ModelErrorBoundary>
        </group>
      </group>

      {/* Renderizar as Cadeiras Físicas da mesa */}
      {CHAIRS.map((chair) => (
        <group key={chair.id} position={[chair.pos[0], 0, chair.pos[2]]} rotation={[0, Math.atan2(chair.lookAt[0] - chair.pos[0], chair.lookAt[2] - chair.pos[2]), 0]}>
          {/* Base giratória metálica */}
          <mesh position={[0, 0.25, 0]}>
            <cylinderGeometry args={[0.015, 0.015, 0.5]} />
            <meshStandardMaterial color="#a1a1aa" metalness={0.9} roughness={0.1} />
          </mesh>
          {/* Pés base */}
          <mesh position={[0, 0.02, 0]} rotation={[-Math.PI / 2, 0, 0]}>
            <ringGeometry args={[0, 0.22, 4]} />
            <meshStandardMaterial color="#71717a" metalness={0.85} roughness={0.2} />
          </mesh>
          {/* Assento */}
          <mesh position={[0, 0.52, 0]}>
            <boxGeometry args={[0.28, 0.05, 0.26]} />
            <meshStandardMaterial color="#334155" roughness={0.7} />
          </mesh>
          {/* Encosto */}
          <mesh position={[0, 0.78, -0.11]} rotation={[0.08, 0, 0]}>
            <boxGeometry args={[0.26, 0.44, 0.04]} />
            <meshStandardMaterial color="#334155" roughness={0.7} />
          </mesh>
        </group>
      ))}

      {/* Iluminação Clara da Sala */}
      <hemisphereLight color="#ffffff" groundColor="#64748b" intensity={1.4} />
      <directionalLight position={[6, 12, 6]} intensity={1.8} castShadow />
      <directionalLight position={[-6, 8, -6]} intensity={0.5} />
      <pointLight position={[0, 3.5, 0]} intensity={2.0} color="#0ea5e9" distance={8} />
    </group>
  );
}

// --- Componente Principal da Tela ---

export default function MeetingRoom() {
  const { roomId } = useParams<{ roomId?: string }>();
  const navigate = useNavigate();
  const activeModel = useModelStore((s) => s.model);

  // Estados do Lobby
  const [inRoom, setInRoom] = useState(false);
  const [name, setName] = useState('');
  const [cargo, setCargo] = useState('');
  const [empresa, setEmpresa] = useState('');
  const [isPresenter, setIsPresenter] = useState(!roomId); // Se não há roomId na URL, ele é o host
  const [selectedAvatar, setSelectedAvatar] = useState(1);
  const [selectedChair, setSelectedChair] = useState('1');
  const [inputRoomId, setInputRoomId] = useState(roomId || '');

  // Estados da Sala (Conexão Supabase)
  const [peers, setPeers] = useState<Record<string, PeerData>>({});
  const [chatMessages, setChatMessages] = useState<{ id: string; sender: string; text: string; time: string }[]>([]);
  const [newMessage, setNewMessage] = useState('');
  const [isMuted, setIsMuted] = useState(false);
  const [isTalking, setIsTalking] = useState(false);
  const [activeUsersCount, setActiveUsersCount] = useState(1);
  const [roomCode, setRoomCode] = useState(roomId || '');
  const [activeTab, setActiveTab] = useState<'chat' | 'participants'>('participants');

  // Estado compartilhado da Apresentação da maquete
  const [presentationState, setPresentationState] = useState<PresentationState>({
    rotation: [0, 0, 0],
    scale: 1,
    sectionEnabled: false,
    sectionAxis: 'y',
    sectionLevel: 0.0,
    sectionInvert: false
  });

  // Carrega modificações da peça vindas do Viewer se houver
  useEffect(() => {
    const savedState = localStorage.getItem('tsxr_initial_meeting_state');
    if (savedState) {
      try {
        const parsed = JSON.parse(savedState) as PresentationState;
        setPresentationState(parsed);
        console.log('🔄 [MeetingRoom] Estado inicial carregado do Viewer:', parsed);
      } catch (err) {
        console.error('Falha ao carregar estado inicial do Viewer', err);
      }
      localStorage.removeItem('tsxr_initial_meeting_state');
    }
  }, []);

  const channelRef = useRef<ReturnType<typeof supabase.channel> | null>(null);
  const chatScrollRef = useRef<HTMLDivElement>(null);

  // Se o roomId mudar na url, atualiza o checkbox isPresenter e o inputRoomId
  useEffect(() => {
    setIsPresenter(!roomId);
    setInputRoomId(roomId || '');
  }, [roomId]);

  // Simulação de detecção de áudio
  useEffect(() => {
    if (!inRoom || isMuted) {
      setIsTalking(false);
      return;
    }
    const interval = setInterval(() => {
      setIsTalking(Math.random() > 0.7);
    }, 1500);
    return () => clearInterval(interval);
  }, [inRoom, isMuted]);

  useEffect(() => {
    if (chatScrollRef.current) {
      chatScrollRef.current.scrollTop = chatScrollRef.current.scrollHeight;
    }
  }, [chatMessages]);

  // --- ESCUTA DO LOBBY EM TEMPO REAL ---
  // Conecta ao canal antes do lobby finalizar para ler assentos e avatares ocupados na sala digitada
  useEffect(() => {
    if (!inputRoomId || inputRoomId.trim().length < 3) {
      setPeers({});
      return;
    }

    const roomIdUpper = inputRoomId.trim().toUpperCase();
    console.log(`🔌 [Lobby Watcher] Escutando sala: ${roomIdUpper}`);

    const tempChannel = supabase.channel(`meeting_room_${roomIdUpper}`, {
      config: {
        presence: { key: 'lobby_watcher_' + Math.random().toString(36).substring(3, 8) }
      }
    });

    tempChannel
      .on('presence', { event: 'sync' }, () => {
        const state = tempChannel.presenceState();
        const formattedPeers: Record<string, PeerData> = {};
        
        Object.keys(state).forEach((chairKey) => {
          // Ignora outros watchers do lobby
          if (chairKey.startsWith('lobby_watcher_')) return;
          
          const presences = state[chairKey] as unknown as PeerData[];
          if (presences && presences.length > 0) {
            formattedPeers[chairKey] = presences[0];
          }
        });
        
        setPeers(formattedPeers);
      })
      .subscribe();

    return () => {
      tempChannel.unsubscribe();
    };
  }, [inputRoomId, inRoom]);

  // Envia as atualizações de apresentação via Broadcast para a sala inteira
  const handlePresentationChange = (updatedFields: Partial<PresentationState>) => {
    if (!isPresenter || !channelRef.current) return;
    
    const newState = { ...presentationState, ...updatedFields } as PresentationState;
    setPresentationState(newState);

    channelRef.current.send({
      type: 'broadcast',
      event: 'presentation_update',
      payload: newState
    });
  };

  // Inicializa o Supabase Presence & Broadcast para conexões oficiais
  const connectToRoom = async (targetRoomId: string) => {
    if (!name.trim()) {
      toast.error('Digite seu nome primeiro');
      return;
    }
    
    // Validar se o avatar já está em uso por outra pessoa
    const avatarInUse = Object.values(peers).find((p) => p.avatarId === selectedAvatar);
    if (avatarInUse) {
      toast.error(`O avatar "${AVATAR_PRESETS[selectedAvatar - 1].name}" já está em uso por ${avatarInUse.username}. Escolha outro!`);
      return;
    }

    // Validar se a cadeira está ocupada
    if (Object.keys(peers).includes(selectedChair)) {
      toast.error('O assento selecionado já está ocupado por outro participante. Por favor, selecione outro assento.');
      return;
    }

    const finalRoomId = targetRoomId.trim().toUpperCase() || Math.random().toString(36).substring(3, 8).toUpperCase();
    setRoomCode(finalRoomId);

    // Evita o erro "cannot add presence callbacks ... after subscribe()" removendo canais antigos com o mesmo tópico
    const oldChannels = supabase.getChannels().filter(c => c.topic === `realtime:meeting_room_${finalRoomId}`);
    for (const old of oldChannels) {
      console.log(`🔌 [MeetingRoom] Removendo canal antigo ativo para evitar conflitos: ${old.topic}`);
      await supabase.removeChannel(old);
    }
    
    console.log(`🔌 [MeetingRoom] Conectando à sala: ${finalRoomId} como ${isPresenter ? 'Apresentador' : 'Convidado'}`);

    const channel = supabase.channel(`meeting_room_${finalRoomId}`, {
      config: {
        broadcast: { self: true },
        presence: { key: selectedChair },
      },
    });

    channelRef.current = channel;

    // Sincroniza participantes online
    channel
      .on('presence', { event: 'sync' }, () => {
        const state = channel.presenceState();
        const formattedPeers: Record<string, PeerData> = {};
        let count = 0;
        
        Object.keys(state).forEach((chairKey) => {
          if (chairKey.startsWith('lobby_watcher_')) return;
          const presences = state[chairKey] as unknown as PeerData[];
          if (presences && presences.length > 0) {
            formattedPeers[chairKey] = presences[0];
            count++;
          }
        });
        setPeers(formattedPeers);
        setActiveUsersCount(count);
      })
      .on('presence', { event: 'join' }, ({ key, newPresences }) => {
        if (key.startsWith('lobby_watcher_')) return;
        toast.info(`"${(newPresences[0] as unknown as PeerData)?.username}" sentou-se no assento ${key}`);
      })
      .on('presence', { event: 'leave' }, ({ key, leftPresences }) => {
        if (key.startsWith('lobby_watcher_')) return;
        toast.info(`"${(leftPresences[0] as unknown as PeerData)?.username}" liberou o assento ${key}`);
      });

    // Escuta mensagens do Chat via Broadcast
    channel.on('broadcast', { event: 'chat_msg' }, (payload) => {
      setChatMessages((prev) => [
        ...prev,
        {
          id: Math.random().toString(),
          sender: payload.payload.sender,
          text: payload.payload.text,
          time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
        },
      ]);
    });

    // Escuta atualizações de Apresentação da Maquete via Broadcast (apenas para convidados)
    channel.on('broadcast', { event: 'presentation_update' }, (payload) => {
      if (!isPresenter) {
        setPresentationState(payload.payload as PresentationState);
      }
    });

    // Inscrever no WebSocket
    channel.subscribe(async (status) => {
      if (status === 'SUBSCRIBED') {
        // Envia as informações completas para o Presence do Supabase
        await channel.track({
          username: name.substring(0, 10),
          avatarId: selectedAvatar,
          chairId: selectedChair,
          role: isPresenter ? 'presenter' : 'guest',
          cargo: cargo.trim() || 'Colaborador',
          empresa: empresa.trim() || 'SteelXR Corp',
          joinedAt: new Date().toISOString(),
        });

        // Se for o apresentador, propaga o estado inicial de apresentação (vinda do Viewer) para todos
        if (isPresenter) {
          channel.send({
            type: 'broadcast',
            event: 'presentation_update',
            payload: presentationState
          });
        }

        setInRoom(true);
        toast.success(`Entrou na sala de reunião: ${finalRoomId}`);
        navigate(`/meeting/${finalRoomId}`, { replace: true });
      } else if (status === 'CHANNEL_ERROR') {
        toast.error('Erro ao conectar ao canal de reuniões.');
      }
    });
  };

  // Enviar Mensagem de Chat
  const handleSendMessage = () => {
    if (!newMessage.trim() || !channelRef.current) return;
    channelRef.current.send({
      type: 'broadcast',
      event: 'chat_msg',
      payload: {
        sender: name.substring(0, 10),
        text: newMessage.trim(),
      },
    });
    setNewMessage('');
  };

  // Sair da Sala de Reunião
  const handleLeaveRoom = async () => {
    if (channelRef.current) {
      await supabase.removeChannel(channelRef.current);
    }
    setInRoom(false);
    setPeers({});
    setChatMessages([]);
    navigate('/');
  };

  const occupiedChairs = useMemo(() => {
    return Object.keys(peers).filter(k => !k.startsWith('lobby_watcher_'));
  }, [peers]);

  // Checar se o avatar selecionado no lobby está em uso
  const isAvatarInUse = useMemo(() => {
    return Object.values(peers).find((p) => p.avatarId === selectedAvatar);
  }, [peers, selectedAvatar]);

  const nextAvatar = () => {
    setSelectedAvatar((prev) => (prev === 10 ? 1 : prev + 1));
  };
  const prevAvatar = () => {
    setSelectedAvatar((prev) => (prev === 1 ? 10 : prev - 1));
  };

  // --- Renderização do Lobby ---

  if (!inRoom) {
    const currentAvatar = AVATAR_PRESETS[selectedAvatar - 1];
    const canJoin = name.trim().length > 0 && !isAvatarInUse && !occupiedChairs.includes(selectedChair);

    return (
      <div className="flex min-h-screen flex-col items-center justify-center bg-background grid-industrial p-6">
        <div className="absolute top-6 left-6 flex items-center gap-2">
          <Button variant="ghost" size="icon" onClick={() => navigate('/')} className="text-muted-foreground hover:text-foreground">
            <Home className="h-5 w-5" />
          </Button>
          <span className="font-mono text-xs uppercase tracking-widest text-muted-foreground">TrackSteelXR</span>
        </div>

        <div className="w-full max-w-4xl rounded-2xl border border-border bg-card/65 p-6 md:p-10 shadow-2xl backdrop-blur-md animate-in fade-in zoom-in-95 duration-200">
          <div className="mb-6 text-center">
            <h2 className="text-2xl font-bold tracking-tight text-foreground md:text-3xl">
              Lobby de <span className="text-primary">Reunião Virtual</span>
            </h2>
            <p className="mt-1 text-xs font-mono uppercase tracking-wider text-muted-foreground">
              Configure suas credenciais e escolha seu avatar
            </p>
          </div>

          <div className="grid grid-cols-1 gap-6 md:grid-cols-12">
            {/* Seletor de Avatar (Lado Esquerdo - 5 colunas) */}
            <div className="flex flex-col items-center justify-center rounded-xl border bg-muted/30 p-5 md:col-span-5 relative">
              <span className="absolute top-3 left-4 font-mono text-[9px] uppercase tracking-widest text-muted-foreground">Visual Avatar</span>
              
              {/* Enquadramento centralizado perfeito (Camera apontando e fov adequado) */}
              <div className="h-40 w-full flex items-center justify-center relative bg-slate-900/60 rounded-lg overflow-hidden border border-border">
                <Canvas camera={{ position: [0, 0.11, 0.28], fov: 42 }}>
                  <ambientLight intensity={0.8} />
                  <directionalLight position={[2, 3, 2]} intensity={1.5} />
                  <pointLight position={[0, 0.15, 0.2]} intensity={1} color={currentAvatar.color} />
                  <MiiAvatar avatarId={selectedAvatar} username={name || 'Você'} position={[0, -0.04, 0]} isTalking={true} scale={0.6} />
                </Canvas>

                {/* Aviso se o avatar estiver em uso na sala */}
                {isAvatarInUse && (
                  <div className="absolute inset-0 bg-black/75 backdrop-blur-sm flex flex-col items-center justify-center text-center p-3 animate-in fade-in duration-200">
                    <ShieldAlert className="h-7 w-7 text-destructive animate-bounce mb-1" />
                    <span className="font-mono text-[10px] font-bold text-destructive uppercase tracking-wider">Avatar em Uso</span>
                    <span className="text-[9px] text-slate-300 mt-1 max-w-xs px-2 leading-snug">
                      Este visual já está ocupado por <strong className="text-primary uppercase block truncate">{isAvatarInUse.username}</strong>
                    </span>
                  </div>
                )}

                <Button variant="ghost" size="icon" className="absolute left-2 h-8 w-8 rounded-full border bg-background/50 hover:bg-background z-10" onClick={prevAvatar}>
                  <ChevronLeft className="h-4 w-4" />
                </Button>
                <Button variant="ghost" size="icon" className="absolute right-2 h-8 w-8 rounded-full border bg-background/50 hover:bg-background z-10" onClick={nextAvatar}>
                  <ChevronRight className="h-4 w-4" />
                </Button>
              </div>

              <div className="mt-3 text-center">
                <span className="font-mono text-xs font-bold uppercase tracking-wider text-primary">
                  {currentAvatar.name}
                </span>
                <p className="text-[9px] text-muted-foreground mt-0.5">{currentAvatar.desc}</p>
              </div>

              {/* Formulário de Identificação: Nome, Cargo e Empresa agrupados sequencialmente na esquerda */}
              <div className="mt-4 w-full space-y-3">
                <div className="space-y-1">
                  <label className="font-mono text-[9px] uppercase tracking-wider text-muted-foreground block">Seu Nome (Máx 10 letras)</label>
                  <Input
                    type="text"
                    maxLength={10}
                    placeholder="Nome do usuário"
                    value={name}
                    onChange={(e) => setName(e.target.value)}
                    className="font-semibold text-center uppercase font-mono tracking-wider text-xs h-9"
                  />
                </div>
                
                <div className="space-y-1">
                  <label className="font-mono text-[9px] uppercase tracking-wider text-muted-foreground block">Cargo / Função</label>
                  <Input
                    type="text"
                    placeholder="Ex: Eng. Civil"
                    value={cargo}
                    onChange={(e) => setCargo(e.target.value)}
                    className="text-xs h-9 text-center"
                  />
                </div>
                
                <div className="space-y-1">
                  <label className="font-mono text-[9px] uppercase tracking-wider text-muted-foreground block">Empresa</label>
                  <Input
                    type="text"
                    placeholder="Ex: Steel Co."
                    value={empresa}
                    onChange={(e) => setEmpresa(e.target.value)}
                    className="text-xs h-9 text-center"
                  />
                </div>
              </div>
            </div>

            {/* Seleção do Assento, Host e Conexão (Lado Direito - 7 colunas) */}
            <div className="flex flex-col justify-between md:col-span-7 space-y-5">
              {/* Seleção do Assento (Exibe quem está ocupando em tempo real) */}
              <div className="space-y-2">
                <span className="font-mono text-[9px] uppercase tracking-wider text-muted-foreground">Selecione seu Assento na Mesa</span>
                <div className="grid grid-cols-2 sm:grid-cols-4 gap-2">
                  {CHAIRS.map((chair) => {
                    const occupier = Object.values(peers).find((p) => p.chairId === chair.id);
                    const isOccupied = !!occupier;
                    const isSelected = selectedChair === chair.id;
                    return (
                      <Button
                        key={chair.id}
                        variant={isSelected ? 'default' : 'outline'}
                        className={`h-12 flex-col p-1 gap-0.5 text-[9px] font-mono ${
                          isOccupied ? 'border-destructive/40 text-destructive bg-destructive/10 cursor-not-allowed hover:bg-destructive/10' : ''
                        }`}
                        disabled={isOccupied}
                        onClick={() => setSelectedChair(chair.id)}
                      >
                        <span className="font-semibold">{chair.name}</span>
                        <span className={`text-[8px] truncate max-w-full font-bold uppercase ${
                          isOccupied ? 'text-destructive' : isSelected ? 'text-primary-foreground' : 'text-muted-foreground'
                        }`}>
                          {isOccupied ? occupier.username : isSelected ? 'Escolhido' : 'Livre'}
                        </span>
                      </Button>
                    );
                  })}
                </div>
              </div>

              {/* Papel e Código de Conexão */}
              <div className="rounded-xl border bg-muted/20 p-4 space-y-4">
                <div className="flex items-center space-x-2">
                  <Checkbox
                    id="presenter-mode"
                    checked={isPresenter}
                    onCheckedChange={(checked) => setIsPresenter(!!checked)}
                  />
                  <label
                    htmlFor="presenter-mode"
                    className="text-xs font-mono font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-foreground cursor-pointer"
                  >
                    Entrar como Apresentador (Host) da Sala
                  </label>
                </div>

                <div className="space-y-1.5">
                  <label className="font-mono text-[9px] uppercase tracking-wider text-muted-foreground">Código da Sala (Vazio para criar nova)</label>
                  <Input
                    type="text"
                    placeholder="Ex: TS-X9F"
                    value={inputRoomId}
                    onChange={(e) => setInputRoomId(e.target.value.toUpperCase())}
                    className="font-mono tracking-widest font-bold text-center text-xs h-9"
                  />
                </div>

                <div className="flex gap-2.5 pt-1">
                  <Button variant="outline" className="flex-1 font-mono text-xs h-10" onClick={() => navigate('/')}>
                    Cancelar
                  </Button>
                  <Button 
                    className="flex-1 glow-primary font-mono text-xs h-10 gap-2" 
                    disabled={!canJoin}
                    onClick={() => connectToRoom(inputRoomId)}
                  >
                    Acessar Reunião <ArrowRight className="h-4 w-4" />
                  </Button>
                </div>
                
                {isAvatarInUse && (
                  <p className="text-[10px] text-destructive font-mono text-center">
                    * Escolha outro avatar para liberar o acesso.
                  </p>
                )}
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }

  // --- Renderização da Sala de Reunião Ativa ---

  return (
    <div className="flex h-screen overflow-hidden bg-slate-950 text-white relative animate-in fade-in duration-350">
      {/* 3D Canvas - Sala Clara */}
      <div className="flex-1 h-full relative">
        <Canvas camera={{ position: [0, 2.5, 2.8], fov: 45 }} shadows gl={{ localClippingEnabled: true }}>
          <ThreeMeetingRoomScene currentActiveModel={activeModel} presentationState={presentationState} />
          
          {/* Renderizar avatares de TODOS na sala */}
          {Object.keys(peers).map((chairKey) => {
            const peer = peers[chairKey];
            const chairConf = CHAIRS.find((c) => c.id === peer.chairId);
            if (!chairConf) return null;
            
            const isLocalUser = peer.chairId === selectedChair;

            return (
              <MiiAvatar
                key={peer.presence_ref}
                avatarId={peer.avatarId}
                username={isLocalUser ? `${peer.username} (Você)` : peer.username}
                position={chairConf.pos}
                isTalking={isLocalUser ? isTalking : (isTalking && Math.random() > 0.5)}
                scale={1.2}
              />
            );
          })}

          <OrbitControls
            makeDefault
            enableDamping
            dampingFactor={0.05}
            minDistance={0.5}
            maxDistance={8}
            maxPolarAngle={Math.PI / 2 - 0.05}
            target={[0, 0.95, 0]}
          />
        </Canvas>

        {/* Painel do Apresentador (Controles de Manipulação Sincronizados) */}
        {isPresenter && (
          <div className="absolute left-4 bottom-16 w-80 rounded-xl border border-primary/30 bg-slate-900/95 p-4 shadow-2xl backdrop-blur z-20 space-y-4 pointer-events-auto">
            <div className="flex items-center justify-between border-b border-slate-800 pb-2">
              <span className="font-mono text-xs font-bold text-primary flex items-center gap-1.5">
                <Award className="h-4 w-4 animate-pulse" /> Painel do Apresentador
              </span>
              <span className="font-mono text-[8px] bg-emerald-500/25 text-emerald-400 px-1.5 py-0.5 rounded uppercase font-semibold">Sincronizado</span>
            </div>

            {/* Rotação Y */}
            <div className="space-y-1">
              <div className="flex justify-between text-[10px] font-mono text-muted-foreground">
                <span>Giro da Peça (Horizontal)</span>
                <span>{Math.round((presentationState.rotation[1] * 180) / Math.PI)}°</span>
              </div>
              <input
                type="range"
                min={-Math.PI}
                max={Math.PI}
                step={0.05}
                title="Giro Horizontal"
                value={presentationState.rotation[1]}
                onChange={(e) => handlePresentationChange({ rotation: [0, parseFloat(e.target.value), 0] })}
                className="w-full h-1 bg-slate-800 rounded-lg appearance-none cursor-pointer accent-primary"
              />
            </div>

            {/* Escala */}
            <div className="space-y-1">
              <div className="flex justify-between text-[10px] font-mono text-muted-foreground">
                <span>Escala (Zoom da Peça)</span>
                <span>{presentationState.scale.toFixed(1)}x</span>
              </div>
              <input
                type="range"
                min={0.3}
                max={3.0}
                step={0.1}
                title="Zoom da Peça"
                value={presentationState.scale}
                onChange={(e) => handlePresentationChange({ scale: parseFloat(e.target.value) })}
                className="w-full h-1 bg-slate-800 rounded-lg appearance-none cursor-pointer accent-primary"
              />
            </div>

            {/* Plano de Corte */}
            <div className="space-y-2 pt-1 border-t border-slate-800">
              <div className="flex items-center justify-between">
                <span className="font-mono text-[10px] text-muted-foreground">Corte de Seção (Clipping)</span>
                <input
                  type="checkbox"
                  id="section-cuts-enable"
                  title="Habilitar Plano de Corte"
                  checked={presentationState.sectionEnabled}
                  onChange={(e) => handlePresentationChange({ sectionEnabled: e.target.checked })}
                  className="rounded border-slate-800 bg-slate-950 accent-primary cursor-pointer h-3.5 w-3.5"
                />
              </div>

              {presentationState.sectionEnabled && (
                <div className="space-y-3 animate-in fade-in slide-in-from-bottom-2 duration-150">
                  {/* Seletor Eixo */}
                  <div className="flex gap-2">
                    {['x', 'y', 'z'].map((ax) => (
                      <Button
                        key={ax}
                        size="sm"
                        variant={presentationState.sectionAxis === ax ? 'default' : 'outline'}
                        className="flex-1 h-7 text-[9px] font-mono uppercase"
                        onClick={() => handlePresentationChange({ sectionAxis: ax })}
                      >
                        Eixo {ax}
                      </Button>
                    ))}
                  </div>

                  {/* Slider de Nível */}
                  <div className="space-y-1">
                    <div className="flex justify-between text-[9px] font-mono text-muted-foreground">
                      <span>Posição do Corte</span>
                      <span>{(presentationState.sectionLevel * 100).toFixed(0)}%</span>
                    </div>
                    <input
                      type="range"
                      min={-0.5}
                      max={0.5}
                      step={0.01}
                      title="Nível de Corte"
                      value={presentationState.sectionLevel}
                      onChange={(e) => handlePresentationChange({ sectionLevel: parseFloat(e.target.value) })}
                      className="w-full h-1 bg-slate-800 rounded-lg appearance-none cursor-pointer accent-primary"
                    />
                  </div>

                  {/* Inverter Corte */}
                  <div className="flex items-center justify-between">
                    <label htmlFor="invert-section" className="text-[9px] font-mono text-muted-foreground cursor-pointer">
                      Inverter Direção do Corte
                    </label>
                    <input
                      type="checkbox"
                      id="invert-section"
                      title="Inverter Plano de Corte"
                      checked={presentationState.sectionInvert}
                      onChange={(e) => handlePresentationChange({ sectionInvert: e.target.checked })}
                      className="rounded border-slate-800 bg-slate-950 accent-primary cursor-pointer h-3 w-3"
                    />
                  </div>
                </div>
              )}
            </div>

            {/* Botão de Reset */}
            <Button
              variant="outline"
              size="sm"
              className="w-full h-8 font-mono text-[9px] gap-1.5"
              onClick={() => handlePresentationChange({
                rotation: [0, 0, 0],
                scale: 1,
                sectionEnabled: false,
                sectionAxis: 'y',
                sectionLevel: 0.0,
                sectionInvert: false
              })}
            >
              <RotateCw className="h-3 w-3" /> Resetar Apresentação
            </Button>
          </div>
        )}

        {/* HUD Superior */}
        <div className="absolute top-4 left-4 right-4 pointer-events-none flex justify-between items-start z-10">
          <div className="pointer-events-auto flex items-center gap-2 rounded-lg border border-border bg-slate-900/90 backdrop-blur-md px-3.5 py-2 shadow-2xl">
            <Users className="h-4 w-4 text-primary" />
            <div className="flex flex-col">
              <span className="font-mono text-[9px] text-muted-foreground uppercase">Reunião Conectada</span>
              <span className="font-mono text-xs font-semibold text-foreground">
                Online: {activeUsersCount}/8
              </span>
            </div>
          </div>

          <div className="pointer-events-auto flex items-center gap-3">
            {/* Código da sala */}
            <div className="flex items-center gap-1.5 rounded-lg border border-border bg-slate-900/90 backdrop-blur-md px-3 py-1.5 shadow-2xl">
              <span className="font-mono text-[10px] text-muted-foreground">CÓDIGO:</span>
              <span className="font-mono text-xs font-bold text-primary tracking-widest">{roomCode}</span>
              <Button
                variant="ghost"
                size="icon"
                className="h-5 w-5 text-muted-foreground hover:text-foreground"
                onClick={() => {
                  navigator.clipboard.writeText(window.location.href);
                  toast.success('Link de convite copiado!');
                }}
                title="Copiar link do convite"
              >
                <Share2 className="h-3 w-3" />
              </Button>
            </div>

            {/* Sair */}
            <Button variant="destructive" size="sm" className="font-mono text-[10px] gap-1.5 h-8 px-3" onClick={handleLeaveRoom}>
              <LogOut className="h-3.5 w-3.5" /> Sair
            </Button>
          </div>
        </div>

        {/* HUD Inferior - Controles de Áudio */}
        <div className="absolute bottom-4 left-4 pointer-events-none z-10 flex gap-2">
          <Button
            variant={isMuted ? 'destructive' : 'default'}
            size="icon"
            className="pointer-events-auto h-10 w-10 rounded-xl shadow-2xl border"
            onClick={() => setIsMuted(!isMuted)}
            title={isMuted ? 'Ativar microfone' : 'Mutar microfone'}
          >
            {isMuted ? <MicOff className="h-4.5 w-4.5" /> : <Mic className="h-4.5 w-4.5" />}
          </Button>

          <div className="pointer-events-auto rounded-xl border bg-slate-900/90 backdrop-blur-md px-4 py-2 flex flex-col justify-center shadow-2xl">
            <span className="font-mono text-[8px] text-muted-foreground uppercase">
              {isPresenter ? 'Apresentação Ativa' : 'Observador'}
            </span>
            <span className="text-[10px] text-foreground font-mono">
              {isPresenter 
                ? 'Você está transmitindo os cortes e rotações da maquete.' 
                : 'Aguarde as rotações e planos de corte efetuados pelo Host.'}
            </span>
          </div>
        </div>
      </div>

      {/* Painel Lateral Direito (Abas Chat / Participantes) */}
      <div className="w-80 border-l border-slate-800 bg-slate-900/95 flex flex-col h-full z-10 shadow-2xl">
        {/* Seletor de Abas */}
        <div className="flex border-b border-slate-800 bg-slate-950/40">
          <Button
            variant="ghost"
            className={`flex-1 rounded-none border-b-2 font-mono text-[10px] uppercase h-12 gap-1.5 ${
              activeTab === 'participants' ? 'border-primary text-primary bg-slate-900/40' : 'border-transparent text-muted-foreground'
            }`}
            onClick={() => setActiveTab('participants')}
          >
            <Users className="h-3.5 w-3.5" /> Membros ({activeUsersCount})
          </Button>
          <Button
            variant="ghost"
            className={`flex-1 rounded-none border-b-2 font-mono text-[10px] uppercase h-12 gap-1.5 ${
              activeTab === 'chat' ? 'border-primary text-primary bg-slate-900/40' : 'border-transparent text-muted-foreground'
            }`}
            onClick={() => setActiveTab('chat')}
          >
            <MessageSquare className="h-3.5 w-3.5" /> Chat
          </Button>
        </div>

        {/* ABA PARTICIPANTES */}
        {activeTab === 'participants' && (
          <div className="flex-1 overflow-y-auto p-4 space-y-3 scrollbar-thin">
            <span className="font-mono text-[9px] text-muted-foreground uppercase tracking-widest block mb-2">Quem está na sala</span>
            
            <div className="space-y-2.5">
              {Object.keys(peers).map((chairKey) => {
                const peer = peers[chairKey];
                const isHost = peer.role === 'presenter';
                const isMe = peer.chairId === selectedChair;

                return (
                  <div key={peer.presence_ref} className="rounded-lg border border-slate-800 bg-slate-950/40 p-3 flex items-start gap-3 relative overflow-hidden">
                    {/* Indicador da cor do avatar do Mii via classe estática Tailwind */}
                    <div className={`h-8 w-8 rounded-full border border-slate-800 flex items-center justify-center font-bold text-xs ${getAvatarBgClass(peer.avatarId)}`}>
                      {peer.username.substring(0, 2).toUpperCase()}
                    </div>
                    
                    {/* Detalhes do Usuário */}
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-1.5">
                        <span className="font-mono text-xs font-bold text-slate-100 truncate block">
                          {peer.username} {isMe && '(Você)'}
                        </span>
                        
                        {isHost && (
                          <span className="text-[8px] font-mono bg-primary/20 text-primary px-1.5 py-0.5 rounded uppercase font-semibold">
                            Host
                          </span>
                        )}
                      </div>

                      {/* Cargo e Empresa */}
                      <span className="font-mono text-[9.5px] text-muted-foreground block truncate mt-0.5 uppercase">
                        💼 {peer.cargo}
                      </span>
                      <span className="font-mono text-[9px] text-primary/75 block truncate uppercase">
                        🏢 {peer.empresa}
                      </span>
                    </div>

                    <div className="absolute top-2 right-2.5 font-mono text-[8px] text-slate-600">
                      Chair {peer.chairId}
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        )}

        {/* ABA CHAT */}
        {activeTab === 'chat' && (
          <>
            <div ref={chatScrollRef} className="flex-1 overflow-y-auto p-4 space-y-3 scrollbar-thin">
              {chatMessages.length === 0 ? (
                <div className="h-full flex flex-col items-center justify-center text-slate-500 text-center px-4 space-y-2">
                  <MessageSquare className="h-8 w-8 opacity-30 text-primary" />
                  <p className="text-[10px] font-mono leading-relaxed">
                    Nenhuma mensagem enviada. Seja o primeiro a digitar no chat da reunião!
                  </p>
                </div>
              ) : (
                chatMessages.map((msg) => (
                  <div key={msg.id} className="space-y-0.5">
                    <div className="flex items-baseline justify-between">
                      <span className="font-mono text-[10px] font-bold text-primary uppercase">{msg.sender}</span>
                      <span className="text-[8px] text-slate-500 font-mono">{msg.time}</span>
                    </div>
                    <p className="text-xs bg-slate-800/60 border border-slate-700/30 rounded-lg p-2 leading-relaxed text-slate-300">
                      {msg.text}
                    </p>
                  </div>
                ))
              )}
            </div>

            {/* Input do Chat */}
            <div className="p-3 border-t border-slate-800 bg-slate-900 flex gap-2">
              <Input
                type="text"
                placeholder="Digite sua mensagem..."
                value={newMessage}
                onChange={(e) => setNewMessage(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === 'Enter') handleSendMessage();
                }}
                className="flex-1 text-xs border-slate-800 bg-slate-950/65"
              />
              <Button variant="default" size="icon" className="h-9 w-9 bg-primary" onClick={handleSendMessage}>
                <Send className="h-3.5 w-3.5" />
              </Button>
            </div>
          </>
        )}
      </div>
    </div>
  );
}
