<script lang="ts">
	import { onMount, onDestroy } from 'svelte';
	import { browser } from '$app/environment';
	import { useQuery, useConvexClient } from 'convex-svelte';
	import { api } from '@sgse-app/backend/convex/_generated/api';
	import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
	import { X, GripVertical, GripHorizontal } from 'lucide-svelte';
	import type {
		JitsiConnection,
		JitsiConference,
		JitsiTrack,
		JitsiMeetJSLib,
		JitsiConnectionOptions,
		WindowWithBlobBuilder
	} from '$lib/types/jitsi';
	
	// Importação dinâmica do Jitsi apenas no cliente
	let JitsiMeetJS: JitsiMeetJSLib | null = $state(null);
	
	import CallControls from './CallControls.svelte';
	import CallSettings from './CallSettings.svelte';
	import HostControls from './HostControls.svelte';
	import RecordingIndicator from './RecordingIndicator.svelte';
	import ErrorModal from '../ErrorModal.svelte';
	
	import {
		callState,
		toggleAudio,
		toggleVideo,
		iniciarGravacao as iniciarGravacaoStore,
		pararGravacao as pararGravacaoStore,
		atualizarDuracao,
		atualizarStatusConexao,
		atualizarParticipantes,
		setAudioHabilitado,
		setVideoHabilitado,
		atualizarDispositivos,
		setJitsiApi,
		setStreamLocal,
		finalizarChamada as finalizarChamadaStore,
		inicializarChamada
	} from '$lib/stores/callStore';
	
	import { obterConfiguracaoJitsi, obterHostEPorta } from '$lib/utils/jitsi';
	import { traduzirErro } from '$lib/utils/erroHelpers';
	import { GravadorMedia, gerarNomeArquivo, salvarGravacao } from '$lib/utils/mediaRecorder';
	import {
		criarDragHandler,
		criarResizeHandler,
		salvarPosicaoJanela,
		restaurarPosicaoJanela,
		obterPosicaoInicial
	} from '$lib/utils/floatingWindow';
	
	import { get } from 'svelte/store';

	interface Props {
		chamadaId: Id<'chamadas'>;
		conversaId: Id<'conversas'>;
		tipo: 'audio' | 'video';
		roomName: string;
		ehAnfitriao: boolean;
		onClose: () => void;
	}

	let {
		chamadaId,
		conversaId,
		tipo,
		roomName,
		ehAnfitriao,
		onClose
	}: Props = $props();

	const client = useConvexClient();

	// Estados
	let janelaElement: HTMLDivElement | null = $state(null);
	let dragHandle: HTMLDivElement | null = $state(null);
	let resizeHandles: HTMLDivElement[] = $state([]);
	let videoContainer: HTMLDivElement | null = $state(null);
	let localVideo: HTMLVideoElement | null = $state(null);
	let showSettings = $state(false);
	let duracaoTimer: ReturnType<typeof setInterval> | null = $state(null);
	let gravador: GravadorMedia | null = $state(null);
	
	let jitsiConnection: JitsiConnection | null = $state(null);
	let jitsiConference: JitsiConference | null = $state(null);
	let localTracks: JitsiTrack[] = $state([]);

	// Estados de erro
	let showErrorModal = $state(false);
	let errorTitle = $state('Erro na Chamada');
	let errorMessage = $state('');
	let errorDetails = $state<string | undefined>(undefined);

	// Estados de conexão e qualidade
	let qualidadeConexao = $state<'excelente' | 'boa' | 'regular' | 'ruim' | 'desconhecida'>('desconhecida');
	let tentativasReconexao = $state(0);
	const MAX_TENTATIVAS_RECONEXAO = 3;
	let reconectando = $state(false);

	// Queries
	const chamadaQuery = useQuery(api.chamadas.obterChamada, { chamadaId });
	const chamada = $derived(chamadaQuery?.data);
	const meuPerfil = useQuery(api.auth.getCurrentUser, {});
	const configJitsiBackend = useQuery(api.configuracaoJitsi.obterConfigJitsi, {});

	// Estado derivado do store
	const estadoChamada = $derived(get(callState));

	// Configuração Jitsi (busca do backend primeiro, depois fallback para env vars)
	const configJitsi = $derived.by(() => obterConfiguracaoJitsi(configJitsiBackend?.data || null));

	// Handler de erro melhorado
	function handleError(message: string, details?: string, podeReconectar: boolean = false): void {
		const erroTraduzido = traduzirErro(new Error(message));
		errorTitle = erroTraduzido.titulo;
		errorMessage = erroTraduzido.mensagem;
		
		// Adicionar sugestões de solução baseadas no tipo de erro
		let sugestoes = '';
		if (message.includes('conectar') || message.includes('servidor')) {
			sugestoes = '\n\nSugestões:\n• Verifique sua conexão com a internet\n• Verifique se o servidor Jitsi está acessível\n• Tente recarregar a página';
		} else if (message.includes('permissão') || message.includes('microfone') || message.includes('câmera')) {
			sugestoes = '\n\nSugestões:\n• Verifique as permissões do navegador para microfone e câmera\n• Certifique-se de que nenhum outro aplicativo está usando os dispositivos\n• Tente recarregar a página e permitir novamente';
		} else if (message.includes('certificado') || message.includes('SSL')) {
			sugestoes = '\n\nSugestões:\n• Se estiver em desenvolvimento local, aceite o certificado autoassinado\n• Verifique as configurações de segurança do navegador';
		}

		errorDetails = (details || erroTraduzido.instrucoes) + sugestoes;
		
		// Se pode reconectar e ainda há tentativas
		if (podeReconectar && tentativasReconexao < MAX_TENTATIVAS_RECONEXAO) {
			errorDetails += `\n\nTentando reconectar automaticamente... (${tentativasReconexao + 1}/${MAX_TENTATIVAS_RECONEXAO})`;
		}
		
		showErrorModal = true;
		console.error(message, details);
	}

	// Garantir que BlobBuilder está disponível antes de importar lib-jitsi-meet
	function garantirBlobBuilderPolyfill(): void {
		if (!browser) return;
		
		const windowWithBlobBuilder = window as WindowWithBlobBuilder;
		
		// Verificar se já existe
		if (
			typeof windowWithBlobBuilder.BlobBuilder !== 'undefined' ||
			typeof windowWithBlobBuilder.webkitBlobBuilder !== 'undefined' ||
			typeof windowWithBlobBuilder.MozBlobBuilder !== 'undefined'
		) {
			return; // Já está disponível
		}
		
		// Criar polyfill inline se não estiver disponível
		console.log('🔧 Criando polyfill BlobBuilder inline...');
		
		function BlobBuilderPolyfill() {
			if (!(this instanceof BlobBuilderPolyfill)) {
				return new BlobBuilderPolyfill();
			}
			this.parts = [];
		}
		
		BlobBuilderPolyfill.prototype.append = function(data: Blob | string) {
			if (data instanceof Blob) {
				this.parts.push(data);
			} else if (typeof data === 'string') {
				this.parts.push(data);
			} else {
				this.parts.push(new Blob([data]));
			}
		};
		
		BlobBuilderPolyfill.prototype.getBlob = function(contentType?: string) {
			return new Blob(this.parts, contentType ? { type: contentType } : undefined);
		};
		
		// Aplicar em todos os locais possíveis
		(window as unknown as Record<string, unknown>).BlobBuilder = BlobBuilderPolyfill;
		(window as unknown as Record<string, unknown>).WebKitBlobBuilder = BlobBuilderPolyfill;
		(window as unknown as Record<string, unknown>).MozBlobBuilder = BlobBuilderPolyfill;
		(window as unknown as Record<string, unknown>).MSBlobBuilder = BlobBuilderPolyfill;
		
		if (typeof globalThis !== 'undefined') {
			(globalThis as unknown as Record<string, unknown>).BlobBuilder = BlobBuilderPolyfill;
			(globalThis as unknown as Record<string, unknown>).WebKitBlobBuilder = BlobBuilderPolyfill;
			(globalThis as unknown as Record<string, unknown>).MozBlobBuilder = BlobBuilderPolyfill;
		}
		
		console.log('✅ Polyfill BlobBuilder aplicado inline');
	}

	// Carregar Jitsi dinamicamente
	async function carregarJitsi(): Promise<void> {
		if (!browser || JitsiMeetJS) return;
		
		try {
			console.log('🔄 Tentando carregar lib-jitsi-meet...');
			
			// Garantir que BlobBuilder está disponível ANTES de importar
			garantirBlobBuilderPolyfill();
			
			// Tentar carregar o módulo lib-jitsi-meet dinamicamente
			// Usar import dinâmico para evitar problemas de SSR e permitir carregamento apenas no browser
			let module;
			try {
				module = await import('lib-jitsi-meet');
			} catch (importError) {
				const importErrorMessage = importError instanceof Error ? importError.message : String(importError);
				console.error('❌ Erro ao importar lib-jitsi-meet:', importError);
				
				// Verificar se é um erro de módulo não encontrado
				if (importErrorMessage.includes('Failed to fetch') || 
				    importErrorMessage.includes('Cannot find module') ||
				    importErrorMessage.includes('Failed to resolve') ||
				    importErrorMessage.includes('Dynamic import')) {
					throw new Error(
						'A biblioteca Jitsi não pôde ser carregada. ' +
						'Verifique se o pacote "lib-jitsi-meet" está instalado corretamente. ' +
						'Se o problema persistir, tente limpar o cache do navegador e recarregar a página.'
					);
				}
				throw importError;
			}
			
			console.log('📦 Módulo carregado, verificando exportações...', {
				hasDefault: !!module.default,
				hasJitsiMeetJS: !!module.JitsiMeetJS,
				keys: Object.keys(module)
			});
			
			// Tentar múltiplas formas de acessar o JitsiMeetJS
			// A biblioteca pode exportar de diferentes formas dependendo da versão
			let jitsiModule: unknown = null;
			
			// Tentativa 1: export default
			if (module.default) {
				if (typeof module.default === 'object' && 'init' in module.default) {
					jitsiModule = module.default;
					console.log('✅ Encontrado em module.default');
				}
			}
			
			// Tentativa 2: export nomeado JitsiMeetJS
			if (!jitsiModule && module.JitsiMeetJS) {
				jitsiModule = module.JitsiMeetJS;
				console.log('✅ Encontrado em module.JitsiMeetJS');
			}
			
			// Tentativa 3: o próprio módulo pode ser o JitsiMeetJS
			if (!jitsiModule && typeof module === 'object' && 'init' in module) {
				jitsiModule = module;
				console.log('✅ Encontrado no próprio módulo');
			}
			
			if (!jitsiModule) {
				throw new Error(
					'Não foi possível encontrar JitsiMeetJS no módulo. ' +
					'Verifique se lib-jitsi-meet está instalado corretamente.'
				);
			}
			
			JitsiMeetJS = jitsiModule as unknown as JitsiMeetJSLib;
			
			// Verificar se JitsiMeetJS foi inicializado corretamente
			if (!JitsiMeetJS || !JitsiMeetJS.init || typeof JitsiMeetJS.init !== 'function') {
				throw new Error('JitsiMeetJS não possui método init válido');
			}
			
			// Verificar se JitsiConnection existe
			if (!JitsiMeetJS.JitsiConnection) {
				throw new Error('JitsiConnection não está disponível no módulo carregado');
			}
			
			console.log('🔧 Inicializando Jitsi Meet JS...');
			
			// Inicializar Jitsi
			JitsiMeetJS.init({
				disableAudioLevels: false,
				disableSimulcast: false,
				enableWindowOnErrorHandler: true,
				enableRemb: true,
				enableTcc: true,
				disableThirdPartyRequests: false
			});
			
			// Configurar nível de log
			if (JitsiMeetJS.setLogLevel && typeof JitsiMeetJS.setLogLevel === 'function') {
				if (JitsiMeetJS.constants && JitsiMeetJS.constants.logLevels) {
					JitsiMeetJS.setLogLevel(JitsiMeetJS.constants.logLevels.INFO);
				}
			}
			
			console.log('✅ Jitsi Meet JS carregado e inicializado com sucesso');
		} catch (error: unknown) {
			const errorMessage = error instanceof Error ? error.message : String(error);
			console.error('❌ Erro ao carregar lib-jitsi-meet:', error);
			console.error('Detalhes do erro:', {
				message: errorMessage,
				stack: error instanceof Error ? error.stack : undefined,
				error
			});
			
			// Verificar se é um erro de módulo não encontrado
			if (errorMessage.includes('Failed to fetch') || 
			    errorMessage.includes('Cannot find module') ||
			    errorMessage.includes('Failed to resolve') ||
			    errorMessage.includes('Dynamic import') ||
			    errorMessage.includes('biblioteca Jitsi não pôde ser carregada')) {
				handleError(
					'Biblioteca de vídeo não encontrada',
					'A biblioteca Jitsi não pôde ser encontrada. Verifique se o pacote "lib-jitsi-meet" está instalado. Se o problema persistir, tente limpar o cache do navegador e recarregar a página.'
				);
			} else {
				handleError(
					'Erro ao carregar biblioteca de vídeo',
					`Não foi possível carregar a biblioteca necessária para chamadas de vídeo. Erro: ${errorMessage}. Por favor, recarregue a página e tente novamente.`
				);
			}
		}
	}

	// Inicializar store
	function inicializarStore(): void {
		if (chamada && meuPerfil?.data) {
			inicializarChamada(
				chamadaId,
				conversaId,
				tipo,
				roomName,
				ehAnfitriao,
				chamada.participantes.map(pId => ({
					usuarioId: pId,
					nome: 'Participante', // Será atualizado depois
					audioHabilitado: true,
					videoHabilitado: tipo === 'video'
				}))
			);
		}
	}

	// Inicializar Jitsi
	async function inicializarJitsi(): Promise<void> {
		if (!browser || !JitsiMeetJS) {
			await carregarJitsi();
		}
		
		if (!JitsiMeetJS) {
			console.error('JitsiMeetJS não está disponível');
			handleError(
				'Biblioteca de vídeo não disponível',
				'A biblioteca Jitsi não pôde ser carregada. Por favor, recarregue a página e tente novamente.'
			);
			return;
		}
		
		try {
			const config = configJitsi();
			const { host, porta } = obterHostEPorta(config.domain);
			const protocol = config.useHttps ? 'https' : 'http';
			
			// Configuração conforme documentação oficial do Jitsi Meet
			// https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-ljm-api/
			const baseUrl = `${protocol}://${host}${porta && porta !== (config.useHttps ? 443 : 80) ? `:${porta}` : ''}`;
			const boshUrl = `${baseUrl}/http-bind`;
			
			// Determinar MUC baseado no host
			// Para localhost, usar conference.localhost
			// Para domínios reais, usar conference.{host}
			const mucDomain = host === 'localhost' || host.startsWith('127.0.0.1') 
				? `conference.${host}` 
				: `conference.${host}`;
			
			const options: JitsiConnectionOptions = {
				hosts: {
					domain: host,
					muc: mucDomain,
					focus: `focus.${host}`
				},
				serviceUrl: boshUrl,
				bosh: boshUrl,
				clientNode: config.appId,
				// Opções de performance recomendadas
				enableLayerSuspension: true,
				enableLipSync: false,
				disableAudioLevels: false,
				disableSimulcast: false,
				enableRemb: true,
				enableTcc: true,
				useStunTurn: true,
				// Configurações de codec
				preferredVideoCodec: 'VP8',
				disableVP8: false,
				disableVP9: false,
				disableH264: false,
				// Configurações de áudio
				stereo: false,
				enableOpusRed: true,
				enableDtmf: true
			};

			console.log('🔧 Configurando conexão Jitsi (conforme documentação oficial):', {
				host,
				porta,
				protocol,
				baseUrl,
				serviceUrl: options.serviceUrl,
				muc: options.hosts?.muc,
				focus: options.hosts?.focus
			});

			const connection = new JitsiMeetJS.JitsiConnection(null, null, options);
			jitsiConnection = connection;
			setJitsiApi(connection);

			// Eventos de conexão
			connection.addEventListener(JitsiMeetJS.constants.events.connection.CONNECTION_ESTABLISHED, () => {
				console.log('✅ Conexão estabelecida');
				atualizarStatusConexao(true);
				tentativasReconexao = 0; // Resetar contador de tentativas
				reconectando = false;
				qualidadeConexao = 'boa'; // Inicial como boa
				
				// Iniciar chamada no backend
				client.mutation(api.chamadas.iniciarChamada, { chamadaId });

				// Criar conferência com opções recomendadas pela documentação oficial
				const estadoAtual = get(callState);
				const conferenceOptions: Record<string, unknown> = {
					startAudioMuted: !estadoAtual.audioHabilitado,
					startVideoMuted: !estadoAtual.videoHabilitado,
					// Opções de P2P (peer-to-peer) para melhor performance
					p2p: {
						enabled: true,
						stunServers: [
							{ urls: 'stun:stun.l.google.com:19302' },
							{ urls: 'stun:stun1.l.google.com:19302' }
						]
					},
					// Configurações de qualidade de vídeo
					resolution: 720,
					maxBitrate: 2500000, // 2.5 Mbps
					// Configurações de áudio
					audioQuality: {
						stereo: false,
						opusMaxAverageBitrate: 64000
					}
				};

				const conference = connection.initJitsiConference(roomName, conferenceOptions);
				jitsiConference = conference;
				setJitsiApi(conference);

				// Eventos da conferência
				configurarEventosConferencia(conference);

				// Entrar na conferência
				conference.join();
			});

			connection.addEventListener(JitsiMeetJS.constants.events.connection.CONNECTION_FAILED, (error: unknown) => {
				console.error('❌ Falha na conexão:', error);
				atualizarStatusConexao(false);
				
				const errorMsg = error instanceof Error ? error.message : String(error);
				
				// Tentar reconectar se ainda houver tentativas
				if (tentativasReconexao < MAX_TENTATIVAS_RECONEXAO) {
					tentativasReconexao++;
					reconectando = true;
					
					setTimeout(() => {
						console.log(`🔄 Tentativa de reconexão ${tentativasReconexao}/${MAX_TENTATIVAS_RECONEXAO}...`);
						connection.connect();
					}, 2000 * tentativasReconexao); // Backoff exponencial
				} else {
					reconectando = false;
					handleError(
						'Erro ao conectar com servidor de vídeo',
						`Não foi possível conectar ao servidor Jitsi após ${MAX_TENTATIVAS_RECONEXAO} tentativas.\n\nErro: ${errorMsg}`,
						false
					);
				}
			});

			connection.addEventListener(JitsiMeetJS.constants.events.connection.CONNECTION_DISCONNECTED, () => {
				console.log('🔌 Conexão desconectada');
				atualizarStatusConexao(false);
				qualidadeConexao = 'desconhecida';
				
				// Tentar reconectar automaticamente se não foi intencional
				if (tentativasReconexao < MAX_TENTATIVAS_RECONEXAO && !reconectando) {
					tentativasReconexao++;
					reconectando = true;
					
					setTimeout(() => {
						console.log(`🔄 Tentando reconectar após desconexão (${tentativasReconexao}/${MAX_TENTATIVAS_RECONEXAO})...`);
						connection.connect();
					}, 3000);
				}
			});

			// Conectar
			console.log('🔄 Tentando conectar ao servidor Jitsi...');
			connection.connect();
		} catch (error) {
			console.error('Erro ao inicializar Jitsi:', error);
			handleError(
				'Erro ao inicializar chamada',
				'Não foi possível inicializar a chamada de vídeo. Verifique suas permissões de microfone e câmera.',
				error instanceof Error ? error.message : String(error)
			);
		}
	}

	// Configurar eventos da conferência
	function configurarEventosConferencia(
		conference: JitsiConference
	): void {
		if (!JitsiMeetJS) return;
		
		// Participante entrou
		conference.on(JitsiMeetJS.constants.events.conference.USER_JOINED, (id: unknown, user: unknown) => {
			console.log('👤 Participante entrou:', id, user);
			// Atualizar lista de participantes
			atualizarListaParticipantes().then(() => {
				// Atualizar nomes nos overlays
				if (typeof id === 'string') {
					atualizarNomeParticipante(id);
				}
			});
		});

		// Participante saiu
		conference.on(JitsiMeetJS.constants.events.conference.USER_LEFT, (id: unknown) => {
			console.log('👋 Participante saiu:', id);
			atualizarListaParticipantes();
		});

		// Áudio/vídeo mutado/desmutado
		conference.on(JitsiMeetJS.constants.events.conference.TRACK_MUTE_CHANGED, (track: unknown) => {
			const jitsiTrack = track as JitsiTrack;
			console.log('🎤 Mute mudou:', jitsiTrack);
			const participantId = jitsiTrack.getParticipantId();
			
			// Atualizar estado do participante
			atualizarListaParticipantes().then(() => {
				// Atualizar indicadores visuais
				atualizarIndicadoresParticipante(participantId);
			});
		});

		// Novo track remoto
		conference.on(
			JitsiMeetJS.constants.events.conference.TRACK_ADDED,
			(track: unknown) => {
				const jitsiTrack = track as JitsiTrack;
				console.log('📹 Track adicionado:', jitsiTrack);
				adicionarTrackRemoto(jitsiTrack);
			}
		);

		// Track removido
		conference.on(
			JitsiMeetJS.constants.events.conference.TRACK_REMOVED,
			(track: unknown) => {
				const jitsiTrack = track as JitsiTrack;
				console.log('📹 Track removido:', jitsiTrack);
				removerTrackRemoto(jitsiTrack);
			}
		);

		// Monitorar qualidade de conexão (se disponível)
		if ('getConnectionQuality' in conference && typeof conference.getConnectionQuality === 'function') {
			setInterval(() => {
				try {
					// Tentar obter estatísticas de conexão
					const stats = (conference as unknown as { getConnectionQuality(): string }).getConnectionQuality();
					if (stats === 'high' || stats === 'veryhigh') {
						qualidadeConexao = 'excelente';
					} else if (stats === 'medium') {
						qualidadeConexao = 'boa';
					} else if (stats === 'low') {
						qualidadeConexao = 'regular';
					} else {
						qualidadeConexao = 'ruim';
					}
				} catch {
					// Se não disponível, manter como boa
					if (qualidadeConexao === 'desconhecida') {
						qualidadeConexao = 'boa';
					}
				}
			}, 5000); // Verificar a cada 5 segundos
		}

		// Conferência iniciada - criar tracks locais
		conference.on(JitsiMeetJS.constants.events.conference.CONFERENCE_JOINED, async () => {
			console.log('🎉 Conferência iniciada! Criando tracks locais...');
			qualidadeConexao = 'boa'; // Inicializar como boa ao entrar na conferência
			
			try {
				const estadoAtual = get(callState);
				
				// Construir constraints para áudio e vídeo
				const constraints: {
					audio?: boolean | Record<string, unknown>;
					video?: boolean | Record<string, unknown>;
				} = {
					audio: estadoAtual.audioHabilitado ? {
						echoCancellation: true,
						noiseSuppression: true,
						autoGainControl: true
					} : false,
					video: estadoAtual.videoHabilitado ? {
						facingMode: 'user',
						width: { ideal: 1280 },
						height: { ideal: 720 }
					} : false
				};

				console.log('📹 Criando tracks locais com constraints:', constraints);
				
				// Criar tracks locais
				const tracks = await JitsiMeetJS.createLocalTracks(constraints, {
					devices: [],
					cameraDeviceId: estadoChamada.dispositivos.cameraId || undefined,
					micDeviceId: estadoChamada.dispositivos.microphoneId || undefined
				});
				
				console.log('✅ Tracks locais criados:', tracks.length);
				
				// Armazenar tracks
				localTracks = tracks;
				
				// Adicionar cada track à conferência
				for (const track of tracks) {
					try {
						await conference.addTrack(track);
						console.log(`✅ Track ${track.getType()} adicionado à conferência`);
						
						// Se for vídeo, anexar ao elemento local
						if (track.getType() === 'video' && localVideo) {
							track.attach(localVideo);
							console.log('✅ Vídeo local anexado ao elemento');
						}
					} catch (trackError) {
						console.error(`Erro ao adicionar track ${track.getType()}:`, trackError);
					}
				}
				
				// Criar MediaStream para gravação (se necessário)
				const stream = new MediaStream(tracks.map(t => t.track));
				setStreamLocal(stream);
				
				// Definir nome do display
				if (meuPerfil?.data?.nome) {
					conference.setDisplayName(meuPerfil.data.nome);
				}
				
				// Atualizar lista de participantes
				atualizarListaParticipantes().then(() => {
					// Atualizar todos os nomes e indicadores
					remoteVideoElements.forEach((_, participantId) => {
						atualizarNomeParticipante(participantId);
						atualizarIndicadoresParticipante(participantId);
					});
				});
			} catch (error) {
				console.error('Erro ao criar tracks locais:', error);
				handleError(
					'Erro ao acessar mídia',
					'Não foi possível acessar seu microfone ou câmera. Verifique as permissões do navegador e tente novamente.',
					error instanceof Error ? error.message : String(error)
				);
			}
		});

		// Conferência finalizada
		conference.on(JitsiMeetJS.constants.events.conference.CONFERENCE_LEFT, () => {
			console.log('🚪 Conferência finalizada');
			
			// Limpar tracks locais
			localTracks.forEach(track => {
				track.dispose().catch(err => console.error('Erro ao liberar track:', err));
			});
			localTracks = [];
			
			// Limpar elementos remotos
			remoteVideoElements.forEach((data) => {
				const videoElement = data.element.querySelector('video');
				if (videoElement) {
					data.track.detach(videoElement);
				}
				data.element.remove();
			});
			remoteVideoElements.clear();

			remoteAudioElements.forEach((audioElement) => {
				audioElement.remove();
			});
			remoteAudioElements.clear();
			
			setStreamLocal(null);
			finalizarChamadaStore();
		});
	}

	// Mapa para rastrear elementos de vídeo remotos
	let remoteVideoElements = $state<Map<string, { element: HTMLElement; track: JitsiTrack }>>(new Map());
	let remoteAudioElements = $state<Map<string, HTMLAudioElement>>(new Map());

	// Adicionar track remoto ao container
	function adicionarTrackRemoto(track: JitsiTrack): void {
		if (!videoContainer) return;

		const participantId = track.getParticipantId();
		const trackType = track.getType();
		
		// Para áudio, criar elemento de áudio invisível
		if (trackType === 'audio') {
			// Verificar se já existe
			if (remoteAudioElements.has(participantId)) {
				return;
			}

			const audioElement = document.createElement('audio');
			audioElement.id = `remote-audio-${participantId}`;
			audioElement.autoplay = true;
			audioElement.playsInline = true;
			audioElement.style.display = 'none';
			
			track.attach(audioElement);
			videoContainer.appendChild(audioElement);
			remoteAudioElements.set(participantId, audioElement);
			return;
		}
		
		// Para vídeo, criar elemento de vídeo com container melhorado
		if (trackType === 'video') {
			// Verificar se já existe
			if (remoteVideoElements.has(participantId)) {
				return;
			}

			// Criar container para o vídeo com indicadores
			const container = document.createElement('div');
			container.id = `remote-video-container-${participantId}`;
			container.className = 'relative aspect-video w-full rounded-lg bg-base-200 overflow-hidden shadow-lg transition-all duration-300';

			// Criar elemento de vídeo
			const videoElement = document.createElement('video');
			videoElement.id = `remote-video-${participantId}`;
			videoElement.autoplay = true;
			videoElement.playsInline = true;
			videoElement.className = 'h-full w-full object-cover';

			// Criar overlay com nome do participante
			const overlay = document.createElement('div');
			overlay.className = 'absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent p-2';
			
			const nomeParticipante = document.createElement('div');
			nomeParticipante.className = 'text-white text-sm font-medium';
			nomeParticipante.textContent = 'Participante';
			
			// Criar indicadores de áudio/vídeo
			const indicators = document.createElement('div');
			indicators.className = 'absolute top-2 right-2 flex gap-1';
			
			// Indicador de áudio
			const audioIndicator = document.createElement('div');
			audioIndicator.id = `audio-indicator-${participantId}`;
			audioIndicator.className = 'bg-base-300 opacity-80 rounded-full p-1';
			audioIndicator.innerHTML = '<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path d="M9.383 3.076A1 1 0 0110 4v12a1 1 0 01-1.617.793L4.383 13H2a1 1 0 01-1-1V8a1 1 0 011-1h2.383l4-3.617a1 1 0 011.617.793zM14.657 2.929a1 1 0 011.414 0A9.972 9.972 0 0119 10a9.972 9.972 0 01-2.929 7.071 1 1 0 01-1.414-1.414A7.971 7.971 0 0017 10c0-2.21-.894-4.208-2.343-5.657a1 1 0 010-1.414zm-2.829 2.828a1 1 0 011.415 0A5.983 5.983 0 0115 10a5.984 5.984 0 01-1.757 4.243 1 1 0 01-1.415-1.415A3.984 3.984 0 0013 10a3.983 3.983 0 00-1.172-2.828 1 1 0 010-1.415z"/></svg>';
			
			// Indicador de vídeo
			const videoIndicator = document.createElement('div');
			videoIndicator.id = `video-indicator-${participantId}`;
			videoIndicator.className = 'bg-base-300 opacity-80 rounded-full p-1';
			videoIndicator.innerHTML = '<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path d="M2 6a2 2 0 012-2h6a2 2 0 012 2v8a2 2 0 01-2 2H4a2 2 0 01-2-2V6zM14.553 7.106A1 1 0 0014 8v4a1 1 0 00.553.894l2 1A1 1 0 0018 13V7a1 1 0 00-1.447-.894l-2 1z"/></svg>';

			indicators.appendChild(audioIndicator);
			indicators.appendChild(videoIndicator);
			overlay.appendChild(nomeParticipante);
			
			container.appendChild(videoElement);
			container.appendChild(overlay);
			container.appendChild(indicators);

			track.attach(videoElement);
			videoContainer.appendChild(container);
			remoteVideoElements.set(participantId, { element: container, track });

			// Atualizar nome do participante se disponível
			atualizarNomeParticipante(participantId);
		}
	}

	// Atualizar nome do participante no overlay
	function atualizarNomeParticipante(participantId: string): void {
		const container = remoteVideoElements.get(participantId);
		if (!container) return;

		const overlay = container.element.querySelector('.absolute.bottom-0');
		if (!overlay) return;

		const nomeElement = overlay.querySelector('.text-white');
		if (!nomeElement) return;

		// Buscar nome do participante no estado
		const participante = estadoChamada.participantes.find(
			p => p.participantId === participantId
		);
		
		if (participante) {
			nomeElement.textContent = participante.nome;
		}
	}

	// Atualizar indicadores de áudio/vídeo
	function atualizarIndicadoresParticipante(participantId: string): void {
		const container = remoteVideoElements.get(participantId);
		if (!container) return;

		const participante = estadoChamada.participantes.find(
			p => p.participantId === participantId
		);

		if (!participante) return;

		const audioIndicator = container.element.querySelector(`#audio-indicator-${participantId}`);
		const videoIndicator = container.element.querySelector(`#video-indicator-${participantId}`);

		if (audioIndicator) {
			audioIndicator.className = participante.audioHabilitado
				? 'bg-success opacity-80 rounded-full p-1'
				: 'bg-error opacity-80 rounded-full p-1';
		}

		if (videoIndicator) {
			videoIndicator.className = participante.videoHabilitado
				? 'bg-success opacity-80 rounded-full p-1'
				: 'bg-error opacity-80 rounded-full p-1';
		}
	}

	// Remover track remoto do container
	function removerTrackRemoto(track: JitsiTrack): void {
		if (!videoContainer) return;
		
		const participantId = track.getParticipantId();
		const trackType = track.getType();
		
		if (trackType === 'audio') {
			const audioElement = remoteAudioElements.get(participantId);
			if (audioElement) {
				track.detach(audioElement);
				audioElement.remove();
				remoteAudioElements.delete(participantId);
			}
		} else if (trackType === 'video') {
			const videoData = remoteVideoElements.get(participantId);
			if (videoData) {
				const videoElement = videoData.element.querySelector('video');
				if (videoElement) {
					track.detach(videoElement);
				}
				videoData.element.remove();
				remoteVideoElements.delete(participantId);
			}
		}
	}

	// Atualizar lista de participantes
	async function atualizarListaParticipantes(): Promise<void> {
		if (!jitsiConference) return;

		const participants = jitsiConference.getParticipants();
		// Mapear participantes para o formato esperado
		// Isso pode ser expandido para buscar informações do backend
		const participantesAtualizados = Array.from(participants.values()).map((participant) => {
			return {
				usuarioId: participant.getId() as Id<'usuarios'>,
				nome: participant.getDisplayName() || 'Participante',
				audioHabilitado: !participant.isAudioMuted(),
				videoHabilitado: !participant.isVideoMuted(),
				participantId: participant.getId()
			};
		});

		atualizarParticipantes(participantesAtualizados);
	}

	// Controles
	async function handleToggleAudio(): Promise<void> {
		if (!jitsiConference) return;
		
		const estadoAtual = get(callState);
		const novoEstadoAudio = !estadoAtual.audioHabilitado;
		
		// Atualizar estado no store
		setAudioHabilitado(novoEstadoAudio);
		
		// Atualizar track local
		const audioTrack = localTracks.find(t => t.getType() === 'audio');
		if (audioTrack) {
			if (novoEstadoAudio) {
				await audioTrack.unmute();
			} else {
				await audioTrack.mute();
			}
		} else {
			// Se não há track, tentar criar um novo
			if (novoEstadoAudio) {
				try {
					const tracks = await JitsiMeetJS!.createLocalTracks({ audio: true });
					if (tracks.length > 0) {
						const newTrack = tracks[0];
						await jitsiConference!.addTrack(newTrack);
						localTracks = [...localTracks, newTrack];
					}
				} catch (error) {
					console.error('Erro ao criar track de áudio:', error);
					handleError('Erro ao habilitar áudio', 'Não foi possível acessar o microfone.');
				}
			}
		}
		
		// Notificar backend se for anfitrião
		if (ehAnfitriao && meuPerfil?.data) {
			await client.mutation(api.chamadas.toggleAudioVideoParticipante, {
				chamadaId,
				participanteId: meuPerfil.data._id,
				tipo: 'audio',
				habilitado: novoEstadoAudio
			}).catch(err => console.error('Erro ao atualizar backend:', err));
		}
	}

	async function handleToggleVideo(): Promise<void> {
		if (!jitsiConference) return;
		
		const estadoAtual = get(callState);
		const novoEstadoVideo = !estadoAtual.videoHabilitado;
		
		// Atualizar estado no store
		setVideoHabilitado(novoEstadoVideo);
		
		// Atualizar track local
		const videoTrack = localTracks.find(t => t.getType() === 'video');
		if (videoTrack) {
			if (novoEstadoVideo) {
				await videoTrack.unmute();
				if (localVideo) {
					videoTrack.attach(localVideo);
				}
			} else {
				await videoTrack.mute();
			}
		} else {
			// Se não há track, tentar criar um novo
			if (novoEstadoVideo) {
				try {
					const tracks = await JitsiMeetJS!.createLocalTracks({ 
						video: { facingMode: 'user' } 
					});
					if (tracks.length > 0) {
						const newTrack = tracks[0];
						await jitsiConference!.addTrack(newTrack);
						localTracks = [...localTracks, newTrack];
						if (localVideo) {
							newTrack.attach(localVideo);
						}
					}
				} catch (error) {
					console.error('Erro ao criar track de vídeo:', error);
					handleError('Erro ao habilitar vídeo', 'Não foi possível acessar a câmera.');
				}
			}
		}
		
		// Notificar backend se for anfitrião
		if (ehAnfitriao && meuPerfil?.data) {
			await client.mutation(api.chamadas.toggleAudioVideoParticipante, {
				chamadaId,
				participanteId: meuPerfil.data._id,
				tipo: 'video',
				habilitado: novoEstadoVideo
			}).catch(err => console.error('Erro ao atualizar backend:', err));
		}
	}

	async function handleIniciarGravacao(): Promise<void> {
		if (!jitsiConference || gravador) return;

		try {
			// Usar tracks locais armazenados
			if (localTracks.length === 0) {
				handleError('Nenhum stream disponível', 'Não há áudio ou vídeo para gravar.');
				return;
			}

			// Criar MediaStream com todos os tracks
			const stream = new MediaStream();
			localTracks.forEach((track) => {
				stream.addTrack(track.track);
			});

			// Criar gravador
			gravador = new GravadorMedia(stream, tipo);
			const iniciou = gravador.iniciar();

			if (iniciou) {
				iniciarGravacaoStore();
				// Notificar backend
				await client.mutation(api.chamadas.iniciarGravacao, { chamadaId }).catch(err => {
					console.error('Erro ao notificar backend sobre gravação:', err);
				});
			} else {
				handleError('Erro ao iniciar gravação', 'Não foi possível iniciar a gravação.');
			}
		} catch (error) {
			console.error('Erro ao iniciar gravação:', error);
			handleError(
				'Erro ao iniciar gravação',
				'Não foi possível iniciar a gravação da chamada.',
				error instanceof Error ? error.message : String(error)
			);
		}
	}

	async function handlePararGravacao(): Promise<void> {
		if (!gravador) return;

		try {
			const blob = await gravador.parar();
			const nomeArquivo = gerarNomeArquivo(tipo, roomName);
			salvarGravacao(blob, nomeArquivo);

			pararGravacaoStore();
			gravador.liberar();
			gravador = null;

			// Notificar backend
			await client.mutation(api.chamadas.finalizarGravacao, { chamadaId }).catch(err => {
				console.error('Erro ao notificar backend sobre finalização de gravação:', err);
			});
		} catch (error) {
			console.error('Erro ao parar gravação:', error);
			handleError(
				'Erro ao parar gravação',
				'Não foi possível finalizar a gravação.',
				error instanceof Error ? error.message : String(error)
			);
		}
	}

	function handleAbrirConfiguracoes(): void {
		showSettings = true;
	}

	function handleAplicarConfiguracoes(dispositivos: {
		microphoneId: string | null;
		cameraId: string | null;
		speakerId: string | null;
	}): void {
		atualizarDispositivos(dispositivos);
		// Aplicar novos dispositivos na conferência
		if (jitsiConference) {
			// Isso requer reconfigurar os tracks
			// Por enquanto, apenas salvar as preferências
		}
	}

	async function handleEncerrar(): Promise<void> {
		if (confirm('Tem certeza que deseja encerrar a chamada?')) {
			await finalizar();
		}
	}

	async function finalizar(): Promise<void> {
		// Parar gravação se estiver gravando
		if (gravador) {
			await handlePararGravacao();
		}

		// Parar timer
		if (duracaoTimer) {
			clearInterval(duracaoTimer);
			duracaoTimer = null;
		}

		// Limpar tracks locais
		for (const track of localTracks) {
			try {
				await track.dispose();
			} catch (err) {
				console.error('Erro ao liberar track:', err);
			}
		}
		localTracks = [];

		// Desconectar Jitsi
		if (jitsiConference) {
			try {
				jitsiConference.leave();
			} catch (err) {
				console.error('Erro ao sair da conferência:', err);
			}
			jitsiConference = null;
		}

		if (jitsiConnection) {
			try {
				jitsiConnection.disconnect();
			} catch (err) {
				console.error('Erro ao desconectar:', err);
			}
			jitsiConnection = null;
		}

		// Limpar streams
		setStreamLocal(null);

		// Finalizar no backend
		await client.mutation(api.chamadas.finalizarChamada, { chamadaId }).catch(err => {
			console.error('Erro ao finalizar chamada no backend:', err);
		});

		// Limpar store
		finalizarChamadaStore();

		// Fechar janela
		onClose();
	}

	// Timer de duração
	function iniciarTimer(): void {
		if (duracaoTimer) return;

		duracaoTimer = setInterval(() => {
			const estado = get(callState);
			if (estado.chamadaId) {
				const novaDuracao = estado.duracaoSegundos + 1;
				atualizarDuracao(novaDuracao);
			}
		}, 1000);
	}

	// Configurar janela flutuante
	function configurarJanelaFlutuante(): void {
		if (!janelaElement || !dragHandle) return;

		// Restaurar posição ou usar inicial
		const posicaoSalva = restaurarPosicaoJanela(chamadaId);
		const posicaoInicial = posicaoSalva || obterPosicaoInicial(800, 600);

		if (janelaElement) {
			janelaElement.style.position = 'fixed';
			janelaElement.style.left = `${posicaoInicial.x}px`;
			janelaElement.style.top = `${posicaoInicial.y}px`;
			janelaElement.style.width = `${posicaoInicial.width}px`;
			janelaElement.style.height = `${posicaoInicial.height}px`;
			janelaElement.style.zIndex = '1000';
		}

		// Criar handlers
		if (dragHandle) {
			criarDragHandler(janelaElement, dragHandle, (x, y) => {
				if (janelaElement) {
					salvarPosicaoJanela(chamadaId, {
						x,
						y,
						width: janelaElement.offsetWidth,
						height: janelaElement.offsetHeight
					});
				}
			});
		}

		// Handles de resize
		const handles: HTMLDivElement[] = [];
		for (let i = 0; i < 8; i++) {
			const handle = document.createElement('div');
			handle.className = `absolute resize-handle resize-${['n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'][i]}`;
			handles.push(handle);
		}

		if (janelaElement) {
			criarResizeHandler(
				janelaElement,
				handles,
				{ minWidth: 400, minHeight: 300 },
				(width, height) => {
					const rect = janelaElement!.getBoundingClientRect();
					salvarPosicaoJanela(chamadaId, {
						x: rect.left,
						y: rect.top,
						width,
						height
					});
				}
			);
			resizeHandles = handles;
		}
	}

	onMount(async () => {
		if (!browser) return;
		
		// Garantir que BlobBuilder está disponível antes de qualquer coisa
		garantirBlobBuilderPolyfill();
		
		// Inicializar store primeiro
		inicializarStore();
		
		// Carregar Jitsi
		await carregarJitsi();
		
		// Configurar janela flutuante
		configurarJanelaFlutuante();

		// Inicializar Jitsi
		await inicializarJitsi();

		// Iniciar timer
		iniciarTimer();

		return () => {
			// Cleanup
			finalizar();
		};
	});

	onDestroy(() => {
		finalizar();
	});
