// c:\Users\zhu\Desktop\Practice Project\new-88live1\features\passport\social-login.js
/**
 * 社交登录（Social Login）桥接层。
 *
 * 封装第三方平台登录逻辑，对页面层暴露统一接口：
 *   - appleLogin    苹果登录
 *
 * 所有接口返回统一格式的会话数据：{ userinfo, statistics, token, ... }
 */

import { get, post } from '@/core/http/http-client'
import { buildRestPath } from '@/core/config/api-paths'
import { STORAGE } from '@/core/constants/storage-keys'
//import { googleLogin as pluginGoogleLogin } from '@/uni_modules/uni-oauth-google'

const ROUTE__LOGIN = buildRestPath('user/third')

const ROUTE__LINE_AUTH_URL = '/line/getAuthUrl'//LINE 授权地址接口
const ROUTE__LINE_GET_USERINFO = '/line/getuserinfo'//LINE 登录换取用户信息接口
const FORM_URLENCODED_HEADER = { 'content-type': 'application/x-www-form-urlencoded' }//后端按表单读取 ticket，这里统一声明表单请求头
const LINE_SUCCESS_PATHS = ['/api/line/loginsuccess', '/line/loginsuccess', '/line/login-success']//LINE 登录成功路径
const LINE_FAIL_PATHS = ['/api/line/loginfail', '/line/loginfail', '/line/login-fail']//LINE 登录失败路径
// 谷歌登录配置web client_id 335082713048-el1qosjevi6a8elp80rrq77798msfkij.apps.googleusercontent.com
//const GOOGLE_SERVER_CLIENT_ID = '335082713048-el1qosjevi6a8elp80rrq77798msfkij.apps.googleusercontent.com'
/**
 * LINE 登录配置
 */
function readClientHandle() {
	return uni.getStorageSync(STORAGE.chatClient) || null
}

/**
 * 把不同后端响应形状归一为 store 期望的 `{ userinfo, statistics, ... }`。
 */
function unwrapSession(raw) {
	if (!raw || typeof raw !== 'object') return null
	if (raw.userinfo && typeof raw.userinfo === 'object') return raw
	if (raw.data && typeof raw.data === 'object' && raw.data.userinfo) return raw.data
	if (raw.token || raw.id) return { userinfo: raw }
	return raw
}

/**
 * 从后端不同响应结构中提取 LINE 授权地址。
 * 新流程先 GET /line/getAuthUrl，再把接口返回的授权地址放进 WebView。
 */
function pickLineAuthUrl(raw) {
	if (!raw) return ''
	if (typeof raw === 'string') return raw.trim()
	const candidates = [
		raw.url,
		raw.auth_url,
		raw.authUrl,
		raw.authorize_url,
		raw.authorizeUrl,
		raw.redirect_url,
		raw.redirectUrl,
		raw.data && raw.data.url,
		raw.data && raw.data.auth_url,
		raw.data && raw.data.authUrl
	]
	const found = candidates.find(item => typeof item === 'string' && item.trim())
	return found ? found.trim() : ''
}

/**
 * 安全读取 WebView 当前 URL。
 * 真机上部分阶段 getURL 可能不可用，统一兜底为空字符串，避免调试监听中断登录流程。
 */
function readWebviewUrl(wv) {
	try {
		return wv && typeof wv.getURL === 'function' ? wv.getURL() : ''
	} catch (e) {
		return ''
	}
}

/**
 * 判断当前 WebView URL 是否命中 LINE 登录成功页。
 * 后端可能带 /api 前缀，成功页命中后前端会提取 ticket 继续换取用户信息。
 */
function isLineLoginSuccessUrl(url) {
	const text = String(url || '').toLowerCase()
	return LINE_SUCCESS_PATHS.some(path => text.indexOf(path) > -1)
}

/**
 * 判断当前 WebView URL 是否命中 LINE 登录失败页。
 * 失败页通常会带 error_msg，前端识别后关闭 WebView 并提示用户。
 */
