package com.erp.warehouse.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.erp.warehouse.entity.Stock;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

/**
 * 库存Mapper
 */
@Mapper
public interface StockMapper extends BaseMapper<Stock> {

    /**
     * 增加库存（乐观锁）
     */
    @Update("UPDATE stock SET quantity = quantity + #{quantity}, version = version + 1, update_time = NOW() " +
            "WHERE sku_code = #{skuCode} AND warehouse_id = #{warehouseId} AND version = #{version}")
    int incrementQuantity(@Param("skuCode") String skuCode, @Param("warehouseId") Long warehouseId,
                          @Param("quantity") Integer quantity, @Param("version") Integer version);

    /**
     * 减少库存（乐观锁）
     */
    @Update("UPDATE stock SET quantity = quantity - #{quantity}, version = version + 1, update_time = NOW() " +
            "WHERE sku_code = #{skuCode} AND warehouse_id = #{warehouseId} AND quantity >= #{quantity} AND version = #{version}")
    int decrementQuantity(@Param("skuCode") String skuCode, @Param("warehouseId") Long warehouseId,
                           @Param("quantity") Integer quantity, @Param("version") Integer version);

    /**
     * 增加锁定数量
     */
    @Update("UPDATE stock SET locked_quantity = locked_quantity + #{quantity}, version = version + 1, update_time = NOW() " +
            "WHERE sku_code = #{skuCode} AND warehouse_id = #{warehouseId} AND version = #{version}")
    int incrementLockedQuantity(@Param("skuCode") String skuCode, @Param("warehouseId") Long warehouseId,
                                 @Param("quantity") Integer quantity, @Param("version") Integer version);

    /**
     * 减少锁定数量
     */
    @Update("UPDATE stock SET locked_quantity = locked_quantity - #{quantity}, version = version + 1, update_time = NOW() " +
            "WHERE sku_code = #{skuCode} AND warehouse_id = #{warehouseId} AND locked_quantity >= #{quantity} AND version = #{version}")
    int decrementLockedQuantity(@Param("skuCode") String skuCode, @Param("warehouseId") Long warehouseId,
                                 @Param("quantity") Integer quantity, @Param("version") Integer version);

    /**
     * 增加预扣数量
     */
    @Update("UPDATE stock SET reserved_quantity = reserved_quantity + #{quantity}, version = version + 1, update_time = NOW() " +
            "WHERE sku_code = #{skuCode} AND warehouse_id = #{warehouseId} AND version = #{version}")
    int incrementReservedQuantity(@Param("skuCode") String skuCode, @Param("warehouseId") Long warehouseId,
                                    @Param("quantity") Integer quantity, @Param("version") Integer version);

    /**
     * 确认预扣出库（reserved减少，quantity减少）
     */
    @Update("UPDATE stock SET reserved_quantity = reserved_quantity - #{quantity}, quantity = quantity - #{quantity}, " +
            "version = version + 1, update_time = NOW() " +
            "WHERE sku_code = #{skuCode} AND warehouse_id = #{warehouseId} AND reserved_quantity >= #{quantity} AND version = #{version}")
    int confirmReserveOutbound(@Param("skuCode") String skuCode, @Param("warehouseId") Long warehouseId,
                                @Param("quantity") Integer quantity, @Param("version") Integer version);

    /**
     * 取消预扣（reserved减少，quantity不变）
     */
    @Update("UPDATE stock SET reserved_quantity = reserved_quantity - #{quantity}, " +
            "version = version + 1, update_time = NOW() " +
            "WHERE sku_code = #{skuCode} AND warehouse_id = #{warehouseId} AND reserved_quantity >= #{quantity} AND version = #{version}")
    int cancelReserveRelease(@Param("skuCode") String skuCode, @Param("warehouseId") Long warehouseId,
                              @Param("quantity") Integer quantity, @Param("version") Integer version);

    /**
     * 发货出库（locked减少，quantity减少）
     */
    @Update("UPDATE stock SET locked_quantity = locked_quantity - #{quantity}, quantity = quantity - #{quantity}, " +
            "version = version + 1, update_time = NOW() " +
            "WHERE sku_code = #{skuCode} AND warehouse_id = #{warehouseId} AND locked_quantity >= #{quantity} AND version = #{version}")
    int shipOutbound(@Param("skuCode") String skuCode, @Param("warehouseId") Long warehouseId,
                     @Param("quantity") Integer quantity, @Param("version") Integer version);

    /**
     * 增加残次品数量
     */
    @Update("UPDATE stock SET defective_quantity = defective_quantity + #{quantity}, version = version + 1, update_time = NOW() " +
            "WHERE sku_code = #{skuCode} AND warehouse_id = #{warehouseId} AND version = #{version}")
    int incrementDefectiveQuantity(@Param("skuCode") String skuCode, @Param("warehouseId") Long warehouseId,
                                    @Param("quantity") Integer quantity, @Param("version") Integer version);

    /**
     * 根据SKU和仓库查询库存
     */
    @Select("SELECT * FROM stock WHERE sku_code = #{skuCode} AND warehouse_id = #{warehouseId} LIMIT 1")
    Stock findBySkuAndWarehouse(@Param("skuCode") String skuCode, @Param("warehouseId") Long warehouseId);
}
