const API = require("../../../lib/API")
const axios = require('axios')
const { BaseStdResponse } = require("../../../BaseStdResponse");
const https = require("https")
const { getUniLoginRuntimeConfig, normalizeSocialType } = require('../../../lib/UniLoginClient')

class GetLoginUrl extends API {
    constructor() {
        super();

        this.setPath('/UniLogin/GetLoginUrl')
        this.setMethod('GET')
    }

    async onRequest(req, res) {
        let { type, device, action, from, mode } = req.query
        type = normalizeSocialType(type)

        if (!type)
            return res.json({
                ...BaseStdResponse.ERR,
                msg: '不支持的第三方登录类型'
            })

        let uniConfig
        try {
            uniConfig = await getUniLoginRuntimeConfig({ requireEnabledType: type })
        } catch (error) {
            return res.json({
                ...BaseStdResponse.ERR,
                msg: error.message || '聚合登录暂未配置，请使用账号密码登录'
            })
        }

        /** 解析 URL 与 hash 内查询串，判断 query 是否已包含某键（避免对整段 URL 做子串误判） */
        const redirectUrlHasQueryKey = (redirectUrl, key) => {
            if (!redirectUrl || !key) return false
            try {
                const u = new URL(redirectUrl)
                if (u.searchParams.has(key)) return true
                const h = u.hash || ''
                const qPos = h.indexOf('?')
                if (qPos === -1) return false
                return new URLSearchParams(h.slice(qPos + 1)).has(key)
            } catch {
                return false
            }
        }

        const appendQuery = (redirectUrl) => {
            const params = []
            if (mode && !redirectUrlHasQueryKey(redirectUrl, 'mode'))
                params.push(`mode=${encodeURIComponent(mode)}`)
            if (action && !redirectUrlHasQueryKey(redirectUrl, 'action'))
                params.push(`action=${encodeURIComponent(action)}`)
            if (from && !redirectUrlHasQueryKey(redirectUrl, 'from'))
                params.push(`from=${encodeURIComponent(from)}`)

            if (params.length === 0)
                return redirectUrl

            return `${redirectUrl}${redirectUrl.includes('?') ? '&' : '?'}${params.join('&')}`
        }

        let redirectUri = appendQuery(uniConfig.return_url)
        let url = `${uniConfig.url}/connect.php?act=login&appid=${uniConfig.appid}&appkey=${uniConfig.appkey}&type=${type}&redirect_uri=${encodeURIComponent(redirectUri)}`
        if (device && device === 'uniapp')
            url = `${uniConfig.url}/connect.php?act=login&appid=${uniConfig.appid}&appkey=${uniConfig.appkey}&type=${type}&redirect_uri=${encodeURIComponent(appendQuery(uniConfig.uni_return_url))}`

        try {
            const r = await axios.get(url, {
                proxy: false,
                httpsAgent: new https.Agent({
                    rejectUnauthorized: false
                })
            })

            if (!r || r.data?.code !== 0 || !r.data?.url) {
                this.logger.error(`获取聚合登录链接失败！${r.data?.msg || 'api接口错误'}`)
                return res.json({
                    ...BaseStdResponse.ERR,
                    msg: '请尝试其他登录方式或稍后再试'
                })
            }

            res.json({
                ...BaseStdResponse.OK,
                data: r.data.url
            })
        } catch (error) {
            this.logger.error(`获取聚合登录链接失败！${error.message || 'api接口错误'}`)
            return res.json({
                ...BaseStdResponse.ERR,
                msg: '请尝试其他登录方式或稍后再试！'
            })
        }
    }
}

module.exports.GetLoginUrl = GetLoginUrl;