function isLineLoginFailUrl(url) {
	const text = String(url || '').toLowerCase()
	return LINE_FAIL_PATHS.some(path => text.indexOf(path) > -1)
}

/**
 * 从 URL 查询参数中读取指定字段。
 * 优先使用 URL 标准解析，兼容失败时再用正则兜底，主要用于读取 ticket/error_msg。
 */
function readUrlQuery(url, key) {
	const target = String(url || '')
	try {
		const parsed = new URL(target)
		return parsed.searchParams.get(key) || ''
	} catch (_) {
		const match = target.match(new RegExp(`[?&]${key}=([^&]+)`))
		return match ? decodeURIComponent(match[1].replace(/\+/g, '%20')) : ''
	}
}

/**
 * 展开打印 /line/getuserinfo 请求失败信息。
 * HttpError 会把原始响应放在 payload 中，这里把状态码、请求地址和后端响应都打印出来，便于真机排查。
 */
function logLineUserinfoError(err) {
	// /line/getuserinfo 失败时，HttpError 的后端响应藏在 payload 里；这里展开关键字段方便真机定位。
	const payload = err && err.payload
	const responseBody = payload && (payload.res || payload.data)
	const requestUrl = payload && payload.config && payload.config.url
	console.log('[LINE 登录] /line/getuserinfo 错误详情:', {
		name: err && err.name,
		kind: err && err.kind,
		message: err && err.message,
		statusCode: payload && payload.statusCode,
		errMsg: payload && payload.errMsg,
		requestUrl,
		responseBody
	})
	try {
		console.log('[LINE 登录] /line/getuserinfo 后端响应 JSON:', JSON.stringify(responseBody))
	} catch (_) {}
}

/**
 * 苹果登录（Sign in with Apple）
 * 仅在 APP 端可用，H5 端不支持。
 *
 * @returns {Promise<Object>} 会话数据 { userinfo, token, ... }
 */
export function appleLogin() {
	return new Promise((resolve, reject) => {
		// #ifdef APP-PLUS
		uni.login({
			provider: 'apple',
			success: async (loginRes) => {
				try {
					const appleInfo = loginRes.appleInfo
					const identityToken = appleInfo.identityToken
					const authorizationCode = appleInfo.authorizationCode
					if (!identityToken && !authorizationCode) {
						reject(new Error('Apple login: no token received'))
						return
					}
					const { data } = await post(ROUTE__LOGIN, {
						platform: 'apple',
						loginData: loginRes,
						client_id: readClientHandle()
					})
					resolve(unwrapSession(data))
				} catch (err) {
					reject(err)
				}
			},
			fail: (err) => {
				const errMsg = err.errMsg || err.errCode || 'Apple login failed'
				reject(new Error(errMsg))
			}
		})
		// #endif

		// #ifndef APP-PLUS
		reject(new Error('Apple login is only supported on APP'))
		// #endif
	})
}

/**
 * 谷歌登录（Sign in with Google）
 * 仅在 APP 端可用，H5 端不支持。
 *
 * @returns {Promise<Object>} 会话数据 { userinfo, token, ... }
 */
// export function googleLogin() {
// 	return new Promise((resolve, reject) => {
// 		// #ifdef APP-PLUS
// 		pluginGoogleLogin({
// 			serverClientId: GOOGLE_SERVER_CLIENT_ID,
// 			success: (res) => {

// 				const idToken = res.idToken
// 				if (!idToken) {
// 					console.error('[Google Login] 未获取到 idToken')
// 					reject(new Error('Google login: no idToken received'))
// 					return
// 				}
// 				// 发送到后端验证
// 				post(ROUTE__LOGIN, {
// 					platform: 'google',
// 					idToken: idToken,
// 					userInfo: {
// 						googleId: res.openId,
// 						email: res.email,
// 						name: res.nickname,
// 						avatar: res.headimgurl
// 					},
// 					client_id: readClientHandle()
// 				}).then(({ data }) => {
// 					resolve(unwrapSession(data))
// 				}).catch(err => {

