import { type Signal, useComputed, useSignal } from '@preact/signals'
import { useEffect } from 'preact/hooks'

type NetworkConnection = {
	addEventListener: (
		type: 'change',
		listener: (event: Event) => void | Promise<void>,
	) => void
}

declare global {
	interface Navigator {
		connection?: NetworkConnection
	}
}

export default function IsOnline(
	{ online, offline }: { online?: string; offline: string },
) {
	const status = useSignal(true)
	const displayed = useComputed(() => {
		if (status.value && online) {
			return <span>{online}</span>
		}
		if (status.value) {
			return <span style={{ display: 'none' }}></span>
		}
		return <span class='island__is_online'>{offline}</span>
	})

	useEffect(() => {
		openSocket(status)
		navigator.connection?.addEventListener('change', () => {
			fetch('/api/serviceworker/is-online')
				.then(() => status.value = true)
				.catch(() => status.value = false)
		})
	}, [])

	return <>{displayed}</>
}

function openSocket(status: Signal<boolean>, timeout = 5_000) {
	const socket = new WebSocket(
		`wss://${location.host}/api/serviceworker/is-online`,
	)

	setTimeout(() => {
		if (socket.OPEN || socket.CONNECTING) return
		socket.close()
	}, timeout)

	socket.addEventListener('open', () => status.value = true)
	socket.addEventListener('close', () => {
		status.value = false
		setTimeout(() => openSocket(status), timeout)
	})
}
