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

function roundMoney(n) {
    return Math.round(Number(n) * 100) / 100
}

function calcDiscount(price, discountType, discountValue) {
    const p = Number(price)
    let discount = 0
    if (discountType === 'percent') {
        const pct = Math.min(100, Math.max(0, Number(discountValue)))
        discount = roundMoney((p * pct) / 100)
    } else {
        discount = roundMoney(Math.min(p, Math.max(0, Number(discountValue))))
    }
    let finalPrice = roundMoney(p - discount)
    if (finalPrice < 0.01) finalPrice = 0.01
    if (finalPrice > p) finalPrice = p
    discount = roundMoney(p - finalPrice)
    return { discountAmount: discount, finalPrice }
}

async function countActiveUsage(couponId, userUuid) {
    const totalRows = await db.query(
        `SELECT COUNT(*) AS cnt FROM coupon_usage
         WHERE coupon_id = ?`,
        [couponId]
    )
    const userRows = await db.query(
        `SELECT COUNT(*) AS cnt FROM coupon_usage
         WHERE coupon_id = ? AND user_uuid = ?`,
        [couponId, userUuid]
    )
    return {
        total: Number(totalRows?.[0]?.cnt || 0),
        perUser: Number(userRows?.[0]?.cnt || 0)
    }
}

/**
 * 校验优惠码并计算优惠后价格
 */
async function validateCoupon({ code, userUuid, goodsId, goodsPrice }) {
    const normalizedCode = String(code || '').trim().toUpperCase()
    if (!normalizedCode) {
        return { ok: false, msg: '请输入优惠码' }
    }

    const rows = await db.query(
        `SELECT * FROM coupons WHERE code = ? AND state = 1 LIMIT 1`,
        [normalizedCode]
    )
    if (!rows || rows.length !== 1) {
        return { ok: false, msg: '优惠码不存在或已失效' }
    }

    const coupon = rows[0]
    const now = Date.now()

    if (coupon.start_time && now < Number(coupon.start_time)) {
        return { ok: false, msg: '优惠码尚未生效' }
    }
    if (coupon.end_time && now > Number(coupon.end_time)) {
        return { ok: false, msg: '优惠码已过期' }
    }

    const price = Number(goodsPrice)
    const minAmount = Number(coupon.min_amount || 0)
    if (minAmount > 0 && price < minAmount) {
        return { ok: false, msg: `订单满 ¥${minAmount} 才可使用该优惠码` }
    }

    if (Number(coupon.goods_scope) === 1) {
        const goodsRows = await db.query(
            'SELECT 1 FROM coupon_goods WHERE coupon_id = ? AND goods_id = ? LIMIT 1',
            [coupon.id, goodsId]
        )
        if (!goodsRows || goodsRows.length === 0) {
            return { ok: false, msg: '该优惠码不适用于当前商品' }
        }
    }

    if (Number(coupon.user_scope) === 1) {
        const userRows = await db.query(
            'SELECT 1 FROM coupon_users WHERE coupon_id = ? AND user_uuid = ? LIMIT 1',
            [coupon.id, userUuid]
        )
        if (!userRows || userRows.length === 0) {
            return { ok: false, msg: '您暂无使用该优惠码的权限' }
        }
    }

    const usage = await countActiveUsage(coupon.id, userUuid)
    const totalLimit = Number(coupon.total_limit || 0)
    const perUserLimit = Number(coupon.per_user_limit || 1)

    if (totalLimit > 0 && usage.total >= totalLimit) {
        return { ok: false, msg: '优惠码已达使用上限' }
    }
    if (usage.perUser >= perUserLimit) {
        return { ok: false, msg: '您已达到该优惠码的使用次数上限' }
    }

    const { discountAmount, finalPrice } = calcDiscount(
        price,
        coupon.discount_type,
        coupon.discount_value
    )

    if (discountAmount <= 0) {
        return { ok: false, msg: '优惠码无效，未产生优惠' }
    }

    return {
        ok: true,
        couponId: coupon.id,
        code: coupon.code,
        name: coupon.name,
        discountType: coupon.discount_type,
        discountValue: Number(coupon.discount_value),
        originalPrice: roundMoney(price),
        discountAmount,
        finalPrice,
        displayDiscount:
            coupon.discount_type === 'percent'
                ? `${coupon.discount_value}% 折扣`
                : `立减 ¥${coupon.discount_value}`
    }
}

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

async function recordUsage(couponId, orderId, userUuid, discountAmount, executor = null) {
    const time = Date.now()
    await executeSql(
        executor,
        `INSERT INTO coupon_usage (coupon_id, order_id, user_uuid, discount_amount, create_time)
         VALUES (?, ?, ?, ?, ?)`,
        [couponId, orderId, userUuid, discountAmount, time]
    )
    await executeSql(executor, 'UPDATE coupons SET used_count = used_count + 1 WHERE id = ?', [couponId])
}

async function releaseUsageForOrder(orderId) {
    const rows = await db.query(
        'SELECT coupon_id FROM orders WHERE orderId = ? AND coupon_id IS NOT NULL LIMIT 1',
        [orderId]
    )
    if (!rows || !rows[0]?.coupon_id) return

    const couponId = rows[0].coupon_id
    const del = await db.query('DELETE FROM coupon_usage WHERE order_id = ?', [orderId])
    if (del?.affectedRows > 0) {
        await db.query(
            'UPDATE coupons SET used_count = GREATEST(used_count - 1, 0) WHERE id = ?',
            [couponId]
        )
    }
}

module.exports = {
    roundMoney,
    calcDiscount,
    validateCoupon,
    recordUsage,
    releaseUsageForOrder
}