// 					reject(err)
// 				})
// 			},
// 			fail: (err) => {
// 				const errMsg = err.errMsg || err.errDesc || `Google login failed (code: ${err.errCode})`
// 				reject(new Error(errMsg))
// 			},
// 			complete: (res) => {
// 				console.log('[Google Login] 登录流程完成', res)
// 			}
// 		})

// 		// #endif
// 		// #ifndef APP-PLUS
// 		reject(new Error('Google login is only supported on APP'))
// 		// #endif
// 	})
// }

/**
 * LINE 登录（后端授权页 WebView 流程）
 * 兼容 iOS 和 Android 端。
 *
 * 注意：LINE 登录方式已改为先调用 GET /line/getAuthUrl 获取授权地址。
 * 前端不再拼接 access.line.me OAuth 参数，也不再把 code 提交到 user/third。
 *
 * @returns {Promise<Object>} /line/getuserinfo 成功后返回 `{ userinfo, statistics }`，页面层沿用普通登录写入流程。
 */
export function lineLogin() {
	return new Promise(async (resolve, reject) => {
		// #ifdef APP-PLUS

		let authUrl = ''
		try {
			// 先向后端获取本次 LINE 授权地址，由后端生成 state、redirect_uri 等参数。
			const { data } = await get(ROUTE__LINE_AUTH_URL)
			authUrl = pickLineAuthUrl(data)
		} catch (err) {
			reject(err)
			return
		}
		if (!authUrl) {
			reject(new Error('LINE login: no auth url received'))
			return
		}

		// 使用 /line/getAuthUrl 返回的授权地址打开 WebView，后端负责跳转 LINE 和处理 callback。
		const wv = plus.webview.create(authUrl, 'line-auth', {
			top: '44px',
			left: '0px',
			width: '100%',
			height: '100%',
			background: '#ffffff',
			// WebView 配置
			//javascriptEnabled: true,
			//domStorageEnabled: true,
			//mixedContentMode: 2,  // 允许混合内容
			//userAgent: 'Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36'
		})
		// 设置 WebView 样式
		wv.setStyle({
			progress: { color: '#00C300' }  // LINE 绿色进度条
		})
		let hasResolved = false

		// 监听页面流转；命中后端登录成功页时，提取 ticket 再换取 App 登录态。
		wv.addEventListener('loaded', async function () {
			const url = readWebviewUrl(wv)
			if (isLineLoginFailUrl(url)) {
				if (hasResolved) return
				hasResolved = true
				// 后端失败页会携带 error_msg，前端识别后关闭 WebView 并把原因抛给页面层。
				const message = readUrlQuery(url, 'error_msg') || readUrlQuery(url, 'message') || 'LINE login failed'
				wv.close()
				reject(new Error(message))
				return
			}
			if (!isLineLoginSuccessUrl(url)) return
			if (hasResolved) return

			hasResolved = true
			const ticket = readUrlQuery(url, 'ticket')
			// ticket 属于登录凭证，只用于换取用户信息，不输出到日志。

			if (!ticket) {
				wv.close()
				reject(new Error('LINE login: missing ticket'))
				return
			}

			try {
				// 后端接口按表单参数读取 ticket；data 保持对象形态，避免影响项目 Sign 签名计算。
				const { data } = await post(ROUTE__LINE_GET_USERINFO, { ticket }, {
					header: FORM_URLENCODED_HEADER
				})
				// 用户信息里包含 token 等敏感字段，成功时不打印响应内容。
				wv.close()
				resolve(unwrapSession(data))
			} catch (err) {
				logLineUserinfoError(err)
				wv.close()
				reject(err)
			}
		})

		// 监听错误
		wv.addEventListener('error', function (error) {
			// WebView 加载错误保留日志，便于定位授权页无法打开等异常。
			console.log('[LINE 登录][WebView] 加载错误:', error)
			if (!hasResolved) {
				hasResolved = true
				wv.close()
				reject(new Error('LINE login: WebView error'))
			}
		})

		// 显示 WebView
		wv.show()

		// #endif

		// #ifndef APP-PLUS
		reject(new Error('LINE login is only supported on APP'))
		// #endif
	})
}
