const API = require('../../lib/API')
const { BaseStdResponse } = require('../../BaseStdResponse')
const crypto = require('crypto')
const { resolveBusinessOrderId } = require('../../lib/OrderPaymentAttempt')
const { getPaymentConfig } = require('../../lib/PaymentClient')
const { completePaidOrder } = require('../../lib/OrderSettlement')

function buildSign(params, key) {
    const raw = Object.keys(params)
        .sort()
        .map(name => `${name}=${params[name]}`)
        .join('&') + key
    return crypto.createHash('md5').update(raw, 'utf8').digest('hex')
}

class CallBack extends API {
    constructor() {
        super()
        this.noEncrypt()
        this.setPath('/Order/CallBack')
        this.setMethod('GET')
    }

    async onRequest(req, res) {
        const {
            pid, trade_no, out_trade_no, type, name, money,
            trade_status, sign, sign_type
        } = req.query

        if ([pid, trade_no, out_trade_no, type, name, money, trade_status, sign, sign_type].some(v => v === undefined)) {
            return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
        }

        this.logger.info(`收到支付回调，网关订单号：${out_trade_no}`)

        const paymentConfig = await getPaymentConfig()
        const rawParams = { money, name, out_trade_no, pid, trade_no, trade_status, type }
        const localSign = buildSign(rawParams, paymentConfig.key)
        if (localSign.toLowerCase() !== String(sign).toLowerCase()) {
            this.logger.error(`支付回调签名校验失败，网关订单号：${out_trade_no}`)
            return res.send('sign fail')
        }

        const orderId = await resolveBusinessOrderId(out_trade_no)

        if (trade_status !== 'TRADE_SUCCESS') {
            this.logger.info(`支付回调未成功，忽略并等待订单超时处理。网关订单号：${out_trade_no}，业务订单号：${orderId}`)
            return res.send('success')
        }

        const result = await completePaidOrder({
            orderId,
            payType: type,
            payId: trade_no,
            payTime: Date.now(),
            paidAmount: money,
            logger: this.logger
        })

        if (result.completed) return res.send('success')
        if (result.reason === 'state_changed') return res.send('success')
        this.logger.error(`支付回调处理失败，业务订单号：${orderId}，原因：${result.reason}`)
        return res.send('fail')
    }
}

module.exports.CallBack = CallBack
