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

function generateOrderId() {
    const now = new Date()
    const pad = (n, w = 2) => n.toString().padStart(w, '0')
    return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}` +
        `${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}` +
        `${pad(now.getMilliseconds(), 3)}`
}

function generatePaymentSign(params, key) {
    const sorted = Object.keys(params).sort()
    const query = sorted.map(k => `${k}=${params[k]}`).join('&') + key

    return crypto.createHash('md5').update(query, 'utf8').digest('hex')
}

// async function getPayStatus(order_no) {
//     const endpoint = config.pay.url + '/api/findorder'
//     try {
//         const res = await axios.post(endpoint, {order_no, type: 1})

//     } catch (error) {

//     }
// }

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

    async onRequest(req, res) {
        const { uuid, session, goods_id, pay_type } = req.body

        if ([uuid, session, goods_id, pay_type].some(v => v === '' || v === null || v === undefined)) {
            return res.json({
                ...BaseStdResponse.MISSING_PARAMETER,
                endpoint: 1513126
            })
        }

        const sessionValid = await AccessControl.checkSession(uuid, session)
        if (!sessionValid) {
            return res.status(401).json({
                ...BaseStdResponse.ACCESS_DENIED
            })
        }

        try {
            const goodsSql = 'SELECT name, price, num, state FROM goods WHERE id = ?'
            const goodsRows = await db.query(goodsSql, [goods_id])

            if (!goodsRows || goodsRows.length !== 1) {
                return res.json({
                    ...BaseStdResponse.ERR,
                    msg: '商品不存在',
                    endpoint: 1513126
                })
            }

            const goods = goodsRows[0]
            if (goods.num < 1 || goods.state !== 1) {
                return res.json({
                    ...BaseStdResponse.ERR,
                    msg: '商品已下架或库存不足',
                    endpoint: 1513126
                })
            }

            const createTime = Date.now()
            const orderId = generateOrderId()

            const insertSql = `
                INSERT INTO orders (orderId, create_user, create_time, goods_id, price, pay_type)
                VALUES (?, ?, ?, ?, ?, ?)
            `
            const result = await db.query(insertSql, [
                orderId, uuid, createTime, goods_id, goods.price, pay_type
            ])

            const updateSql = 'UPDATE goods SET num = num - 1 WHERE id = ?'
            await db.query(updateSql, [goods_id])

            if (result && result.affectedRows > 0) {
                const paymentConfig = config.pay || {}

                if (!paymentConfig.pid || !paymentConfig.url || !paymentConfig.key || !paymentConfig.return_url) {
                    return res.json({
                        ...BaseStdResponse.ERR,
                        msg: '支付配置错误，请联系管理员'
                    })
                }

                const payParams = {
                    pid: paymentConfig.pid,
                    type: pay_type,
                    out_trade_no: orderId,
                    notify_url: `${config.url}/Order/CallBack`,
                    return_url: paymentConfig.return_url + orderId,
                    name: goods.name,
                    money: goods.price
                }

                const sign = generatePaymentSign(payParams, paymentConfig.key)
                payParams.sign = sign
                payParams.sign_type = 'MD5'

                await Redis.set(`payData:${orderId}`, JSON.stringify(payParams), {
                    EX: 300
                })

                res.json({
                    ...BaseStdResponse.OK,
                    id: orderId,
                    pay: {
                        payUrl: `${paymentConfig.url}/submit.php`,
                        payData: payParams
                    }
                })

                // 定时器轮询订单状态
                try {
                    // 定时轮询订单状态，最多持续5分钟（300秒），每次间隔5秒
                    const MAX_RETRIES = 60 // 5分钟 / 5秒
                    const DELAY = 5000 // 5秒

                    const queryUrl = `${paymentConfig.url}/api.php?act=order&pid=${paymentConfig.pid}&key=${paymentConfig.key}&out_trade_no=${orderId}`

                    const pollOrderStatus = async (retry = 0) => {
                        if (retry >= MAX_RETRIES) {
                            this.logger.info(`订单超时未支付，订单号：${orderId}`)
                            await db.query('UPDATE orders SET state = 3 WHERE orderId = ?', [orderId]);
                            return
                        }

                        try {
                            const queryRes = await axios.get(queryUrl)
                            const queryData = queryRes.data

                            if (queryData.code === 1 && queryData.status === 1) {
                                const { trade_no, out_trade_no, type } = queryData
                                const time = Date.now()

                                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
                                    }

                                    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])
                                    }

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

                                    this.logger.info(`订单处理成功：${out_trade_no}`)
                                    return // 成功处理后终止轮询
                                } else {
                                    this.logger.warn(`订单不存在或已处理：${out_trade_no}`)
                                }
                            }

                            // 未支付，继续轮询
                            setTimeout(() => pollOrderStatus(retry + 1), DELAY)

                        } catch (error) {
                            this.logger.warn(`轮询支付状态失败：${error.stack}`)
                            setTimeout(() => pollOrderStatus(retry + 1), DELAY)
                        }
                    }

                    // 启动轮询
                    pollOrderStatus()

                } catch {
                    this.logger.info(`获取订单支付状态失败！${error.stack}`)
                }

            } else {
                return res.json({
                    ...BaseStdResponse.ERR,
                    msg: '创建订单失败',
                    endpoint: 7894378
                })
            }
        } catch (err) {
            this.logger.error(`创建订单失败！${err.stack}`)
            return res.json({
                ...BaseStdResponse.ERR,
                msg: "创建订单异常，请联系管理员"
            })
        }
    }
}

module.exports.CreateOrder = CreateOrder
