const env = require(`${__hooks}/bai_api_pb_hooks/bai_api_shared/config/env.js`)
const { createAppError } = require(`${__hooks}/bai_api_pb_hooks/bai_api_shared/utils/appError.js`)

let accessTokenCache = {
    token: '',
    expiresAt: 0,
}

function ensureWechatConfig() {
    if (!env.wechatAppId || !env.wechatSecret) {
        throw createAppError(500, '微信小程序配置缺失')
    }
}

function getWxOpenId(code) {
    ensureWechatConfig()

    const res = $http.send({
        url: 'https://api.weixin.qq.com/sns/jscode2session?appid=' + encodeURIComponent(env.wechatAppId) + '&secret=' + encodeURIComponent(env.wechatSecret) + '&js_code=' + encodeURIComponent(code) + '&grant_type=authorization_code',
        method: 'GET',
        headers: {
            'content-type': 'application/json',
        },
        timeout: 10,
    })

    const data = res.json || {}

    if (data.openid) return data.openid

    if (data.errcode || data.errmsg) {
        throw createAppError(502, ('获取OpenID失败: ' + (data.errcode || '') + ' ' + (data.errmsg || '')).replace(/^\s+|\s+$/g, ''))
    }

    throw createAppError(502, '获取OpenID失败: 响应中未包含openid')
}

function getWechatAccessToken() {
    if (accessTokenCache.token && Date.now() < accessTokenCache.expiresAt) {
        return accessTokenCache.token
    }

    ensureWechatConfig()

    const res = $http.send({
        url: 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' + encodeURIComponent(env.wechatAppId) + '&secret=' + encodeURIComponent(env.wechatSecret),
        method: 'GET',
        headers: {
            'content-type': 'application/json',
        },
        timeout: 10,
    })

    const data = res.json || {}
    if (!data.access_token) {
        throw createAppError(502, ('获取微信 access_token 失败: ' + (data.errcode || '') + ' ' + (data.errmsg || '')).replace(/^\s+|\s+$/g, ''))
    }

    accessTokenCache = {
        token: data.access_token,
        expiresAt: Date.now() + Math.max(((data.expires_in || 7200) - 300), 60) * 1000,
    }

    return accessTokenCache.token
}

function getWxPhoneNumber(phoneCode) {
    const accessToken = getWechatAccessToken()

    const res = $http.send({
        url: 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' + encodeURIComponent(accessToken),
        method: 'POST',
        headers: {
            'content-type': 'application/json',
        },
        body: JSON.stringify({ code: phoneCode }),
        timeout: 10,
    })

    const data = res.json || {}
    const phoneInfo = data.phone_info || {}
    const phone = phoneInfo.purePhoneNumber || phoneInfo.phoneNumber

    if (phone) return phone

    throw createAppError(502, ('获取微信手机号失败: ' + (data.errcode || '') + ' ' + (data.errmsg || '')).replace(/^\s+|\s+$/g, ''))
}

module.exports = {
    getWxOpenId,
    getWxPhoneNumber,
}
