<?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.ylx.massage.mapper.CouponReceiveMapper">

    <resultMap id="CouponReceiveVoMap" type="com.ylx.massage.domain.vo.CouponReceiveVo">
        <result property="id" column="id" jdbcType="VARCHAR"/>
        <result property="openid" column="receive_open_id" jdbcType="VARCHAR"/>
        <result property="couponId" column="coupon_id" jdbcType="VARCHAR"/>
        <result property="couponName" column="coupon_name" jdbcType="VARCHAR"/>
        <result property="couponType" column="coupon_type" jdbcType="INTEGER"/>
        <result property="validityType" column="validity_type" jdbcType="INTEGER"/>
        <result property="validStartTime" column="valid_start_time" jdbcType="TIMESTAMP"/>
        <result property="expirationTime" column="expiration_time" jdbcType="TIMESTAMP"/>
        <result property="marketPrice" column="market_price" jdbcType="DECIMAL"/>
        <result property="ruleMinSpendAmount" column="rule_min_spend_amount" jdbcType="DECIMAL"/>
        <result property="ruleDiscountRate" column="rule_discount_rate" jdbcType="DECIMAL"/>
        <result property="ruleDiscountCapAmount" column="rule_discount_cap_amount" jdbcType="DECIMAL"/>
        <result property="ruleDiscountRateAmount" column="rule_reduction_amount" jdbcType="DECIMAL"/>
        <result property="country" column="country" jdbcType="VARCHAR"/>
        <result property="countryAll" column="country_all" jdbcType="VARCHAR"/>
        <result property="locality" column="locality" jdbcType="VARCHAR"/>
        <result property="merchantId" column="merchant_id" jdbcType="VARCHAR"/>
        <result property="storeName" column="store_name" jdbcType="VARCHAR"/>
        <result property="relatedType" column="related_type" jdbcType="VARCHAR"/>
        <result property="relatedId" column="related_id" jdbcType="VARCHAR"/>
        <result property="relatedName" column="related_name" jdbcType="VARCHAR"/>
    </resultMap>

    <sql id="selectCouponReceiveVo">
        distinct a.id, a.receive_open_id, a.coupon_id, b.coupon_name,a.coupon_type,a.validity_type,a.valid_start_time,a.expiration_time,a.coupon_status,b.market_price,a.create_time, a.update_time, a.is_delete,
  b.rule_min_spend_amount,b.rule_discount_rate,b.rule_discount_cap_amount,b.rule_reduction_amount,b.country,b.country_all,b.locality,b.related_type,b.related_id,b.related_name
    </sql>

    <!-- 批量插入 -->
    <insert id="insertBatch" keyProperty="id">
        insert into coupon_receive(id,openid,coupon_id,expiration_time,dept_id,dept_name)
        values
        <foreach collection="entities" item="entity" separator=",">
            (#{entity.id},#{entity.openid},#{entity.couponId},#{entity.expirationTime},#{entity.deptId},#{entity.deptName})
        </foreach>
    </insert>
    <!-- 批量插入或按主键更新 -->
    <insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">
        insert into coupon_receive(openid,coupon_id,expiration_time,dept_id,dept_name,create_time,update_time,is_delete)
        values
        <foreach collection="entities" item="entity" separator=",">
            (#{entity.openid},#{entity.couponId},#{entity.expirationTime},#{entity.deptId},#{entity.deptName},#{entity.createTime},#{entity.updateTime},#{entity.isDelete})
        </foreach>
        on duplicate key update
        openid = values(openid),
        coupon_id = values(coupon_id),
        expiration_time = values(expiration_time),
        dept_id = values(dept_id),
        dept_name = values(dept_name),
        create_time = values(create_time),
        update_time = values(update_time),
        is_delete = values(is_delete)
    </insert>


    <!-- 查询我的待使用的优惠券 -->
    <!--<select id="getByOpenId" resultMap="CouponReceiveVoMap">
        SELECT
            <include refid="selectCouponReceiveVo"/>
        FROM coupon_receive a
        LEFT JOIN coupon b ON a.coupon_id = b.id
        WHERE a.is_delete = 0
          AND b.is_delete = 0
          AND a.use_state = 0
          and a.expiration_time &gt;= now()
          and a.openid = #{openid}
    </select>-->

    <select id="getByOpenId" resultMap="CouponReceiveVoMap">
        SELECT
        <include refid="selectCouponReceiveVo"/>
        FROM coupon_receive a
        LEFT JOIN user_coupon_relation b ON a.coupon_id = b.coupon_id and b.open_id = a.receive_open_id
        WHERE a.is_delete = 0
        and a.receive_open_id = #{openid}
    </select>

    <!-- 1. 核销优惠券 (乐观锁) -->
    <update id="useCouponOptimisticLock">
        UPDATE coupon_receive
        SET coupon_status = 2,
        use_time = #{useTime},
        order_id = #{orderId},
        order_type = #{orderType},
        update_time = NOW()
        WHERE coupon_id = #{couponId}
        AND receive_open_id = #{openId}
        AND coupon_status = 0  <!-- 核心：只有状态为 0(待使用) 才能被更新 -->
        AND is_delete = 0
    </update>

    <!-- 2. 优惠券规则表使用数量 +1 -->
    <update id="incrementUsedNum">
        UPDATE coupon
        SET used_num = used_num + 1,
            update_time = NOW()
        WHERE id = #{couponId}
          AND is_delete = 0
    </update>

    <!-- 3. 退还优惠券 (乐观锁) -->
    <update id="returnCouponOptimisticLock">
        UPDATE coupon_receive
        SET coupon_status = 0,
        use_time = NULL,
        order_id = NULL,
        order_type = NULL,
        update_time = NOW()
        WHERE coupon_id = #{couponId}
        AND receive_open_id = #{openId}
        AND order_id = #{orderId} <!-- 核心：必须匹配原订单，防止退错 -->
        AND coupon_status = 2     <!-- 核心：只有状态为 2(已使用) 才能退回 -->
        AND is_delete = 0
    </update>

    <!-- 4. 优惠券规则表使用数量 -1 -->
    <update id="decrementUsedNum">
        UPDATE coupon
        SET used_num = used_num - 1,
        update_time = NOW()
        WHERE id = #{couponId}
        AND used_num > 0  <!-- 核心防御：防止减为负数 -->
        AND is_delete = 0
    </update>

    <!-- 查询优惠券领取详情 -->
    <select id="selectCouponDetailForCalc" resultType="java.util.Map">
        SELECT
        cr.id,
        cr.coupon_status,
        cr.valid_start_time,
        cr.expiration_time,
        c.discount_type,
        c.discount_value,
        c.reb_value,
        c.threshold_amount
        FROM coupon_receive cr
        JOIN coupon c ON cr.coupon_id = c.id
        <where>
            cr.is_delete = 0
            AND c.is_delete = 0
            <if test="couponId != null and couponId != ''">
                AND cr.coupon_id = #{couponId}
            </if>
            <if test="openId != null and openId != ''">
                AND cr.receive_open_id = #{openId}
            </if>
        </where>
        LIMIT 1
    </select>

</mapper>

