import appSettings from '@/core/config/app-settings'
import { isAbsoluteHttpUrl, trimTrailingSlash } from '@/core/network/url-detect'
import { buildApiSignature } from '@/core/network/request-sign'
import { applyClientHeaders, readSessionToken } from '@/core/network/client-meta'
import { adaptiveToast } from '@/core/ui/smart-toast'
import { parseApiResponse, snapshotEnvelope, applySuccessPayload } from './response-evaluator'

const LOGIN_ROUTE = '/pages/passport/lobby'

/** 为 true 时 HTTP 4xx/5xx 不弹 toast（用于网络探测等后台请求） */
let suppressHttpErrorToast = false

export function runWithoutHttpErrorToast(fn) {
	suppressHttpErrorToast = true
	return Promise.resolve()
		.then(fn)
		.finally(() => {
			suppressHttpErrorToast = false
		})
}

function ensureHeaderObject(cfg) {
	cfg.header = typeof cfg.header === 'object' && cfg.header !== null ? cfg.header : {}
	return cfg.header
}

function attachApiAuth(cfg) {
	const headers = ensureHeaderObject(cfg)
	const body = typeof cfg.data === 'object' && cfg.data !== null ? cfg.data : {}
	headers.Sign = buildApiSignature(cfg.url, body)
	cfg.url = trimTrailingSlash(appSettings.appurl) + cfg.url
	const token = readSessionToken()
	if (token) headers.token = token
	Object.assign(headers, applyClientHeaders(headers))
}

function decorateRelativeRequest(cfg) {
	if (isAbsoluteHttpUrl(cfg.url)) return
	attachApiAuth(cfg)
	const base = cfg.url
	const langQuery = `lang=${encodeURIComponent(uni.getLocale())}`
	cfg.url = base.includes('?') ? `${base}&${langQuery}` : `${base}?${langQuery}`
}

function decorateUpload(cfg) {
	if (isAbsoluteHttpUrl(cfg.url)) {
		const token = readSessionToken()
		if (token) ensureHeaderObject(cfg).token = token
		return
	}
	attachApiAuth(cfg)
}

export function registerHttpInterceptors(i18n) {
	const t = (key, fallback) => {
		try {
			return i18n ? i18n.t(key) : fallback
		} catch (_) {
			return fallback
		}
	}

	uni.addInterceptor('uploadFile', {
		invoke(cfg) {
			decorateUpload(cfg)
		},
		success(res) {
			if (res.statusCode !== 200) {
				let message = '上传失败'
				try {
					message = JSON.parse(res.data).msg || message
				} catch (_) {}
				adaptiveToast(message, 'error')
				return false
			}
			uni.showToast({ title: 'Success', position: true })
			return true
		}
	})

	uni.addInterceptor('request', {
		invoke(cfg) {
			cfg.sslVerify = false
			decorateRelativeRequest(cfg)
			if (appSettings.debug) console.log('[http:invoke]', cfg)
		},
		success(res) {
			snapshotEnvelope(res)
			const parsed = parseApiResponse(res)

			if (parsed.kind === 'success') {
				applySuccessPayload(res, parsed)
				if (appSettings.debug) {
					try {
						const reqUrl = res && res.config && res.config.url
						if (reqUrl && /live\/play/.test(reqUrl)) {
							console.log('=== [HTTP-DIAG] live/play raw response ===')
							console.log('[HTTP-DIAG] url =', reqUrl)
							console.log('[HTTP-DIAG] envelope =', res.res)
							console.log('[HTTP-DIAG] parsed.data =', parsed.data)
							console.log('[HTTP-DIAG] envelope JSON =', JSON.stringify(res.res))
						}
					} catch (logErr) {
						console.warn('[HTTP-DIAG] log failed', logErr)
					}
					console.log('[http:ok]', res)
				}
				return true
			}
			if (parsed.kind === 'passthrough') return
			// 业务失败须放行 success，由 http-client finalizeResponse 抛错并结束 Promise；
			// 若 return false 会拦截 success，await 永不 settle，页面 loading 无法结束。
			if (parsed.kind === 'silent_fail') {
				if (appSettings.debug) console.log('[http:silent-fail]', res)
				return true
			}

			if (parsed.kind === 'biz_fail') {
				adaptiveToast(parsed.message, 'error')
				if (appSettings.debug) console.log('[http:biz-fail]', res)
				return true
			}

			const status = parsed.status
			if (suppressHttpErrorToast) {
				if (appSettings.debug) {
					const reqUrl = (res && res.config && res.config.url) || ''
					console.warn('[http:silent-http-error]', status, reqUrl)
				}
				return true
			}
			if (status === 401) {
				adaptiveToast(parsed.message || '未授权', 'error')
				uni.reLaunch({ url: LOGIN_ROUTE })
			} else if (status === 404) {
				adaptiveToast(t('common.apiNotFound', 'API 接口不存在'), 'error')
			} else if (status === 500) {
				adaptiveToast(t('common.apiServerBusy', 'API 服務器繁忙'), 'error')
			} else {
				adaptiveToast(parsed.message || '请求失败', 'error')
			}
			if (appSettings.debug) console.log('[http:fail]', res)
			return true
		},
		fail(err) {
			if (appSettings.debug) console.log('[http:error]', err)
		}
	})
}
