const API = require("../../../lib/API")
const db = require("../../../plugin/DataBase/db")
const AccessControl = require("../../../lib/AccessControl")
const { BaseStdResponse } = require("../../../BaseStdResponse")
const EmailTemplate = require("../../../plugin/Email/emailTemplate")
const { insertLedgerRecord } = require("../../../lib/Lepao/CountLedger")

class RejectSendCountRequest extends API {
    constructor() {
        super()
        this.setPath("/Admin/Goods/SendCountRequest/Reject")
        this.setMethod("POST")
    }

    async onRequest(req, res) {
        let { uuid, session, id, reject_reason } = req.body
        id = Number(id)
        reject_reason = typeof reject_reason === "string" ? reject_reason.trim() : ""

        if ([uuid, session, id].some(value => value === "" || value === null || value === undefined || Number.isNaN(id)))
            return res.json({ ...BaseStdResponse.MISSING_PARAMETER })

        if (!Number.isInteger(id) || id <= 0)
            return res.json({ ...BaseStdResponse.ERR, msg: "参数错误" })

        if (reject_reason.length > 255)
            return res.json({ ...BaseStdResponse.ERR, msg: "拒绝原因过长，请控制在255字以内！" })

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

        if (!await AccessControl.canAccess(uuid, ['action.goods.reviewSendCount']))
            return res.json({ ...BaseStdResponse.PERMISSION_DENIED })

        const conn = await db.connect()
        try {
            await conn.beginTransaction()

            const [requestRows] = await conn.execute(
                `SELECT id, sender_uuid, receiver_user_id, count, status
                 FROM lepao_send_count_request
                 WHERE id = ?
                 FOR UPDATE`,
                [id]
            )

            if (!requestRows || requestRows.length !== 1) {
                await conn.rollback()
                return res.json({ ...BaseStdResponse.MISSING_FILE, msg: "未找到赠送申请记录！" })
            }

            const request = requestRows[0]
            if (request.status !== "pending") {
                await conn.rollback()
                return res.json({ ...BaseStdResponse.ERR, msg: "该申请已审核，请刷新后重试！" })
            }

            const [senderRows] = await conn.execute(
                "SELECT lepao_count FROM users WHERE uuid = ? FOR UPDATE",
                [request.sender_uuid]
            )
            if (!senderRows || senderRows.length !== 1) {
                await conn.rollback()
                return res.json({ ...BaseStdResponse.ERR, msg: "赠送人不存在，退回次数失败！" })
            }
            const beforeCount = Number(senderRows[0].lepao_count || 0)

            const [refundResult] = await conn.execute(
                "UPDATE users SET lepao_count = lepao_count + ? WHERE uuid = ?",
                [request.count, request.sender_uuid]
            )
            if (!refundResult || refundResult.affectedRows !== 1) {
                await conn.rollback()
                return res.json({ ...BaseStdResponse.ERR, msg: "赠送人不存在，退回次数失败！" })
            }

            const [updateResult] = await conn.execute(
                `UPDATE lepao_send_count_request
                 SET status = 'rejected', reviewer_uuid = ?, reviewed_at = NOW(), reject_reason = ?
                 WHERE id = ?`,
                [uuid, reject_reason || null, id]
            )
            if (!updateResult || updateResult.affectedRows !== 1) {
                await conn.rollback()
                return res.json({ ...BaseStdResponse.ERR, msg: "更新审核状态失败，请稍后再试！" })
            }

            await insertLedgerRecord({
                executor: conn,
                userUuid: request.sender_uuid,
                delta: Number(request.count || 0),
                balanceBefore: beforeCount,
                balanceAfter: beforeCount + Number(request.count || 0),
                bizType: 'gift_send_refund',
                bizId: `send_request:${id}`,
                operatorUuid: uuid,
                remark: reject_reason || ''
            })

            await conn.commit()
            const requestId = request.id
            const reviewTime = new Date().getTime()

            // 非阻塞通知赠送人，不影响审核结果
            Promise.resolve().then(async () => {
                try {
                    const infoSql = `
                        SELECT
                            su.email AS sender_email,
                            su.username AS sender_username,
                            ru.username AS receiver_username
                        FROM users su
                        LEFT JOIN users ru ON ru.id = ?
                        WHERE su.uuid = ?
                    `
                    const infoRows = await db.query(infoSql, [request.receiver_user_id, request.sender_uuid])
                    if (!infoRows || infoRows.length !== 1 || !infoRows[0].sender_email) {
                        this.logger.warn(`[SendCountNotify][reject][requestId=${requestId}] 赠送人邮箱为空或用户不存在，跳过通知`)
                        return
                    }

                    await EmailTemplate.sendCountRequestRejected(infoRows[0].sender_email, {
                        requestId,
                        receiverUsername: infoRows[0].receiver_username || "未知用户",
                        count: request.count,
                        reviewTime,
                        rejectReason: reject_reason || "无"
                    })
                } catch (mailErr) {
                    this.logger.error(`[SendCountNotify][reject][requestId=${requestId}] 赠送人通知发送失败：${mailErr.message || "未知错误"}`)
                }
            })

            return res.json({ ...BaseStdResponse.OK, msg: "已拒绝该赠送申请" })
        } catch (err) {
            try { await conn.rollback() } catch (_) { }
            this.logger.error(`拒绝赠送申请失败！${err.message || "未知错误"}`)
            return res.json({ ...BaseStdResponse.ERR, msg: "拒绝申请失败，请稍后再试！" })
        } finally {
            if (conn?.connection && typeof conn.connection.release === 'function' && typeof conn?.release === 'function') {
                conn.release()
            }
        }
    }
}

module.exports.RejectSendCountRequest = RejectSendCountRequest
