/**
 * Utilitários para integração com Jitsi Meet
 */

export interface ConfiguracaoJitsi {
	domain: string;
	appId: string;
	roomPrefix: string;
	useHttps: boolean;
	acceptSelfSignedCert?: boolean;
}

export interface DispositivoMedia {
	deviceId: string;
	label: string;
	kind: 'audioinput' | 'audiooutput' | 'videoinput';
}

export interface DispositivosDisponiveis {
	microphones: DispositivoMedia[];
	speakers: DispositivoMedia[];
	cameras: DispositivoMedia[];
}

/**
 * Obter configuração do Jitsi do backend ou variáveis de ambiente (fallback)
 *
 * @param configBackend - Configuração do backend (opcional). Se fornecida, será usada.
 * @returns Configuração do Jitsi
 */
export function obterConfiguracaoJitsi(
	configBackend?: {
		domain: string;
		appId: string;
		roomPrefix: string;
		useHttps: boolean;
		acceptSelfSignedCert?: boolean;
	} | null
): ConfiguracaoJitsi {
	// Se há configuração do backend e está ativa, usar ela
	if (configBackend) {
		return {
			domain: configBackend.domain,
			appId: configBackend.appId,
			roomPrefix: configBackend.roomPrefix,
			useHttps: configBackend.useHttps,
			acceptSelfSignedCert: configBackend.acceptSelfSignedCert || false
		};
	}

	// Fallback para variáveis de ambiente
	const domain = import.meta.env.VITE_JITSI_DOMAIN || 'localhost:8443';
	const appId = import.meta.env.VITE_JITSI_APP_ID || 'sgse-app';
	const roomPrefix = import.meta.env.VITE_JITSI_ROOM_PREFIX || 'sgse';
	const useHttps = import.meta.env.VITE_JITSI_USE_HTTPS === 'true' || domain.includes(':8443');
	const acceptSelfSignedCert = import.meta.env.VITE_JITSI_ACCEPT_SELF_SIGNED === 'true';

	return {
		domain,
		appId,
		roomPrefix,
		useHttps,
		acceptSelfSignedCert
	};
}

/**
 * Obter configuração do Jitsi de forma síncrona (apenas variáveis de ambiente)
 * Use esta função quando não houver acesso ao Convex client
 */
export function obterConfiguracaoJitsiSync(): ConfiguracaoJitsi {
	const domain = import.meta.env.VITE_JITSI_DOMAIN || 'localhost:8443';
	const appId = import.meta.env.VITE_JITSI_APP_ID || 'sgse-app';
	const roomPrefix = import.meta.env.VITE_JITSI_ROOM_PREFIX || 'sgse';
	const useHttps = import.meta.env.VITE_JITSI_USE_HTTPS === 'true' || domain.includes(':8443');

	return {
		domain,
		appId,
		roomPrefix,
		useHttps
	};
}

/**
 * Obter host e porta separados do domínio
 */
export function obterHostEPorta(domain: string): { host: string; porta: number } {
	const [host, portaStr] = domain.split(':');
	const porta = portaStr ? parseInt(portaStr, 10) : domain.includes('8443') ? 8443 : 443;
	return { host: host || 'localhost', porta };
}

/**
 * Gerar nome único para a sala Jitsi
 *
 * @param conversaId - ID da conversa
 * @param tipo - Tipo de chamada ('audio' ou 'video')
 * @param configBackend - Configuração do backend (opcional). Se não fornecida, usa fallback.
 */
export function gerarRoomName(
	conversaId: string,
	tipo: 'audio' | 'video',
	configBackend?: {
		roomPrefix: string;
	} | null
): string {
	const config = obterConfiguracaoJitsi(configBackend || undefined);
	const timestamp = Date.now();
	const random = Math.random().toString(36).substring(2, 9);
	const conversaHash = conversaId.replace(/[^a-zA-Z0-9]/g, '').substring(0, 10);

	return `${config.roomPrefix}-${tipo}-${conversaHash}-${timestamp}-${random}`;
}

/**
 * Obter URL completa da sala Jitsi
 *
 * @param roomName - Nome da sala Jitsi
 * @param configBackend - Configuração do backend (opcional). Se não fornecida, usa fallback.
 */
export function obterUrlSala(
	roomName: string,
	configBackend?: {
		domain: string;
		useHttps: boolean;
	} | null
): string {
	const config = obterConfiguracaoJitsi(configBackend || undefined);
	const protocol = config.useHttps ? 'https' : 'http';
	return `${protocol}://${config.domain}/${roomName}`;
}

/**
 * Validar se dispositivos de mídia estão disponíveis
 */
export async function validarDispositivos(): Promise<{
	microfoneDisponivel: boolean;
	cameraDisponivel: boolean;
}> {
	if (typeof window === 'undefined') {
		return {
			microfoneDisponivel: false,
			cameraDisponivel: false
		};
	}

	try {
		const devices = await navigator.mediaDevices.enumerateDevices();

		const microfoneDisponivel = devices.some((device) => device.kind === 'audioinput');
		const cameraDisponivel = devices.some((device) => device.kind === 'videoinput');

		return {
			microfoneDisponivel,
			cameraDisponivel
		};
	} catch (error) {
		console.error('Erro ao validar dispositivos:', error);
		return {
			microfoneDisponivel: false,
			cameraDisponivel: false
		};
	}
}

