<script lang="ts">
	import { Check, Volume2, X } from 'lucide-svelte';
	import { onMount } from 'svelte';
	import type { DispositivoMedia } from '$lib/utils/jitsi';
	import { obterDispositivosDisponiveis, solicitarPermissaoMidia } from '$lib/utils/jitsi';

	interface Props {
		open: boolean;
		dispositivoAtual: {
			microphoneId: string | null;
			cameraId: string | null;
			speakerId: string | null;
		};
		onClose: () => void;
		onAplicar: (dispositivos: {
			microphoneId: string | null;
			cameraId: string | null;
			speakerId: string | null;
		}) => void;
	}

	let { open, dispositivoAtual, onClose, onAplicar }: Props = $props();

	let dispositivos = $state<{
		microphones: DispositivoMedia[];
		speakers: DispositivoMedia[];
		cameras: DispositivoMedia[];
	}>({
		microphones: [],
		speakers: [],
		cameras: []
	});

	let selecionados = $state({
		microphoneId: dispositivoAtual.microphoneId || null,
		cameraId: dispositivoAtual.cameraId || null,
		speakerId: dispositivoAtual.speakerId || null
	});

	let carregando = $state(false);
	let previewStream: MediaStream | null = $state(null);
	let previewVideo: HTMLVideoElement | null = $state(null);
	let erro = $state<string | null>(null);

	// Carregar dispositivos disponíveis
	async function carregarDispositivos(): Promise<void> {
		carregando = true;
		erro = null;
		try {
			dispositivos = await obterDispositivosDisponiveis();
			if (dispositivos.microphones.length === 0 && dispositivos.cameras.length === 0) {
				erro = 'Nenhum dispositivo de mídia encontrado. Verifique as permissões do navegador.';
			}
		} catch (error) {
			console.error('Erro ao carregar dispositivos:', error);
			erro = 'Erro ao carregar dispositivos de mídia.';
		} finally {
			carregando = false;
		}
	}

	// Atualizar preview quando mudar dispositivos
	async function atualizarPreview(): Promise<void> {
		if (previewStream) {
			previewStream.getTracks().forEach((track) => track.stop());
			previewStream = null;
		}

		if (!previewVideo) return;

		try {
			const audio = selecionados.microphoneId !== null;
			const video = selecionados.cameraId !== null;

			if (audio || video) {
				const constraints: MediaStreamConstraints = {
					audio: audio
						? {
								deviceId: selecionados.microphoneId
									? { exact: selecionados.microphoneId }
									: undefined
							}
						: false,
					video: video
						? {
								deviceId: selecionados.cameraId ? { exact: selecionados.cameraId } : undefined
							}
						: false
				};

				previewStream = await solicitarPermissaoMidia(audio, video);
				if (previewStream && previewVideo) {
					previewVideo.srcObject = previewStream;
				}
			} else {
				previewVideo.srcObject = null;
			}
		} catch (error) {
			console.error('Erro ao atualizar preview:', error);
			erro = 'Erro ao acessar dispositivo de mídia.';
		}
	}

	// Testar áudio
	async function testarAudio(): Promise<void> {
		if (!selecionados.microphoneId) {
			erro = 'Selecione um microfone primeiro.';
			return;
		}

		try {
			const stream = await solicitarPermissaoMidia(true, false);
			if (stream) {
				// Criar elemento de áudio temporário para teste
				const audio = new Audio();
				const audioTracks = stream.getAudioTracks();
				if (audioTracks.length > 0) {
					// O áudio será reproduzido automaticamente se conectado
					setTimeout(() => {
						stream.getTracks().forEach((track) => track.stop());
					}, 3000);
				}
			}
		} catch (error) {
			console.error('Erro ao testar áudio:', error);
			erro = 'Erro ao testar microfone.';
		}
	}

	function handleFechar(): void {
		// Parar preview ao fechar
		if (previewStream) {
			previewStream.getTracks().forEach((track) => track.stop());
			previewStream = null;
		}
		if (previewVideo) {
			previewVideo.srcObject = null;
		}
		erro = null;
		onClose();
	}

	function handleAplicar(): void {
		onAplicar({
			microphoneId: selecionados.microphoneId,
			cameraId: selecionados.cameraId,
			speakerId: selecionados.speakerId
		});
		handleFechar();
	}

	// Carregar dispositivos quando abrir
	$effect(() => {
		if (typeof window === 'undefined') return;

		if (open) {
			carregarDispositivos();
		} else {
			// Limpar preview ao fechar
			if (previewStream) {
				previewStream.getTracks().forEach((track) => track.stop());
				previewStream = null;
			}
		}
	});

	// Atualizar preview quando mudar seleção
	$effect(() => {
		if (typeof window === 'undefined') return;

		if (open && (selecionados.microphoneId || selecionados.cameraId)) {
			atualizarPreview();
		}
	});

	onMount(() => {
		return () => {
			// Cleanup ao desmontar
			if (previewStream) {
				previewStream.getTracks().forEach((track) => track.stop());
			}
		};
	});
