const path = require('path')
const Logger = require('../../lib/Logger')
const { getJkesSettings, normalizeApiBase } = require('./jkesSettings')
const { postJkes } = require('./jkesHttp')

const logger = new Logger(path.join(__dirname, '../../logs/JKES.log'), 'INFO')

function buildJkesHeaders(token) {
    const tokenClean = String(token ?? '').trim()
    const s = getJkesSettings()
    return {
        'x-auth-token': tokenClean,
        'content-type': 'application/json',
        'Accept-Encoding': 'gzip,compress,br,deflate',
        'User-Agent': s.userAgent,
        Referer: s.referer
    }
}

function isJkesLoginExpiredPayload(payload) {
    if (!payload || typeof payload !== 'object') return false
    const code = Number(payload.code)
    const msg = String(payload.message ?? payload.msg ?? '').trim()
    return (
        (code === 500 && msg.includes('无效用户')) ||
        (code === 401 && msg.includes('您的认证已经失效'))
    )
}

function makeJkesLoginExpiredError(payload) {
    const msg = '乐跑账号登录失效，请重新使用乐跑登录器进行登录'
    const err = new Error(msg)
    err.code = 'JKES_AUTH_EXPIRED'
    err.loginExpired = true
    err.retryable = false
    err.payload = payload
    return err
}

/**
 * @param {string} url 如 /sys/user/getMyInfo
 * @param {object} [data] POST body
 * @param {string} token
 * @param {object} [options]
 * @param {'auto'|'direct'|'proxy'} [options.outboundMode='auto']
 */
async function jkesRequest(url, data, token, options = {}) {
    const tokenClean = String(token ?? '').trim()
    if (!tokenClean) {
        logger.error('[JKES] 缺少 token')
        return null
    }

    const s = getJkesSettings()
    const pathPart = url.startsWith('/') ? url : `/${url}`
    const fullUrl = `${normalizeApiBase(s.apiBase)}${pathPart}`
    const body = data === undefined || data === null ? {} : data
    const { outboundMode = 'auto' } = options

    let parsed
    try {
        parsed = new URL(fullUrl)
    } catch (e) {
        logger.error(`[JKES] 非法 URL: ${fullUrl}`)
        return null
    }
    if (parsed.protocol !== 'https:') {
        logger.error(`[JKES] 必须使用 https: ${fullUrl}`)
        return null
    }

    try {
        logger.info(`[JKES] POST ${pathPart}`)
        const res = await postJkes(fullUrl, body, {
            headers: buildJkesHeaders(tokenClean),
            timeout: Number(s.requestTimeoutMs) || 30000,
            validateStatus: () => true,
            outboundMode,
            logger
        })

        const payload = res.data
        const payloadPreview =
            typeof payload === 'object' && payload !== null
                ? JSON.stringify(payload)
                : String(payload ?? '')

        if (isJkesLoginExpiredPayload(payload)) {
            throw makeJkesLoginExpiredError(payload)
        }

        if (res.status !== 200) {
            logger.error(
                `[JKES] HTTP ${res.status} ${pathPart} 响应: ${payloadPreview.slice(0, 1000)}`
            )
            if (typeof payload === 'object' && payload !== null) {
                return payload
            }
            return null
        }

        return payload
    } catch (error) {
        if (error?.loginExpired) throw error
        const st = error.response?.status
        const dataErr = error.response?.data
        const errStr =
            typeof dataErr === 'object' && dataErr !== null
                ? JSON.stringify(dataErr)
                : String(dataErr ?? '')
        logger.error(
            `[JKES] 请求异常 ${pathPart} http=${st ?? 'n/a'} body=${errStr.slice(0, 500)} ${error.message}`
        )
        return null
    }
}

module.exports = {
    jkesRequest,
    isJkesLoginExpiredPayload,
    makeJkesLoginExpiredError,
    get BASE_URL() {
        return normalizeApiBase(getJkesSettings().apiBase)
    }
}