/**
 * Solicitar permissão de acesso aos dispositivos de mídia
 */
export async function solicitarPermissaoMidia(
	audio: boolean = true,
	video: boolean = false
): Promise<MediaStream | null> {
	if (typeof window === 'undefined') {
		return null;
	}

	try {
		const stream = await navigator.mediaDevices.getUserMedia({
			audio,
			video: video ? { facingMode: 'user' } : false
		});
		return stream;
	} catch (error) {
		console.error('Erro ao solicitar permissão de mídia:', error);
		return null;
	}
}

/**
 * Obter lista de dispositivos de mídia disponíveis
 */
export async function obterDispositivosDisponiveis(): Promise<DispositivosDisponiveis> {
	if (typeof window === 'undefined') {
		return {
			microphones: [],
			speakers: [],
			cameras: []
		};
	}

	try {
		// Solicitar permissão primeiro para obter labels dos dispositivos
		await navigator.mediaDevices.getUserMedia({ audio: true, video: true });

		const devices = await navigator.mediaDevices.enumerateDevices();

		const microphones: DispositivoMedia[] = devices
			.filter((device) => device.kind === 'audioinput')
			.map((device) => ({
				deviceId: device.deviceId,
				label: device.label || `Microfone ${device.deviceId.substring(0, 8)}`,
				kind: 'audioinput' as const
			}));

		const speakers: DispositivoMedia[] = devices
			.filter((device) => device.kind === 'audiooutput')
			.map((device) => ({
				deviceId: device.deviceId,
				label: device.label || `Alto-falante ${device.deviceId.substring(0, 8)}`,
				kind: 'audiooutput' as const
			}));

		const cameras: DispositivoMedia[] = devices
			.filter((device) => device.kind === 'videoinput')
			.map((device) => ({
				deviceId: device.deviceId,
				label: device.label || `Câmera ${device.deviceId.substring(0, 8)}`,
				kind: 'videoinput' as const
			}));

		return {
			microphones,
			speakers,
			cameras
		};
	} catch (error) {
		console.error('Erro ao obter dispositivos disponíveis:', error);
		return {
			microphones: [],
			speakers: [],
			cameras: []
		};
	}
}

/**
 * Configurar dispositivo de áudio de saída (alto-falante)
 */
export async function configurarAltoFalante(
	deviceId: string,
	audioElement: HTMLAudioElement
): Promise<boolean> {
	if (typeof window === 'undefined') {
		return false;
	}

	try {
		// @ts-expect-error - setSinkId pode não estar disponível em todos os navegadores
		if (audioElement.setSinkId && typeof audioElement.setSinkId === 'function') {
			await audioElement.setSinkId(deviceId);
			return true;
		}
		return false;
	} catch (error) {
		console.error('Erro ao configurar alto-falante:', error);
		return false;
	}
}

/**
 * Verificar se WebRTC está disponível no navegador
 */
export function verificarSuporteWebRTC(): boolean {
	if (typeof window === 'undefined') {
		return false;
	}

	return !!(
		navigator.mediaDevices &&
		navigator.mediaDevices.getUserMedia &&
		window.RTCPeerConnection
	);
}

/**
 * Obter informações do navegador para debug
 */
export function obterInfoNavegador(): {
	navegador: string;
	versao: string;
	webrtcSuportado: boolean;
	mediaDevicesDisponivel: boolean;
} {
	if (typeof window === 'undefined') {
		return {
			navegador: 'Servidor',
			versao: 'N/A',
			webrtcSuportado: false,
			mediaDevicesDisponivel: false
		};
	}

	const userAgent = navigator.userAgent;
	let navegador = 'Desconhecido';
	let versao = 'Desconhecida';

	if (userAgent.indexOf('Chrome') > -1) {
		navegador = 'Chrome';
		const match = userAgent.match(/Chrome\/(\d+)/);
		versao = match ? match[1] : 'Desconhecida';
	} else if (userAgent.indexOf('Firefox') > -1) {
		navegador = 'Firefox';
		const match = userAgent.match(/Firefox\/(\d+)/);
		versao = match ? match[1] : 'Desconhecida';
	} else if (userAgent.indexOf('Safari') > -1) {
		navegador = 'Safari';
		const match = userAgent.match(/Version\/(\d+)/);
		versao = match ? match[1] : 'Desconhecida';
	} else if (userAgent.indexOf('Edge') > -1) {
		navegador = 'Edge';
		const match = userAgent.match(/Edge\/(\d+)/);
		versao = match ? match[1] : 'Desconhecida';
	}

	return {
		navegador,
		versao,
		webrtcSuportado: verificarSuporteWebRTC(),
		mediaDevicesDisponivel: !!navigator.mediaDevices
	};
}
