import { STORAGE } from '@/core/constants/storage-keys'
import { isTeenModeEnabled, verifyTeenPin } from '@/features/account/teen-mode-settings'

export const SESSION_LIMIT_MS = 40 * 60 * 1000
export const DAILY_LIMIT_MS = 40 * 60 * 1000
export const CURFEW_START_HOUR = 22
export const CURFEW_END_HOUR = 6
export const TICK_MS = 15000

const LOCK_PAGE = 'pages/user/settings/teen-mode-lock'

let i18nRef = null
let started = false
let foreground = false
let tickTimer = null
let navigatingLock = false

const lockState = {
	locked: false,
	reason: ''
}

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 pad2(n) {
	return n < 10 ? `0${n}` : String(n)
}

function todayKey(date = new Date()) {
	return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`
}

function defaultUsage(now = Date.now()) {
	return {
		date: todayKey(new Date(now)),
		dailyMs: 0,
		sessionMs: 0,
		lastTickAt: now
	}
}

function normalizeUsage(raw) {
	if (!raw || typeof raw !== 'object') return defaultUsage()
	const now = Date.now()
	const usage = {
		date: String(raw.date || todayKey(new Date(now))),
		dailyMs: Math.max(0, Number(raw.dailyMs) || 0),
		sessionMs: Math.max(0, Number(raw.sessionMs) || 0),
		lastTickAt: Number(raw.lastTickAt) || now
	}
	if (usage.date !== todayKey()) {
		usage.date = todayKey()
		usage.dailyMs = 0
		usage.sessionMs = 0
		usage.lastTickAt = now
	}
	return usage
}

function readUsage() {
	try {
		return normalizeUsage(uni.getStorageSync(STORAGE.teenModeUsage))
	} catch (_) {
		return defaultUsage()
	}
}

function writeUsage(usage) {
	uni.setStorageSync(STORAGE.teenModeUsage, normalizeUsage(usage))
}

export function isCurfewHour(date = new Date()) {
	const hour = date.getHours()
	return hour >= CURFEW_START_HOUR || hour < CURFEW_END_HOUR
}

function notifyLock() {
	listeners.forEach((fn) => {
		try {
			fn({ ...lockState })
		} catch (_) {}
	})
}

function setLock(reason) {
	const nextReason = reason || ''
	if (lockState.locked === !!nextReason && lockState.reason === nextReason) return
	lockState.locked = !!nextReason
	lockState.reason = nextReason
	notifyLock()
	syncNativeMask()
	if (lockState.locked) {
		openLockPage(nextReason)
	}
}

function clearLock() {
	setLock('')
	closeLockPageIfNeeded()
}

export function refreshTeenModeGuard() {
	return evaluateLock()
}

export function getTeenLockState() {
	return { ...lockState }
}

export function subscribeTeenLock(listener) {
	if (typeof listener !== 'function') return () => {}
	listeners.add(listener)
	listener({ ...lockState })
	return () => listeners.delete(listener)
}

function flushUsage(now = Date.now()) {
	if (!foreground || isCurfewHour(new Date(now))) return readUsage()
	const usage = readUsage()
	const delta = Math.max(0, now - (usage.lastTickAt || now))
	if (delta <= 0) return usage
	usage.dailyMs += delta
	usage.sessionMs += delta
	usage.lastTickAt = now
	writeUsage(usage)
	return usage
}

function evaluateLock(now = Date.now()) {
	if (!isTeenModeEnabled()) {
		clearLock()
		return null
	}
	const date = new Date(now)
	if (isCurfewHour(date)) {
		setLock('curfew')
		return 'curfew'
	}
	if (lockState.locked && lockState.reason === 'curfew') {
		// 宵禁刚结束，继续检查时长
	} else if (lockState.locked && (lockState.reason === 'session' || lockState.reason === 'daily')) {
		return lockState.reason
	}
	const usage = flushUsage(now)
	if (usage.sessionMs >= SESSION_LIMIT_MS) {
		setLock('session')
		return 'session'
	}
	if (usage.dailyMs >= DAILY_LIMIT_MS) {
		setLock('daily')
		return 'daily'
	}
	clearLock()
	return null
}

function isOnLockPage() {
	const pages = getCurrentPages()
	const top = pages[pages.length - 1]
	const route = top && (top.route || (top.$page && top.$page.fullPath))
	return String(route || '').indexOf(LOCK_PAGE) !== -1
}

function openLockPage(reason) {
	if (navigatingLock || isOnLockPage()) return
	navigatingLock = true
	const url = `/pages/user/settings/teen-mode-lock?reason=${encodeURIComponent(reason || 'session')}`
	uni.navigateTo({
		url,
		fail: () => {
			uni.reLaunch({ url })
		},
		complete: () => {
			setTimeout(() => {
				navigatingLock = false
				syncNativeMask()
			}, 400)
		}
	})
}

function closeLockPageIfNeeded() {
	if (!isOnLockPage()) return
	uni.navigateBack({
		delta: 1,
		fail: () => {}
	})
}

export function tryUnlockTeenLock(pin) {
	if (!lockState.locked) return true
	if (lockState.reason === 'curfew') return false
	if (!verifyTeenPin(pin)) return false

	const usage = readUsage()
	const now = Date.now()
	if (lockState.reason === 'session') {
		usage.sessionMs = 0
	} else if (lockState.reason === 'daily') {
		usage.dailyMs = 0
		usage.sessionMs = 0
	}
	usage.lastTickAt = now
	writeUsage(usage)
	clearLock()
	return true
}

export function getTeenLockCopy(reason) {
	if (reason === 'curfew') {
		return {
			title: t('user.teenModeLockCurfewTitle', '宵禁时段'),
			desc: t(
				'user.teenModeLockCurfewDesc',
				'每日 22:00 至次日 6:00 为宵禁时段，期间暂停使用。请明日 6:00 后再试。'
			),
			showPin: false
		}
	}
	if (reason === 'daily') {
		return {
			title: t('user.teenModeLockDailyTitle', '今日使用时长已达上限'),
			desc: t(
				'user.teenModeLockDailyDesc',
				'今日累计使用已超过 40 分钟，请输入监护密码后继续。'
			),
			showPin: true
		}
	}
	return {
		title: t('user.teenModeLockSessionTitle', '该次使用时长已达上限'),
		desc: t(
			'user.teenModeLockSessionDesc',
			'本次连续使用已超过 40 分钟，请输入监护密码后继续。'
		),
		showPin: true
	}
}

function startTick() {
	stopTick()
	if (!foreground || !isTeenModeEnabled()) return
	tickTimer = setInterval(() => {
		evaluateLock()
	}, TICK_MS)
}

function stopTick() {
	if (tickTimer) {
		clearInterval(tickTimer)
		tickTimer = null
	}
}

export function notifyTeenModeChanged() {
	if (!isTeenModeEnabled()) {
		stopTick()
		clearLock()
		return
	}
	const usage = defaultUsage()
	writeUsage(usage)
	if (foreground) {
		evaluateLock()
		startTick()
	}
}

export function onTeenModeForeground() {
	foreground = true
	if (!isTeenModeEnabled()) {
		stopTick()
		return
	}
	const usage = readUsage()
	const now = Date.now()
	usage.lastTickAt = now
	writeUsage(usage)
	evaluateLock(now)
	startTick()
}

export function onTeenModeBackground() {
	if (!isTeenModeEnabled()) {
		foreground = false
		stopTick()
		return
	}
	flushUsage()
	foreground = false
	stopTick()
}

export function startTeenModeGuard(i18n) {
	if (started) return
	started = true
	i18nRef = i18n
	subscribeTeenLock(syncNativeMask)
}

// #ifdef APP-PLUS
let nativeMask = null

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

function syncNativeMask() {
	try {
		if (!lockState.locked || isOnLockPage()) {
			if (nativeMask) nativeMask.hide()
			return
		}
		ensureNativeMask().show()
	} catch (e) {
		console.warn('[teen-mode-guard] native mask', e)
	}
}

export function syncTeenLockOverlay() {
	syncNativeMask()
}
// #endif

// #ifndef APP-PLUS
function syncNativeMask() {}
export function syncTeenLockOverlay() {}
// #endif
