const API = require("../../lib/API.js")
const db = require("../../plugin/DataBase/db.js")
const { BaseStdResponse } = require("../../BaseStdResponse.js")
const config = require('../../config.json')
const crypto = require("crypto")

const PAYMENT_KEY = config.pay.key

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 rawParams = {
            money, name, out_trade_no, pid, trade_no, trade_status, type
        }
        const sortedKeys = Object.keys(rawParams).sort()
        const preSignStr = sortedKeys.map(key => `${key}=${rawParams[key]}`).join('&') + PAYMENT_KEY
        const localSign = crypto.createHash('md5').update(preSignStr, 'utf8').digest('hex')

        if (localSign.toLowerCase() !== sign.toLowerCase()) {
            this.logger.error(`签名校验失败，订单号：${out_trade_no}`)
            return res.send('签名验证失败')
        }

        // 支付未成功，标记为失败
        if (trade_status !== 'TRADE_SUCCESS') {
            const sql = 'UPDATE orders SET state = 3, pay_id = ? WHERE orderId = ?'
            await db.query(sql, [trade_no, out_trade_no])
            this.logger.info(`支付未成功。订单号：${out_trade_no}`)
            return res.send('success')
        }

        try {
            // 更新订单状态为已支付（state=1）
            const time = new Date().getTime()
            let sql = 'UPDATE orders SET state = 1, pay_type = ?, pay_id = ?, pay_time = ? WHERE orderId = ? AND state = 0'
            const result = await db.query(sql, [type, trade_no, time, out_trade_no])

            if (result.affectedRows > 0) {
                // 查询订单与商品信息
                sql = `
                    SELECT 
                        g.lepao_count,
                        g.ic_count,
                        g.vip,
                        a.create_user
                    FROM 
                        orders a
                    LEFT JOIN 
                        goods g 
                    ON 
                        a.goods_id = g.id
                    WHERE 
                        a.orderId = ?
                `
                const rows = await db.query(sql, [out_trade_no])
                if (!rows || rows.length !== 1) {
                    this.logger.error(`订单商品信息异常，订单号：${out_trade_no}`)
                    await db.query('UPDATE orders SET state = 4 WHERE orderId = ?', [out_trade_no])
                    return res.send('fail')
                }

                const { lepao_count, ic_count, vip, create_user } = rows[0]

                // 更新用户剩余次数
                sql = 'UPDATE users SET lepao_count = lepao_count + ?, ic_count = ic_count + ?, vip = ? WHERE uuid = ?'
                const updateUser = await db.query(sql, [lepao_count, ic_count, vip, create_user])
                if (!updateUser || updateUser.affectedRows !== 1) {
                    this.logger.error(`更新用户失败，UUID: ${create_user}`)
                    await db.query('UPDATE orders SET state = 4 WHERE orderId = ?', [out_trade_no])
                    return res.send('fail')
                }

                sql = 'UPDATE orders SET state = 2 WHERE orderId = ?'
                await db.query(sql, [out_trade_no])

                this.logger.info(`支付成功，订单处理完毕。订单号：${out_trade_no}`)

                return res.send('success')
            } else {
                this.logger.warn(`订单不存在或已处理，订单号：${out_trade_no}`)
                return res.send('订单不存在或已处理')
            }
        } catch (err) {
            this.logger.error(`支付回调处理异常：${err.stack}`)
            return res.send('服务器错误')
        }
    }
}

module.exports.CallBack = CallBack