</script>

<div
	bind:this={janelaElement}
	class="bg-base-100 pointer-events-auto flex flex-col rounded-lg shadow-2xl"
	role="dialog"
	aria-labelledby="call-window-title"
	aria-modal="true"
>
	<!-- Header com drag handle -->
	<div
		bind:this={dragHandle}
		class="bg-base-200 flex cursor-move items-center justify-between rounded-t-lg px-4 py-2"
	>
		<div class="flex items-center gap-2">
			<GripVertical class="text-base-content/50 h-4 w-4" />
			<h3 id="call-window-title" class="text-base-content text-sm font-semibold">
				Chamada {tipo === 'audio' ? 'de Áudio' : 'de Vídeo'}
			</h3>
		</div>
		<button
			type="button"
			class="btn btn-sm btn-circle btn-ghost"
			onclick={finalizar}
			aria-label="Fechar"
		>
			<X class="h-4 w-4" />
		</button>
	</div>

	<!-- Indicador de gravação -->
	{#if estadoChamada.gravando}
		<RecordingIndicator
			gravando={estadoChamada.gravando}
			iniciadoPor={ehAnfitriao ? 'Você' : undefined}
		/>
	{/if}

	<!-- Container de vídeo -->
	{#if true}
		{@const numVideosRemotos = remoteVideoElements.size}
		{@const temVideoLocal = tipo === 'video' && estadoChamada.videoHabilitado && localVideo}
		{@const totalVideos = (temVideoLocal ? 1 : 0) + numVideosRemotos}
		{@const usarGrid = estadoChamada.estaConectado && totalVideos > 0}
		{@const numColunas = totalVideos === 1 ? 1 : totalVideos <= 4 ? 2 : 3}
		<div
			bind:this={videoContainer}
			class="bg-base-300 flex-1 gap-4 p-4 overflow-auto"
			class:grid={usarGrid}
			class:flex={!usarGrid}
			class:flex-wrap={!usarGrid}
			class:grid-cols-1={usarGrid && numColunas === 1}
			class:grid-cols-2={usarGrid && numColunas === 2}
			class:grid-cols-3={usarGrid && numColunas === 3}
		>
		{#if !estadoChamada.estaConectado}
			<div class="flex h-full w-full items-center justify-center col-span-full">
				<div class="text-center">
					<span class="loading loading-spinner loading-lg text-primary"></span>
					<p class="mt-4 text-lg font-medium">Conectando à chamada...</p>
					<p class="mt-2 text-sm text-base-content/70">
						Aguarde enquanto estabelecemos a conexão
					</p>
				</div>
			</div>
		{:else}
			<!-- Vídeo Local -->
			{#if tipo === 'video' && estadoChamada.videoHabilitado && localVideo}
				<div class="relative aspect-video w-full rounded-lg bg-base-200 overflow-hidden shadow-lg transition-all duration-300">
					<video
						bind:this={localVideo}
						autoplay
						muted
						playsinline
						class="h-full w-full object-cover"
					></video>
					<!-- Overlay com nome local -->
					<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent p-2">
						<div class="text-white text-sm font-medium">
							{meuPerfil?.data?.nome || 'Você'}
						</div>
					</div>
					<!-- Indicadores locais -->
					<div class="absolute top-2 right-2 flex gap-1">
						<div
							class="rounded-full p-1 opacity-80"
							class:bg-success={estadoChamada.audioHabilitado}
							class:bg-error={!estadoChamada.audioHabilitado}
						>
							<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
								<path d="M9.383 3.076A1 1 0 0110 4v12a1 1 0 01-1.617.793L4.383 13H2a1 1 0 01-1-1V8a1 1 0 011-1h2.383l4-3.617a1 1 0 011.617.793zM14.657 2.929a1 1 0 011.414 0A9.972 9.972 0 0119 10a9.972 9.972 0 01-2.929 7.071 1 1 0 01-1.414-1.414A7.971 7.971 0 0017 10c0-2.21-.894-4.208-2.343-5.657a1 1 0 010-1.414zm-2.829 2.828a1 1 0 011.415 0A5.983 5.983 0 0115 10a5.984 5.984 0 01-1.757 4.243 1 1 0 01-1.415-1.415A3.984 3.984 0 0013 10a3.983 3.983 0 00-1.172-2.828 1 1 0 010-1.415z"/>
							</svg>
						</div>
						<div
							class="rounded-full p-1 opacity-80"
							class:bg-success={estadoChamada.videoHabilitado}
							class:bg-error={!estadoChamada.videoHabilitado}
						>
							<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
								<path d="M2 6a2 2 0 012-2h6a2 2 0 012 2v8a2 2 0 01-2 2H4a2 2 0 01-2-2V6zM14.553 7.106A1 1 0 0014 8v4a1 1 0 00.553.894l2 1A1 1 0 0018 13V7a1 1 0 00-1.447-.894l-2 1z"/>
							</svg>
						</div>
					</div>
				</div>
			{:else if tipo === 'audio'}
				<!-- Placeholder para chamada de áudio -->
				<div class="flex h-full w-full items-center justify-center col-span-full">
					<div class="text-center">
						<div class="bg-primary/20 rounded-full p-8 mx-auto w-32 h-32 flex items-center justify-center mb-4">
							<svg class="w-16 h-16 text-primary" fill="currentColor" viewBox="0 0 20 20">
								<path d="M9.383 3.076A1 1 0 0110 4v12a1 1 0 01-1.617.793L4.383 13H2a1 1 0 01-1-1V8a1 1 0 011-1h2.383l4-3.617a1 1 0 011.617.793zM14.657 2.929a1 1 0 011.414 0A9.972 9.972 0 0119 10a9.972 9.972 0 01-2.929 7.071 1 1 0 01-1.414-1.414A7.971 7.971 0 0017 10c0-2.21-.894-4.208-2.343-5.657a1 1 0 010-1.414zm-2.829 2.828a1 1 0 011.415 0A5.983 5.983 0 0115 10a5.984 5.984 0 01-1.757 4.243 1 1 0 01-1.415-1.415A3.984 3.984 0 0013 10a3.983 3.983 0 00-1.172-2.828 1 1 0 010-1.415z"/>
							</svg>
						</div>
						<p class="text-lg font-medium">Chamada de Áudio</p>
						<p class="text-sm text-base-content/70 mt-2">
							{estadoChamada.participantes.length} participante{estadoChamada.participantes.length !== 1 ? 's' : ''}
						</p>
					</div>
				</div>
			{/if}
			<!-- Vídeos remotos serão adicionados dinamicamente pelo JavaScript -->
		{/if}
		</div>
	{/if}

	<!-- Controles do anfitrião -->
	{#if ehAnfitriao && estadoChamada.participantes.length > 0}
		<HostControls
			participantes={estadoChamada.participantes}
			onToggleParticipanteAudio={(usuarioId) => {
				// Implementar toggle de áudio do participante
				console.log('Toggle audio participante:', usuarioId);
			}}
			onToggleParticipanteVideo={(usuarioId) => {
				// Implementar toggle de vídeo do participante
				console.log('Toggle video participante:', usuarioId);
			}}
		/>
	{/if}

	<!-- Controles -->
	<CallControls
		audioHabilitado={estadoChamada.audioHabilitado}
		videoHabilitado={estadoChamada.videoHabilitado}
		gravando={estadoChamada.gravando}
		ehAnfitriao={ehAnfitriao}
		duracaoSegundos={estadoChamada.duracaoSegundos}
		onToggleAudio={handleToggleAudio}
		onToggleVideo={handleToggleVideo}
		onIniciarGravacao={handleIniciarGravacao}
		onPararGravacao={handlePararGravacao}
		onAbrirConfiguracoes={handleAbrirConfiguracoes}
		onEncerrar={handleEncerrar}
	/>

	<!-- Modal de configurações -->
	{#if showSettings}
		<CallSettings
			open={showSettings}
			dispositivoAtual={estadoChamada.dispositivos}
			onClose={() => (showSettings = false)}
			onAplicar={handleAplicarConfiguracoes}
		/>
	{/if}

	<!-- Modal de Erro -->
	<ErrorModal
		open={showErrorModal}
		title={errorTitle}
		message={errorMessage}
		details={errorDetails}
		onClose={() => {
			showErrorModal = false;
			errorMessage = '';
			errorDetails = undefined;
		}}
	/>
</div>

<style>
	.resize-handle {
		background: transparent;
		border: 2px solid transparent;
	}
	
	.resize-n,
	.resize-s {
		height: 4px;
		width: 100%;
		cursor: ns-resize;
	}
	
	.resize-e,
	.resize-w {
		height: 100%;
		width: 4px;
		cursor: ew-resize;
	}
	
	.resize-nw,
	.resize-se {
		height: 8px;
		width: 8px;
		cursor: nwse-resize;
	}
	
	.resize-ne,
	.resize-sw {
		height: 8px;
		width: 8px;
		cursor: nesw-resize;
	}
	
	.resize-n {
		top: 0;
		left: 0;
	}
	
	.resize-ne {
		top: 0;
		right: 0;
	}
	
	.resize-e {
		top: 0;
		right: 0;
	}
	
	.resize-se {
		bottom: 0;
		right: 0;
	}
	
	.resize-s {
		bottom: 0;
		left: 0;
	}
	
	.resize-sw {
		bottom: 0;
		left: 0;
	}
	
	.resize-w {
		top: 0;
		left: 0;
	}
	
	.resize-nw {
		top: 0;
		left: 0;
	}
</style>

