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 SendCount extends API {
    constructor() {
        super()
        this.setPath("/Goods/SendCount")
        this.setMethod("POST")
    }

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

        count = Math.round(count * 100) / 100

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

        if (count <= 0 || count > 9999)
            return res.json({ ...BaseStdResponse.ERR, msg: "超出赠送的里程范围，请重新选择赠送公里数" })

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


        const conn = await db.connect() // 这里直接拿 connection
        try {
            await conn.beginTransaction()

            const [senderRows] = await conn.execute(
                "SELECT id, username, lepao_count, COALESCE(send_count_auto_approve, 0) AS send_count_auto_approve FROM users WHERE uuid = ?",
                [uuid]
            )
            if (!senderRows || senderRows.length !== 1) {
                await conn.rollback()
                return res.json({ ...BaseStdResponse.MISSING_FILE, msg: "获取用户信息失败！" })
            }

            const [targetRows] = await conn.execute(
                "SELECT id, uuid FROM users WHERE username = ?",
                [username]
            )
            if (!targetRows || targetRows.length !== 1) {
                await conn.rollback()
                return res.json({ ...BaseStdResponse.ERR, msg: "未找到接收用户，请检查用户名是否正确！" })
            }
            if (targetRows[0].uuid === uuid) {
                await conn.rollback()
                return res.json({ ...BaseStdResponse.ERR, msg: "不能给自己赠送里程！" })
            }

            const [decResult] = await conn.execute(
                "UPDATE users SET lepao_count = lepao_count - ? WHERE uuid = ? AND lepao_count >= ?",
                [count, uuid, count]
            )
            if (decResult.affectedRows !== 1) {
                await conn.rollback()
                return res.json({ ...BaseStdResponse.ERR, msg: "剩余乐跑里程不足，请购买后再赠送！" })
            }

            const senderLepaoBefore = Number(senderRows[0].lepao_count || 0)
            const autoApprove = Number(senderRows[0].send_count_auto_approve) === 1

            if (autoApprove) {
                const [recvRows] = await conn.execute(
                    "SELECT uuid, lepao_count FROM users WHERE id = ? FOR UPDATE",
                    [targetRows[0].id]
                )
                if (!recvRows || recvRows.length !== 1) {
                    await conn.rollback()
                    return res.json({ ...BaseStdResponse.ERR, msg: "未找到接收用户，请检查用户名是否正确！" })
                }
                const receiverUuid = recvRows[0].uuid
                const beforeRecv = Number(recvRows[0].lepao_count || 0)

                const [incResult] = await conn.execute(
                    "UPDATE users SET lepao_count = lepao_count + ? WHERE id = ?",
                    [count, targetRows[0].id]
                )
                if (!incResult || incResult.affectedRows !== 1) {
                    await conn.rollback()
                    return res.json({ ...BaseStdResponse.ERR, msg: "接收方入账失败，请稍后再试！" })
                }

                const [insertResult] = await conn.execute(
                    `INSERT INTO lepao_send_count_request
                    (sender_uuid, receiver_user_id, count, status, created_at, reviewed_at, reviewer_uuid)
                    VALUES (?, ?, ?, 'approved', NOW(), NOW(), NULL)`,
                    [uuid, targetRows[0].id, count]
                )
                if (!insertResult || insertResult.affectedRows !== 1) {
                    await conn.rollback()
                    return res.json({ ...BaseStdResponse.ERR, msg: "记录赠送失败，请稍后再试！" })
                }

                const requestId = insertResult.insertId
                await insertLedgerRecord({
                    executor: conn,
                    userUuid: uuid,
                    delta: -count,
                    balanceBefore: senderLepaoBefore,
                    balanceAfter: senderLepaoBefore - count,
                    bizType: "gift_send_lock",
                    bizId: `send_request:${requestId}`,
                    remark: `向${username}赠送${count}公里`
                })
                await insertLedgerRecord({
                    executor: conn,
                    userUuid: receiverUuid,
                    delta: count,
                    balanceBefore: beforeRecv,
                    balanceAfter: beforeRecv + count,
                    bizType: "gift_receive",
                    bizId: `send_request:${requestId}`,
                    operatorUuid: null,
                    remark: `${senderRows[0].username}赠送${count}公里`
                })

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

                Promise.resolve().then(async () => {
                    try {
                        const infoSql = `
                            SELECT ru.email AS receiver_email, ru.username AS receiver_username
                            FROM users ru
                            WHERE ru.id = ?
                        `
                        const infoRows = await db.query(infoSql, [targetRows[0].id])
                        if (!infoRows || infoRows.length !== 1 || !infoRows[0].receiver_email) {
                            this.logger.warn(`[SendCountNotify][auto][requestId=${requestId}] 接收人邮箱为空，跳过通知`)
                            return
                        }
                        await EmailTemplate.sendCountRequestApproved(infoRows[0].receiver_email, {
                            requestId,
                            senderUsername: senderRows[0].username,
                            count,
                            reviewTime
                        })
                    } catch (mailErr) {
                        this.logger.error(`[SendCountNotify][auto][requestId=${requestId}] 接收人通知发送失败：${mailErr.message || "未知错误"}`)
                    }
                })

                return res.json({ ...BaseStdResponse.OK, msg: "赠送成功，对方已到账" })
            }

            const [insertResult] = await conn.execute(
                `INSERT INTO lepao_send_count_request
                (sender_uuid, receiver_user_id, count, status, created_at)
                VALUES (?, ?, ?, 'pending', NOW())`,
                [uuid, targetRows[0].id, count]
            )
            if (!insertResult || insertResult.affectedRows !== 1) {
                await conn.rollback()
                return res.json({ ...BaseStdResponse.ERR, msg: "提交赠送审核失败，请稍后再试！" })
            }

            const requestId = insertResult.insertId
            await insertLedgerRecord({
                executor: conn,
                userUuid: uuid,
                delta: -count,
                balanceBefore: senderLepaoBefore,
                balanceAfter: senderLepaoBefore - count,
                bizType: "gift_send_lock",
                bizId: `send_request:${requestId}`,
                remark: `向${username}赠送${count}次`
            })
            await conn.commit()
            const createTime = new Date().getTime()

            // 非阻塞通知管理员，不影响主业务流程
            Promise.resolve().then(async () => {
                try {
                    const adminSql = `
                        SELECT email
                        FROM users
                        WHERE email IS NOT NULL
                          AND email <> ''
                          AND (JSON_CONTAINS(permission, '"admin"') OR JSON_CONTAINS(permission, '"service"'))
                    `
                    const adminRows = await db.query(adminSql)
                    if (!adminRows || adminRows.length === 0) {
                        this.logger.warn(`[SendCountNotify][submit][requestId=${requestId}] 未找到可通知的管理员邮箱`)
                        return
                    }

                    const emails = [...new Set(adminRows.map(row => row.email).filter(Boolean))]
                    for (const email of emails) {
                        await EmailTemplate.sendCountRequestNotifyAdmins(email, {
                            requestId,
                            senderUsername: senderRows[0].username,
                            receiverUsername: username,
                            count,
                            createTime
                        })
                    }
                } catch (mailErr) {
                    this.logger.error(`[SendCountNotify][submit][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.SendCount = SendCount
