<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.spot.mapper.AccountMapper">

    <!-- 撤单退币：从冻结余额(cold_money)扣除，增加到可用余额(hot_money)，使用 WHERE 条件防并发 -->
    <update id="refundFromFrozenToAvailable">
        UPDATE account
        SET hot_money   = hot_money + #{refundAmount},
            cold_money  = cold_money - #{refundAmount},
            mtime       = now()
        WHERE id = #{accountId}
          AND cold_money >= #{refundAmount}
    </update>

    <!-- 扣除冻结余额 -->
    <update id="deductFrozenBalance">
        UPDATE account
        SET cold_money = cold_money - #{frozenAmount},
            mtime      = now()
        WHERE id = #{accountId}
          AND cold_money >= #{frozenAmount}
    </update>

    <!-- 增加可用余额 -->
    <update id="addAvailableBalance">
        UPDATE account
        SET hot_money = hot_money + #{availableAmount},
            mtime     = now()
        WHERE id = #{accountId}
    </update>

    <!-- 增加冻结余额 -->
    <update id="addFrozenBalance">
        UPDATE account
        SET cold_money = cold_money + #{frozenAmount},
            mtime      = now()
        WHERE id = #{accountId}
    </update>

    <!-- 冻结金额：从可用余额(hot_money)扣除，增加到冻结余额(cold_money)，使用 WHERE 条件防超扣 -->
    <update id="freezeFromAvailableToFrozen">
        UPDATE account
        SET hot_money  = hot_money - #{freezeAmount},
            cold_money = cold_money + #{freezeAmount},
            mtime      = now()
        WHERE id = #{accountId}
          AND hot_money >= #{freezeAmount}
    </update>

    <!-- 扣除可用余额 -->
    <update id="deductAvailableBalance">
        UPDATE account
        SET hot_money = hot_money - #{availableAmount},
            mtime     = now()
        WHERE id = #{accountId}
          AND hot_money >= #{availableAmount}
    </update>

    <!-- 从可用余额转到提现余额：hot_money 扣除，withdraw_money 增加 -->
    <update id="freezeFromAvailableToWithdraw">
        UPDATE account
        SET hot_money       = hot_money - #{withdrawAmount},
            withdraw_money  = withdraw_money + #{withdrawAmount},
            mtime           = now()
        WHERE id = #{accountId}
          AND hot_money >= #{withdrawAmount}
    </update>

    <!-- 初始化现货账户（INSERT IGNORE：账户已存在时静默跳过，并发安全） -->
    <insert id="insertOrIgnore">
        INSERT IGNORE INTO account (uid, symbol, hot_money, cold_money, withdraw_money, ctime, mtime)
        VALUES (#{uid}, #{symbol}, 0, 0, 0, now(), now())
    </insert>

    <!--
        查询有冻结余额但无对应活跃委托的孤悬账户
        逻辑：
          - BUY 委托冻结计价货币（quote），如 BTCUSDT 买单冻结 USDT
          - SELL 委托冻结基础货币（base），如 BTCUSDT 卖单冻结 BTC
          - 活跃委托状态：INIT(0)、NEW(1)、PART_FILLED(3)、PENDING_CANCEL(5)
        NOT EXISTS 子查询：找不到任何可以解释该账户冻结余额的活跃委托，则视为孤悬
    -->
    <select id="findFrozenAccountsWithoutOrders" resultType="com.spot.entity.Account">
        SELECT a.*
        FROM account a
        WHERE a.cold_money > 0
          AND NOT EXISTS (
            SELECT 1
            FROM ex_order o
            JOIN config_symbol cs ON cs.symbol = o.symbol
            WHERE o.user_id = a.uid
              AND o.status IN (0, 1, 3, 5)
              AND (
                    (o.side = 'BUY'  AND cs.quote = a.symbol)
                 OR (o.side = 'SELL' AND cs.base  = a.symbol)
              )
          )
        LIMIT #{batchSize}
    </select>

</mapper>
