package com.example.scaffold.service.impl;

import com.example.scaffold.entity.Order;
import com.example.scaffold.entity.Product;
import com.example.scaffold.mapper.OrderMapper;
import com.example.scaffold.mapper.ProductMapper;
import com.example.scaffold.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 订单服务 - 演示事务传播和隔离级别
 * 
 * 学习要点：
 * 1. 事务传播行为 - Propagation
 * 2. 事务隔离级别 - Isolation
 * 3. 事务回滚 - rollbackFor
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderService {
    
    private final OrderMapper orderMapper;
    private final ProductMapper productMapper;
    private final UserMapper userMapper;
    
    /**
     * 创建订单 - 演示事务
     * REQUIRED: 有事务则加入，无则新建
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Order createOrder(Long userId, Long productId, Integer quantity) {
        log.info("📦 [OrderService] 创建订单: userId={}, productId={}, quantity={}", userId, productId, quantity);
        
        // 检查用户
        if (userMapper.findById(userId) == null) {
            throw new RuntimeException("用户不存在: " + userId);
        }
        
        // 检查产品
        Product product = productMapper.findById(productId);
        if (product == null) {
            throw new RuntimeException("产品不存在: " + productId);
        }
        
        // 扣减库存
        int rows = productMapper.decreaseStock(productId, quantity);
        if (rows == 0) {
            throw new RuntimeException("库存不足");
        }
        
        // 创建订单
        Order order = new Order();
        order.setUserId(userId);
        order.setProductId(productId);
        order.setQuantity(quantity);
        order.setTotalPrice(product.getPrice().multiply(BigDecimal.valueOf(quantity)));
        order.setStatus("PENDING");
        
        orderMapper.insert(order);
        log.info("✅ [OrderService] 订单创建成功: orderId={}", order.getId());
        
        return order;
    }
    
    /**
     * 模拟事务回滚
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Order createOrderWithRollback(Long userId, Long productId, Integer quantity, boolean shouldRollback) {
        log.info("📦 [OrderService] 创建订单(可能回滚): userId={}, shouldRollback={}", userId, shouldRollback);
        
        Order order = createOrder(userId, productId, quantity);
        
        if (shouldRollback) {
            log.warn("⚠️ [OrderService] 触发回滚!");
            throw new RuntimeException("模拟事务回滚");
        }
        
        return order;
    }
    
    /**
     * REQUIRES_NEW - 挂起当前事务，创建新事务
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void logOrderOperation(Long orderId, String operation) {
        log.info("📝 [OrderService] 记录订单操作: orderId={}, operation={}", orderId, operation);
        // 这个方法会在独立事务中执行
        // 即使外部事务回滚，这里的记录也会保留
    }
    
    /**
     * 使用隔离级别 READ_COMMITTED
     */
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public Order getOrder(Long id) {
        return orderMapper.findById(id);
    }
    
    public List<Order> findAll() {
        return orderMapper.findAll();
    }
    
    public List<Order> findByUserId(Long userId) {
        return orderMapper.findByUserId(userId);
    }
    
    @Transactional
    public void updateStatus(Long id, String status) {
        orderMapper.updateStatus(id, status);
    }
    
    @Transactional
    public void deleteById(Long id) {
        orderMapper.deleteById(id);
    }
}