import appSettings from '@/core/config/app-settings'
import { runWithoutHttpErrorToast } from '@/core/http/interceptor-registry'

let blocked = false
let modalOpen = false
let probeInflight = null
let i18nRef = null

const listeners = new Set()

function t(key, fallback) {
	if (!i18nRef) return fallback
	try {
		const v = i18nRef.t(key)
		return v && v !== key ? v : fallback
	} catch (_) {
		return fallback
	}
}

function notify() {
	listeners.forEach((fn) => {
		try {
			fn(blocked)
		} catch (_) {}
	})
}

function setBlocked(next) {
	const v = !!next
	if (blocked === v) return
	blocked = v
	notify()
}

export function isNetworkBlocked() {
	return blocked
}

export function subscribeNetworkBlock(listener) {
	if (typeof listener === 'function') {
		listeners.add(listener)
		listener(blocked)
	}
	return () => listeners.delete(listener)
}

function getNetworkTypeAsync() {
	return new Promise((resolve) => {
		uni.getNetworkType({
			success: (res) => resolve((res && res.networkType) || 'unknown'),
			fail: () => resolve('none')
		})
	})
}

function probeApiReachable() {
	const base = (appSettings.appurl || '').replace(/\/$/, '')
	if (!base) return Promise.resolve(true)
	// 探测根路径常会 404，但会触发全局拦截器 toast「API 接口不存在」
	return runWithoutHttpErrorToast(
		() =>
			new Promise((resolve) => {
				uni.request({
					url: `${base}/`,
					method: 'GET',
					timeout: 6000,
					success: (res) => {
						const code = res && res.statusCode
						resolve(code >= 200 && code < 500)
					},
					fail: () => resolve(false)
				})
			})
	)
}

/**
 * 是否具备可用网络（无网络 / 系统禁止本 App 使用网络时返回 false）
 */
export async function checkNetworkAccess() {
	const type = await getNetworkTypeAsync()
	if (type === 'none') return false
	// 已连接 Wi‑Fi/蜂窝但仍可能被系统禁止本 App 使用网络，用轻量请求探测
	const reachable = await probeApiReachable()
	return reachable
}

export async function refreshNetworkAccess() {
	// #ifndef APP-PLUS
	setBlocked(false)
	return true
	// #endif
	// #ifdef APP-PLUS
	if (probeInflight) return probeInflight
	probeInflight = checkNetworkAccess()
		.then((ok) => {
			setBlocked(!ok)
			return ok
		})
		.finally(() => {
			probeInflight = null
		})
	return probeInflight
	// #endif
}

export function openNetworkSettings() {
	// #ifdef APP-PLUS
	try {
		const os = (plus.os.name || '').toLowerCase()
		if (os === 'ios') {
			plus.runtime.openURL('app-settings:')
			return
		}
		if (os === 'android') {
			const main = plus.android.runtimeMainActivity()
			const Intent = plus.android.importClass('android.content.Intent')
			const Settings = plus.android.importClass('android.provider.Settings')
			const intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS)
			main.startActivity(intent)
			return
		}
	} catch (e) {
		console.warn('[network-guard] open settings failed', e)
	}
	// #endif
	if (typeof uni.openAppAuthorizeSetting === 'function') {
		uni.openAppAuthorizeSetting({})
	}
}

export function promptNetworkRequired() {
	if (!blocked || modalOpen) return
	modalOpen = true
	uni.showModal({
		title: t('networkGuard.title', '需要网络'),
		content: t(
			'networkGuard.content',
			'当前无法访问网络。请在系统设置中允许本应用使用无线局域网与蜂窝数据，否则无法继续使用。'
		),
		confirmText: t('networkGuard.confirm', '去设置'),
		cancelText: t('networkGuard.cancel', '知道了'),
		showCancel: true,
		success: (res) => {
			modalOpen = false
			if (res.confirm) openNetworkSettings()
		},
		fail: () => {
			modalOpen = false
		}
	})
}

// #ifdef APP-PLUS
let nativeMask = null

function ensureNativeMask() {
	if (nativeMask) return nativeMask
	nativeMask = new plus.nativeObj.View(
		'hl88-network-blocker',
		{
			top: '0px',
			left: '0px',
			width: '100%',
			height: '100%',
			backgroundColor: 'rgba(0,0,0,0.01)'
		},
		[]
	)
	nativeMask.interceptTouchEvent(true)
	nativeMask.addEventListener('click', () => {
		promptNetworkRequired()
	})
	return nativeMask
}

function syncNativeMask() {
	try {
		const mask = ensureNativeMask()
		if (blocked) mask.show()
		else mask.hide()
	} catch (e) {
		console.warn('[network-guard] native mask', e)
	}
}
// #endif

function onBlockStateChange() {
	// #ifdef APP-PLUS
	syncNativeMask()
	// #endif
}

let started = false

export function startNetworkAccessGuard(i18n) {
	// #ifndef APP-PLUS
	return
	// #endif
	// #ifdef APP-PLUS
	if (started) return
	started = true
	i18nRef = i18n

	subscribeNetworkBlock(onBlockStateChange)

	const kickoff = () => refreshNetworkAccess()

	if (typeof plus !== 'undefined') {
		kickoff()
	} else if (typeof document !== 'undefined') {
		document.addEventListener('plusready', kickoff, false)
	} else {
		kickoff()
	}

	if (typeof uni.onNetworkStatusChange === 'function') {
		uni.onNetworkStatusChange(() => {
			refreshNetworkAccess()
		})
	}
	// #endif
}

export function stopNetworkAccessGuard() {
	// #ifndef APP-PLUS
	return
	// #endif
	// #ifdef APP-PLUS
	started = false
	if (nativeMask) {
		try {
			nativeMask.hide()
			nativeMask.close()
		} catch (_) {}
		nativeMask = null
	}
	// #endif
}
