<?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="study.orderflow.mapper.OrderMapper">

  <select id="findStock" resultType="map">
    SELECT id, tenant, sku, available, unit_price, version
    FROM stock
    WHERE tenant = #{tenant} AND sku = #{sku}
  </select>

  <!-- 原子条件扣减：WHERE 同时裁决租户、SKU 与库存充足性，单条 UPDATE 原子完成 -->
  <update id="deductStock">
    UPDATE stock
    SET available = available - #{quantity}, version = version + 1
    WHERE tenant = #{tenant} AND sku = #{sku} AND available &gt;= #{quantity}
  </update>

  <insert id="insertOrder">
    INSERT INTO orders (tenant, sku, quantity, amount, status, idempotency_key)
    VALUES (#{tenant}, #{sku}, #{quantity}, #{amount}, 'CREATED', #{idempotencyKey})
  </insert>

  <!-- 幂等记录与业务效果同事务；uk_idem 唯一约束裁决重复 -->
  <insert id="insertIdempotency">
    INSERT INTO order_idempotency (idempotency_key, tenant, request_hash)
    VALUES (#{idempotencyKey}, #{tenant}, #{requestHash})
  </insert>

  <update id="linkIdempotencyToOrder">
    UPDATE order_idempotency
    SET order_id = #{orderId}
    WHERE idempotency_key = #{idempotencyKey} AND tenant = #{tenant}
  </update>

  <select id="findIdempotency" resultType="map">
    SELECT idempotency_key, tenant, request_hash, order_id
    FROM order_idempotency
    WHERE idempotency_key = #{idempotencyKey} AND tenant = #{tenant}
  </select>

  <select id="findOrder" resultType="map">
    SELECT id, tenant, sku, quantity, amount, status, idempotency_key
    FROM orders
    WHERE id = #{id} AND tenant = #{tenant}
  </select>

  <select id="findOrderByKey" resultType="map">
    SELECT id, tenant, sku, quantity, amount, status, idempotency_key
    FROM orders
    WHERE idempotency_key = #{idempotencyKey} AND tenant = #{tenant}
  </select>

  <!-- U80：发布意图与订单同事务；event_id 唯一 -->
  <insert id="insertOutbox">
    INSERT INTO outbox (event_id, aggregate_id, aggregate_version, payload, state, available_at, claim_version)
    VALUES (#{eventId}, #{aggregateId}, #{aggregateVersion}, #{payload}, 'PENDING', NOW(6), 0)
  </insert>

  <select id="countOrders" resultType="int">
    SELECT COUNT(*) FROM orders WHERE tenant = #{tenant}
  </select>
</mapper>
