const API = require('../../lib/API')
const db = require('../../plugin/DataBase/db')
const Redis = require('../../plugin/DataBase/Redis')
const { BaseStdResponse } = require('../../BaseStdResponse')
const AccessControl = require('../../lib/AccessControl')
const { buildPaymentSession } = require('../../lib/OrderPayment')
const { createPaymentAttempt, generateGatewayOrderNo } = require('../../lib/OrderPaymentAttempt')
const { enqueueOrderPaymentCheck } = require('../../plugin/mq/orderPaymentWorker')

class PayOrder extends API {
    constructor() {
        super()
        this.setPath('/Order/Pay')
        this.setMethod('POST')
    }

    async onRequest(req, res) {
        const { uuid, session, orderId, pay_type } = req.body
        if ([uuid, session, orderId, pay_type].some(v => v === '' || v === null || v === undefined)) {
            return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
        }
        if (!await AccessControl.checkSession(uuid, session)) {
            return res.status(401).json({ ...BaseStdResponse.ACCESS_DENIED })
        }

        try {
            const normalizedPayType = String(pay_type).trim()
            const rows = await db.query(`
                SELECT o.orderId, o.price, o.state, g.name
                FROM orders o
                LEFT JOIN goods g ON o.goods_id = g.id
                WHERE o.orderId = ? AND o.create_user = ?
                LIMIT 1
            `, [orderId, uuid])
            const order = rows?.[0]
            if (!order) {
                return res.json({ ...BaseStdResponse.ERR, msg: '订单不存在' })
            }
            if (Number(order.state) !== 0) {
                return res.json({ ...BaseStdResponse.ERR, msg: '仅待付款订单可更换支付方式' })
            }

            const gatewayOrderNo = generateGatewayOrderNo(order.orderId)
            const payment = await buildPaymentSession({
                orderId: order.orderId,
                gatewayOrderNo,
                payType: normalizedPayType,
                goodsName: order.name,
                price: order.price,
                deviceType: req.headers['device-type']
            })

            const updateRes = await db.query(
                'UPDATE orders SET pay_type = ? WHERE orderId = ? AND create_user = ? AND state = 0',
                [normalizedPayType, orderId, uuid]
            )
            if (!updateRes?.affectedRows) {
                return res.json({ ...BaseStdResponse.ERR, msg: '订单状态已变更，请刷新后重试' })
            }

            await createPaymentAttempt({
                orderId: order.orderId,
                payType: normalizedPayType,
                gatewayOrderNo
            })

            await Redis.set(`payData:${orderId}`, JSON.stringify(payment.payData), { EX: 300 })
            try {
                await enqueueOrderPaymentCheck(orderId)
            } catch (error) {
                this.logger.error(`投递订单支付检查消息失败，订单号：${orderId}，错误：${error.stack || error}`)
            }

            return res.json({ ...BaseStdResponse.OK, id: orderId, pay: payment })
        } catch (error) {
            this.logger.error(`发起订单支付失败，订单号：${orderId}，错误：${error.stack || error}`)
            return res.json({ ...BaseStdResponse.ERR, msg: error.message || '发起支付失败，请稍后重试' })
        }
    }
}

module.exports.PayOrder = PayOrder
