<?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.microservices.zone.member.mapper.ZonePointsTransactionMapper">

    <resultMap type="ZonePointsTransaction" id="ZonePointsTransactionResult">
        <result property="id" column="id"/>
        <result property="eventId" column="event_id"/>
        <result property="eventType" column="event_type"/>
        <result property="accountId" column="account_id"/>
        <result property="transactionType" column="transaction_type"/>
        <result property="points" column="points"/>
        <result property="availableAfter" column="available_after"/>
        <result property="frozenAfter" column="frozen_after"/>
        <result property="operatorId" column="operator_id"/>
        <result property="reason" column="reason"/>
        <result property="replyContent" column="reply_content"/>
        <result property="sourceId" column="source_id"/>
        <result property="sourceData" column="source_data"/>
        <result property="subject" column="subject"/>
        <result property="subjectDesc" column="subject_desc"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>

    <sql id="selectZonePointsTransactionVo">
        select id, event_id, event_type, account_id, transaction_type, points,
               available_after, frozen_after, operator_id,
               reason, reply_content, source_id, source_data, subject, subject_desc,
               create_time, update_time
        from zone_points_transaction
    </sql>

    <sql id="selectZonePointsTransactionAliasVo">
        select zpt.id, zpt.event_id, zpt.event_type, zpt.account_id, zpt.transaction_type, zpt.points,
               zpt.available_after, zpt.frozen_after, zpt.operator_id,
               zpt.reason, zpt.reply_content, zpt.source_id, zpt.source_data,
               zpt.subject, zpt.subject_desc,
               zpt.create_time, zpt.update_time
        from zone_points_transaction zpt
    </sql>

    <select id="selectZonePointsTransactionList" parameterType="ZonePointsTransaction" resultMap="ZonePointsTransactionResult">
        <include refid="selectZonePointsTransactionAliasVo"/>
        <where>
            <if test="eventId != null and eventId != ''">and zpt.event_id = #{eventId}</if>
            <if test="eventType != null and eventType != ''">and zpt.event_type = #{eventType}</if>
            <if test="accountId != null">and zpt.account_id = #{accountId}</if>
            <if test="transactionType != null and transactionType != ''">and zpt.transaction_type = #{transactionType}</if>
            <if test="sourceId != null">and zpt.source_id = #{sourceId}</if>
            ${params.dataScope}
        </where>
        order by zpt.create_time desc
    </select>

    <select id="selectZonePointsTransactionById" parameterType="Long" resultMap="ZonePointsTransactionResult">
        <include refid="selectZonePointsTransactionVo"/>
        where id = #{id}
    </select>

    <select id="selectZonePointsTransactionByEventId" resultMap="ZonePointsTransactionResult">
        <include refid="selectZonePointsTransactionVo"/>
        where event_id = #{eventId}
        order by create_time desc
    </select>

    <select id="selectZonePointsTransactionByAccountId" resultMap="ZonePointsTransactionResult">
        <include refid="selectZonePointsTransactionVo"/>
        where account_id = #{accountId}
        order by create_time desc
    </select>

    <select id="selectZonePointsTransactionByUserIdAndZoneId" resultMap="ZonePointsTransactionResult">
        <include refid="selectZonePointsTransactionAliasVo"/>
        left join zone_points_account zpa on zpt.account_id = zpa.id
        where zpa.user_id = #{userId} and zpa.zone_id = #{zoneId}
        order by zpt.create_time desc
    </select>

    <select id="selectMyPointsTransactionDetailsByZone" resultMap="ZonePointsTransactionResult">
        <include refid="selectZonePointsTransactionAliasVo"/>
        left join zone_points_account zpa on zpt.account_id = zpa.id
        where zpa.user_id = #{userId} and zpa.zone_id = #{zoneId}
        <if test="transactionType != null and transactionType != ''">and zpt.transaction_type = #{transactionType}</if>
        order by zpt.create_time desc
    </select>

    <!-- 查询当前用户流水列表（合并后直接从流水表查询，无需 JOIN 事件表） -->
    <select id="selectCurrentUserTransactionWithEvent" resultMap="ZonePointsTransactionResult">
        <include refid="selectZonePointsTransactionAliasVo"/>
        left join zone_points_account zpa on zpt.account_id = zpa.id
        where zpa.user_id = #{userId} and zpa.zone_id = #{zoneId}
        order by zpt.create_time desc, zpt.id desc
    </select>

    <insert id="insertZonePointsTransaction" parameterType="ZonePointsTransaction" useGeneratedKeys="true" keyProperty="id">
        insert into zone_points_transaction
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="eventId != null and eventId != ''">event_id,</if>
            <if test="eventType != null and eventType != ''">event_type,</if>
            <if test="accountId != null">account_id,</if>
            <if test="transactionType != null and transactionType != ''">transaction_type,</if>
            <if test="points != null">points,</if>
            <if test="availableAfter != null">available_after,</if>
            <if test="frozenAfter != null">frozen_after,</if>
            <if test="operatorId != null">operator_id,</if>
            <if test="reason != null and reason != ''">reason,</if>
            <if test="replyContent != null and replyContent != ''">reply_content,</if>
            <if test="sourceId != null">source_id,</if>
            <if test="sourceData != null and sourceData != ''">source_data,</if>
            <if test="subject != null and subject != ''">subject,</if>
            <if test="subjectDesc != null and subjectDesc != ''">subject_desc,</if>
            <if test="createTime != null">create_time,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="eventId != null and eventId != ''">#{eventId},</if>
            <if test="eventType != null and eventType != ''">#{eventType},</if>
            <if test="accountId != null">#{accountId},</if>
            <if test="transactionType != null and transactionType != ''">#{transactionType},</if>
            <if test="points != null">#{points},</if>
            <if test="availableAfter != null">#{availableAfter},</if>
            <if test="frozenAfter != null">#{frozenAfter},</if>
            <if test="operatorId != null">#{operatorId},</if>
            <if test="reason != null and reason != ''">#{reason},</if>
            <if test="replyContent != null and replyContent != ''">#{replyContent},</if>
            <if test="sourceId != null">#{sourceId},</if>
            <if test="sourceData != null and sourceData != ''">#{sourceData},</if>
            <if test="subject != null and subject != ''">#{subject},</if>
            <if test="subjectDesc != null and subjectDesc != ''">#{subjectDesc},</if>
            <if test="createTime != null">#{createTime},</if>
        </trim>
    </insert>

    <update id="updateZonePointsTransaction" parameterType="ZonePointsTransaction">
        update zone_points_transaction
        <trim prefix="SET" suffixOverrides=",">
            <if test="eventId != null and eventId != ''">event_id = #{eventId},</if>
            <if test="eventType != null and eventType != ''">event_type = #{eventType},</if>
            <if test="accountId != null">account_id = #{accountId},</if>
            <if test="transactionType != null and transactionType != ''">transaction_type = #{transactionType},</if>
            <if test="points != null">points = #{points},</if>
            <if test="availableAfter != null">available_after = #{availableAfter},</if>
            <if test="frozenAfter != null">frozen_after = #{frozenAfter},</if>
            <if test="operatorId != null">operator_id = #{operatorId},</if>
            <if test="reason != null">reason = #{reason},</if>
            <if test="replyContent != null">reply_content = #{replyContent},</if>
            <if test="sourceId != null">source_id = #{sourceId},</if>
            <if test="sourceData != null">source_data = #{sourceData},</if>
            <if test="subject != null">subject = #{subject},</if>
            <if test="subjectDesc != null">subject_desc = #{subjectDesc},</if>
            update_time = now(),
        </trim>
        where id = #{id}
    </update>

    <delete id="deleteZonePointsTransactionById" parameterType="Long">
        delete from zone_points_transaction where id = #{id}
    </delete>

    <delete id="deleteZonePointsTransactionByIds" parameterType="String">
        delete from zone_points_transaction where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>

    <!-- ==================== 幂等校验（JOIN account 获取 userId/zoneId） ==================== -->

    <select id="countByEventTypeAndSourceAndUser" resultType="int">
        select count(*)
        from zone_points_transaction zpt
        where zpt.event_type = #{eventType}
          and zpt.source_id = #{sourceId}
          and zpt.account_id = #{accountId}
    </select>

    <select id="countByEventTypeAndZoneAndUser" resultType="int">
        select count(*)
        from zone_points_transaction zpt
        left join zone_points_account zpa on zpt.account_id = zpa.id
        where zpt.event_type = #{eventType}
          and zpa.zone_id = #{zoneId}
          and zpa.user_id = #{userId}
    </select>

    <select id="selectPointsTransactionOne" resultMap="ZonePointsTransactionResult">
        <include refid="selectZonePointsTransactionAliasVo"/>
        left join zone_points_account zpa on zpt.account_id = zpa.id
        where zpa.zone_id = #{zoneId}
          and zpa.user_id = #{userId}
          and zpt.event_type = #{eventType}
        order by zpt.create_time desc
        limit 1
    </select>

</mapper>