</script>

{#if open}
	<dialog
		class="modal modal-open"
		onclick={(e) => e.target === e.currentTarget && handleFechar()}
		role="dialog"
		aria-labelledby="modal-title"
	>
		<div class="modal-box max-w-2xl" onclick={(e) => e.stopPropagation()}>
			<!-- Header -->
			<div class="border-base-300 flex items-center justify-between border-b px-6 py-4">
				<h2 id="modal-title" class="text-xl font-semibold">Configurações de Mídia</h2>
				<button
					type="button"
					class="btn btn-sm btn-circle"
					onclick={handleFechar}
					aria-label="Fechar"
				>
					<X class="h-5 w-5" />
				</button>
			</div>

			<!-- Content -->
			<div class="max-h-[70vh] space-y-6 overflow-y-auto p-6">
				{#if erro}
					<div class="alert alert-error">
						<span>{erro}</span>
					</div>
				{/if}

				{#if carregando}
					<div class="flex items-center justify-center py-8">
						<span class="loading loading-spinner loading-lg"></span>
					</div>
				{:else}
					<!-- Seleção de Microfone -->
					<div>
						<label class="text-base-content mb-2 block text-sm font-medium"> Microfone </label>
						<select
							class="select select-bordered w-full"
							bind:value={selecionados.microphoneId}
							onchange={atualizarPreview}
						>
							<option value={null}>Padrão do Sistema</option>
							{#each dispositivos.microphones as microfone}
								<option value={microfone.deviceId}>{microfone.label}</option>
							{/each}
						</select>
						{#if selecionados.microphoneId}
							<button type="button" class="btn btn-sm btn-ghost mt-2" onclick={testarAudio}>
								<Volume2 class="h-4 w-4" />
								Testar
							</button>
						{/if}
					</div>

					<!-- Seleção de Câmera -->
					<div>
						<label class="text-base-content mb-2 block text-sm font-medium"> Câmera </label>
						<select
							class="select select-bordered w-full"
							bind:value={selecionados.cameraId}
							onchange={atualizarPreview}
						>
							<option value={null}>Padrão do Sistema</option>
							{#each dispositivos.cameras as camera}
								<option value={camera.deviceId}>{camera.label}</option>
							{/each}
						</select>
					</div>

					<!-- Preview de Vídeo -->
					{#if selecionados.cameraId}
						<div>
							<label class="text-base-content mb-2 block text-sm font-medium"> Preview </label>
							<div class="bg-base-300 aspect-video w-full overflow-hidden rounded-lg">
								<video
									bind:this={previewVideo}
									autoplay
									muted
									playsinline
									class="h-full w-full object-cover"
								></video>
							</div>
						</div>
					{/if}

					<!-- Seleção de Alto-falante (se disponível) -->
					{#if dispositivos.speakers.length > 0}
						<div>
							<label class="text-base-content mb-2 block text-sm font-medium"> Alto-falante </label>
							<select class="select select-bordered w-full" bind:value={selecionados.speakerId}>
								<option value={null}>Padrão do Sistema</option>
								{#each dispositivos.speakers as speaker}
									<option value={speaker.deviceId}>{speaker.label}</option>
								{/each}
							</select>
						</div>
					{/if}
				{/if}
			</div>

			<!-- Footer -->
			<div class="modal-action border-base-300 border-t px-6 py-4">
				<button type="button" class="btn btn-ghost" onclick={handleFechar}> Cancelar </button>
				<button type="button" class="btn btn-primary" onclick={handleAplicar} disabled={carregando}>
					<Check class="h-4 w-4" />
					Aplicar
				</button>
			</div>
		</div>

		<form method="dialog" class="modal-backdrop">
			<button type="button" onclick={handleFechar}>fechar</button>
		</form>
	</dialog>
{/if}
