const crypto = require('crypto')
const db = require('../plugin/DataBase/db')

function generateGatewayOrderNo(orderId) {
    const suffix = `${Date.now().toString(36)}${crypto.randomBytes(3).toString('hex')}`
    return `${String(orderId).slice(0, 40)}P${suffix}`
}

function normalizeResult(result) {
    return Array.isArray(result) ? result[0] : result
}

async function executeSql(executor, sql, params) {
    if (executor && typeof executor.execute === 'function') return executor.execute(sql, params)
    return db.query(sql, params)
}

async function createPaymentAttempt({ orderId, payType, gatewayOrderNo = generateGatewayOrderNo(orderId), executor = null }) {
    const result = await executeSql(
        executor,
        'INSERT INTO order_payment_attempts (gateway_order_no, order_id, pay_type, create_time) VALUES (?, ?, ?, ?)',
        [gatewayOrderNo, orderId, payType, Date.now()]
    )
    if (!normalizeResult(result)?.affectedRows) throw new Error('保存支付尝试失败')
    return gatewayOrderNo
}

async function resolveBusinessOrderId(gatewayOrderNo) {
    const rows = await db.query(
        'SELECT order_id FROM order_payment_attempts WHERE gateway_order_no = ? LIMIT 1',
        [gatewayOrderNo]
    )
    return rows?.[0]?.order_id || gatewayOrderNo
}

async function getLatestGatewayOrderNo(orderId) {
    const rows = await db.query(
        'SELECT gateway_order_no FROM order_payment_attempts WHERE order_id = ? ORDER BY create_time DESC LIMIT 1',
        [orderId]
    )
    return rows?.[0]?.gateway_order_no || orderId
}

async function getGatewayOrderNos(orderId) {
    const rows = await db.query(
        'SELECT gateway_order_no FROM order_payment_attempts WHERE order_id = ? ORDER BY create_time DESC',
        [orderId]
    )
    const values = (rows || [])
        .map(row => row.gateway_order_no)
        .filter(Boolean)
    if (!values.includes(orderId)) values.push(orderId)
    return values
}

module.exports = {
    generateGatewayOrderNo,
    createPaymentAttempt,
    resolveBusinessOrderId,
    getLatestGatewayOrderNo,
    getGatewayOrderNos
}
