// FPSMS-backend/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickExecutionIssueService.kt
package com.ffii.fpsms.modules.pickOrder.service

import com.ffii.fpsms.modules.master.web.models.MessageResponse
import com.ffii.fpsms.modules.pickOrder.entity.PickExecutionIssue
import com.ffii.fpsms.modules.pickOrder.entity.PickExecutionIssueRepository
import com.ffii.fpsms.modules.stock.entity.StockOutLine
import com.ffii.fpsms.modules.pickOrder.entity.IssueCategory // ✅ 添加这行
import com.ffii.fpsms.modules.pickOrder.entity.HandleStatus
import com.ffii.fpsms.modules.stock.entity.StockOutLIneRepository
import com.ffii.fpsms.modules.stock.entity.InventoryLotLine
import com.ffii.fpsms.modules.stock.entity.InventoryLotLineRepository
import com.ffii.fpsms.modules.stock.entity.InventoryRepository
import com.ffii.fpsms.modules.stock.web.model.PickExecutionIssueRequest
import com.ffii.fpsms.modules.stock.service.SuggestedPickLotService
import com.ffii.fpsms.modules.stock.entity.enum.InventoryLotLineStatus
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.springframework.transaction.annotation.Propagation
import java.math.BigDecimal
import java.time.LocalDate
import java.time.LocalDateTime
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository
import com.ffii.core.support.JdbcDao
import com.ffii.fpsms.modules.stock.entity.StockOutRepository
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLineRepository
import com.ffii.fpsms.modules.deliveryOrder.service.DoPickOrderService
import com.ffii.fpsms.modules.jobOrder.entity.JoPickOrderRepository
import com.ffii.fpsms.modules.jobOrder.entity.JoPickOrderRecordRepository
import com.ffii.fpsms.modules.stock.web.model.StockOutLineStatus
import com.ffii.fpsms.modules.stock.web.model.StockOutStatus
import com.ffii.fpsms.modules.pickOrder.enums.PickOrderLineStatus
import com.ffii.fpsms.modules.pickOrder.enums.PickOrderStatus
@Service
open class PickExecutionIssueService(
    private val pickExecutionIssueRepository: PickExecutionIssueRepository,
    private val stockOutLineRepository: StockOutLIneRepository,
    private val inventoryLotLineRepository: InventoryLotLineRepository,
    private val inventoryRepository: InventoryRepository,
    private val suggestedPickLotService: SuggestedPickLotService,
    private val pickOrderRepository: PickOrderRepository,
    private val jdbcDao: JdbcDao,
    private val stockOutRepository: StockOutRepository,
    private val pickOrderLineRepository: PickOrderLineRepository,
    private val doPickOrderService: DoPickOrderService,
    private val joPickOrderRepository: JoPickOrderRepository,
    private val joPickOrderRecordRepository: JoPickOrderRecordRepository

) {

    @Transactional(rollbackFor = [Exception::class])
    open fun recordPickExecutionIssue(request: PickExecutionIssueRequest): MessageResponse {
        try {
            // 1. 检查是否已经存在相同的 pick execution issue 记录
            val existingIssues = pickExecutionIssueRepository.findByPickOrderLineIdAndLotIdAndDeletedFalse(
                request.pickOrderLineId, 
                request.lotId ?: 0L
            )
            
            if (existingIssues.isNotEmpty()) {
                return MessageResponse(
                    id = null,
                    name = "Pick execution issue already exists",
                    code = "DUPLICATE",
                    type = "pick_execution_issue",
                    message = "A pick execution issue for this lot has already been recorded",
                    errorPosition = null
                )
            }
            val pickOrder = pickOrderRepository.findById(request.pickOrderId).orElse(null)
            // 2. 创建 pick execution issue 记录
            val pickExecutionIssue = PickExecutionIssue(
                id = null,  // ✅ 添加 id
                pickOrderId = request.pickOrderId,
                pickOrderCode = request.pickOrderCode,
                pickOrderCreateDate = request.pickOrderCreateDate,
                pickExecutionDate = request.pickExecutionDate ?: LocalDate.now(),
                pickOrderLineId = request.pickOrderLineId,
                issueNo = generateIssueNo(),
                joPickOrderId = pickOrder?.jobOrder?.id,  // ✅ 添加
                doPickOrderId = if (pickOrder?.type?.value == "do") pickOrder.id else null,  // ✅ 添加
                issueCategory = IssueCategory.valueOf(
                    request.issueCategory ?: "lot_issue"
                ),
                itemId = request.itemId,
                itemCode = request.itemCode,
                itemDescription = request.itemDescription,
                lotId = request.lotId,
                lotNo = request.lotNo,
                storeLocation = request.storeLocation,
                requiredQty = request.requiredQty,
                actualPickQty = request.actualPickQty,
                missQty = request.missQty,
                badItemQty = request.badItemQty,
                issueRemark = request.issueRemark,
                pickerName = request.pickerName,  // ✅ 确保从 request 中获取
                handleStatus = HandleStatus.pending,  // ✅ 添加
                handleDate = null,  // ✅ 添加
                handledBy = request.handledBy,
                created = LocalDateTime.now(),
                createdBy = "system",
                version = 0,  // ✅ 添加
                modified = LocalDateTime.now(),
                modifiedBy = "system",
                deleted = false  // ✅ 添加
            )

            val savedIssue = pickExecutionIssueRepository.save(pickExecutionIssue)

            // 3. 获取相关数据
            val actualPickQty = request.actualPickQty ?: BigDecimal.ZERO
            val missQty = request.missQty ?: BigDecimal.ZERO
            val badItemQty = request.badItemQty ?: BigDecimal.ZERO
            val lotId = request.lotId
            val itemId = request.itemId

            println("=== PICK EXECUTION ISSUE PROCESSING (NEW LOGIC) ===")
            println("Actual Pick Qty: ${actualPickQty}")
            println("Miss Qty: ${missQty}")
            println("Bad Item Qty: ${badItemQty}")
            println("Lot ID: ${lotId}")
            println("Item ID: ${itemId}")
            println("================================================")

            // 4. 新的统一处理逻辑
            when {
                // 情况1: 只有 miss item (actualPickQty = 0, missQty > 0, badItemQty = 0)
                actualPickQty == BigDecimal.ZERO && missQty > BigDecimal.ZERO && badItemQty == BigDecimal.ZERO -> {
                    handleMissItemOnly(request, missQty)
                }
                
                // 情况2: 只有 bad item (badItemQty > 0, missQty = 0)
                badItemQty > BigDecimal.ZERO && missQty == BigDecimal.ZERO -> {
                    handleBadItemOnly(request, badItemQty)
                }
                
                // 情况3: 既有 miss item 又有 bad item
                missQty > BigDecimal.ZERO && badItemQty > BigDecimal.ZERO -> {
                    handleBothMissAndBadItem(request, missQty, badItemQty)
                }
                
                // ✅ 修复：情况4: 有 miss item 的情况（无论 actualPickQty 是多少）
                missQty > BigDecimal.ZERO -> {
                    handleMissItemWithPartialPick(request, actualPickQty, missQty)
                }
                
                // 情况5: 正常拣货 (actualPickQty > 0, 没有 miss 或 bad item)
                actualPickQty > BigDecimal.ZERO -> {
                    handleNormalPick(request, actualPickQty)
                }
                
                else -> {
                    println("Unknown case: actualPickQty=${actualPickQty}, missQty=${missQty}, badItemQty=${badItemQty}")
                }
            }

            val pickOrderForCompletion = pickOrderRepository.findById(request.pickOrderId).orElse(null)
            val consoCode = pickOrderForCompletion?.consoCode
            
            if (consoCode != null) {
                println("🔍 Checking if pick order $consoCode should be completed after lot rejection...")
                try {
                    checkAndCompletePickOrder(consoCode)
                } catch (e: Exception) {
                    println("⚠️ Error checking pick order completion: ${e.message}")
                }
            }
    
    
            return MessageResponse(
                id = savedIssue.id,
                name = "Pick execution issue recorded successfully",
                code = "SUCCESS",
                type = "pick_execution_issue",
                message = "Pick execution issue recorded successfully",
                errorPosition = null
            )

        } catch (e: Exception) {
            println("=== ERROR IN recordPickExecutionIssue ===")
            e.printStackTrace()
            return MessageResponse(
                id = null,
                name = "Failed to record pick execution issue",
                code = "ERROR",
                type = "pick_execution_issue",
                message = "Error: ${e.message}",
                errorPosition = null
            )
        }
    }
    private fun generateIssueNo(): String {
        val now = LocalDateTime.now()
        val yearMonth = now.format(java.time.format.DateTimeFormatter.ofPattern("yyMM"))
        
        // 查询当月最新的 issueNo
        val latestIssueNo = pickExecutionIssueRepository.findLatestIssueNoByYearMonth(yearMonth)
        
        // 计算下一个序列号
        val nextSequence = if (latestIssueNo != null) {
            // 从最新的 issueNo 中提取序列号
            // 例如: SKO-2510-001 -> 001
            val parts = latestIssueNo.split("-")
            if (parts.size == 3) {
                val currentSequence = parts[2].toIntOrNull() ?: 0
                currentSequence + 1
            } else {
                1
            }
        } else {
            1
        }
        
        // 格式化为 SKO-YYMM-001
        return "SKO-${yearMonth}-${nextSequence.toString().padStart(3, '0')}"
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = [Exception::class])
private fun checkAndCompletePickOrder(consoCode: String) {
    println("=== DEBUG: checkAndCompletePickOrder ===")
    println("consoCode: $consoCode")
    
    // 1. 查找 StockOut
    val stockOut = stockOutRepository.findByConsoPickOrderCode(consoCode).orElse(null)
    if (stockOut == null) {
        println("❌ No stock_out found for consoCode: $consoCode")
        return
    }
    
    // 2. 查找所有相关的 stock out lines
    val stockOutLinesSql = """
        SELECT sol.*
        FROM stock_out_line sol
        JOIN pick_order_line pol ON pol.id = sol.pickOrderLineId
        JOIN pick_order po ON po.id = pol.poId
        WHERE po.consoCode = :consoCode
        AND sol.deleted = false
    """.trimIndent()
    
    val stockOutLinesResult = jdbcDao.queryForList(stockOutLinesSql, mapOf("consoCode" to consoCode))
    val stockOutLineIds = stockOutLinesResult.mapNotNull { row ->
        when (val id = row["id"]) {
            is Number -> id.toLong()
            is String -> id.toLongOrNull()
            else -> null
        }
    }
    
    val stockOutLines = if (stockOutLineIds.isNotEmpty()) {
        stockOutLineRepository.findAllById(stockOutLineIds)
    } else {
        emptyList()
    }
    
    println("Total stock out lines for consoCode $consoCode: ${stockOutLines.size}")
    
    // 3. 检查是否有未完成的行
    val unfinishedLines = stockOutLines.filter {
        it.status != StockOutLineStatus.COMPLETE.status
                && it.status != StockOutLineStatus.REJECTED.status
    }
    
    println("📊 Stock out lines: ${stockOutLines.size}, Unfinished: ${unfinishedLines.size}")
    
    // 4. 如果所有行都完成或被拒绝，则完成 pick order
    if (unfinishedLines.isEmpty()) {
        println("✅ All stock out lines completed or rejected, completing pick order...")
        
        // 4.1 更新 StockOut 状态
        stockOut.status = StockOutStatus.COMPLETE.status
        stockOutRepository.saveAndFlush(stockOut)
        
        // 4.2 更新所有 pick order lines 状态
        val completedPickOrderLineIds = stockOutLines.mapNotNull { it.pickOrderLine?.id }
        println("Completed pick order line IDs: $completedPickOrderLineIds")
        
        if (completedPickOrderLineIds.isNotEmpty()) {
            val pickOrderLines = pickOrderLineRepository.findAllById(completedPickOrderLineIds)
            pickOrderLines.forEach { line ->
                line.status = PickOrderLineStatus.COMPLETED
                println("Updated pick order line ${line.id} to COMPLETED")
            }
            pickOrderLineRepository.saveAll(pickOrderLines)
            println("✅ Updated ${pickOrderLines.size} pick order lines to COMPLETED status")
            
            // 4.3 获取所有受影响的 pick orders
            val pickOrderIds = pickOrderLines.mapNotNull { it.pickOrder?.id }.distinct()
            println("Affected pick order IDs: $pickOrderIds")
            
            // 4.4 检查每个 pick order 是否完全完成
            pickOrderIds.forEach { pickOrderId ->
                val pickOrder = pickOrderRepository.findById(pickOrderId).orElse(null)
                if (pickOrder != null) {
                    // 检查这个 pick order 的所有行是否都完成了
                    val allLines = pickOrder.pickOrderLines
                    val completedLines = allLines.filter { it.status == PickOrderLineStatus.COMPLETED }
                    
                    println("Pick order ${pickOrder.code}: ${completedLines.size}/${allLines.size} lines completed")
                    
                    if (completedLines.size == allLines.size && allLines.isNotEmpty()) {
                        // 所有行都完成了，更新 pick order 状态
                        pickOrder.status = PickOrderStatus.COMPLETED
                        pickOrder.completeDate = LocalDateTime.now()
                        pickOrderRepository.save(pickOrder)
                        println("✅ Updated pick order ${pickOrder.code} to COMPLETED status")
                        
                        // 4.5 处理 DO pick order 相关记录
                        try {
                            val removedCount = doPickOrderService.removeDoPickOrdersForPickOrder(pickOrderId)
                            println("✅ Removed $removedCount do_pick_order records for completed pick order ${pickOrderId}")
                            
                            doPickOrderService.completeDoPickOrderRecordsForPickOrder(pickOrderId)
                            println("✅ Updated do_pick_order_record status to COMPLETED for pick order ${pickOrderId}")
                        } catch (e: Exception) {
                            println("⚠️ Error updating DO pick order records: ${e.message}")
                        }
                        
                        // 4.6 处理 JO pick order 相关记录
                        if (pickOrder.jobOrder != null) {
                            try {
                                val joPickOrders = joPickOrderRepository.findByPickOrderId(pickOrderId)
                                joPickOrders.forEach { 
                                    it.ticketCompleteTime = LocalDateTime.now()
                                }
                                joPickOrderRepository.saveAll(joPickOrders)
                                
                                val joPickOrderRecords = joPickOrderRecordRepository.findByPickOrderId(pickOrderId)
                                joPickOrderRecords.forEach { 
                                    it.ticketCompleteTime = LocalDateTime.now()
                                }
                                joPickOrderRecordRepository.saveAll(joPickOrderRecords)
                                
                                println("✅ Set jo_pick_order ticketCompleteTime for pick order ${pickOrderId}")
                            } catch (e: Exception) {
                                println("⚠️ Error updating JO pick order records: ${e.message}")
                            }
                        }
                    }
                }
            }
        }
        
        println("🎉 Pick order completed successfully!")
    } else {
        println("⏳ Still have ${unfinishedLines.size} unfinished lines, pick order not completed yet")
    }
}
// FPSMS-backend/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickExecutionIssueService.kt
// ✅ 修复：处理有部分拣货但有 miss item 的情况
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = [Exception::class])
private fun handleMissItemWithPartialPick(request: PickExecutionIssueRequest, actualPickQty: BigDecimal, missQty: BigDecimal) {
    println("=== HANDLING MISS ITEM WITH PARTIAL PICK (FIXED LOGIC) ===")
    println("Actual Pick Qty: ${actualPickQty}")
    println("Miss Qty: ${missQty}")
    
    val lotId = request.lotId ?: return
    val itemId = request.itemId ?: return
    val inventoryLotLine = inventoryLotLineRepository.findById(lotId).orElse(null)
    
    if (inventoryLotLine != null) {
        // ✅ 修复1：只处理已拣货的部分：更新 outQty
        val currentOutQty = inventoryLotLine.outQty ?: BigDecimal.ZERO
        val newOutQty = currentOutQty.add(actualPickQty)
        inventoryLotLine.outQty = newOutQty
        
        // ✅ 修复2：Miss item 不减少 inQty，而是标记为 unavailable
        // 因为 miss item 意味着这些物品实际上不存在或找不到
        // 所以应该标记整个批次为 unavailable，而不是减少 inQty
        
        // ✅ 修复3：如果 missQty > 0，标记批次为 unavailable
        if (missQty > BigDecimal.ZERO) {
            inventoryLotLine.status = InventoryLotLineStatus.UNAVAILABLE
        }
        
        inventoryLotLine.modified = LocalDateTime.now()
        inventoryLotLine.modifiedBy = "system"
        inventoryLotLineRepository.save(inventoryLotLine)
        
        println("Miss item with partial pick: Updated lot ${lotId}")
        println("  - Added to outQty: ${actualPickQty} (${currentOutQty} -> ${newOutQty})")
        println("  - Set status to UNAVAILABLE due to missQty: ${missQty}")
    }
    
    // ✅ 修复4：更新 inventory 表的 unavailableQty
    // 对于 miss item，应该将 missQty 计入 unavailableQty
    updateInventoryUnavailableQty(itemId, missQty)
    
    // ✅ 修复5：更新 stock_out_line 状态为 rejected（因为还有 miss item）
    updateStockOutLineStatus(request, "rejected")
    
    // 重新建议拣货批次（针对 miss 的数量）
    try {
        resuggestPickOrder(request.pickOrderId)
        println("Resuggested pick order for miss qty: ${missQty}")
    } catch (e: Exception) {
        println("Error during resuggest in handleMissItemWithPartialPick: ${e.message}")
    }
}

// ✅ 修复：Miss item 处理逻辑
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = [Exception::class])
private fun handleMissItemOnly(request: PickExecutionIssueRequest, missQty: BigDecimal) {
    println("=== HANDLING MISS ITEM ONLY (FIXED LOGIC) ===")
    println("Miss Qty: ${missQty}")
    
    val lotId = request.lotId ?: return
    val itemId = request.itemId ?: return
    val inventoryLotLine = inventoryLotLineRepository.findById(lotId).orElse(null)
    
    if (inventoryLotLine != null) {
        // ✅ 修复：Miss item 意味着剩余的所有物品都找不到
        val currentInQty = inventoryLotLine.inQty ?: BigDecimal.ZERO
        val currentOutQty = inventoryLotLine.outQty ?: BigDecimal.ZERO
        val remainingQty = currentInQty.minus(currentOutQty)
        
        // 标记批次为 unavailable
        inventoryLotLine.status = InventoryLotLineStatus.UNAVAILABLE
        inventoryLotLine.modified = LocalDateTime.now()
        inventoryLotLine.modifiedBy = "system"
        inventoryLotLineRepository.save(inventoryLotLine)
        
        println("Miss item only: Set lot ${lotId} status to UNAVAILABLE")
        println("  - Remaining qty: ${remainingQty}")
        println("  - Miss qty (user input): ${missQty}")
        println("  - Unavailable qty (should be remaining qty): ${remainingQty}")
    }
    
    // ✅ 修复：更新 inventory 表的 unavailableQty
    // 应该是剩余的数量，而不是 missQty
    val currentInQty = inventoryLotLine?.inQty ?: BigDecimal.ZERO
    val currentOutQty = inventoryLotLine?.outQty ?: BigDecimal.ZERO
    val remainingQty = currentInQty.minus(currentOutQty)
    
    // ✅ 修复：只增加剩余数量，不要重复计算 missQty
    updateInventoryUnavailableQty(itemId, remainingQty)
    
    // ✅ 修复：更新 stock_out_line 状态为 rejected
    updateStockOutLineStatus(request, "rejected")
    
    // 重新建议拣货批次
    try {
        resuggestPickOrder(request.pickOrderId)
        println("Resuggested pick order to find alternative lots for missing qty: ${missQty}")
    } catch (e: Exception) {
        println("Error during resuggest in handleMissItemOnly: ${e.message}")
    }
}

// ✅ 修复：Bad item 处理逻辑
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = [Exception::class])
private fun handleBadItemOnly(request: PickExecutionIssueRequest, badItemQty: BigDecimal) {
    println("=== HANDLING BAD ITEM ONLY (FIXED LOGIC) ===")
    println("Bad Item Qty: ${badItemQty}")
    
    val lotId = request.lotId ?: return
    val itemId = request.itemId ?: return
    val inventoryLotLine = inventoryLotLineRepository.findById(lotId).orElse(null)
    
    if (inventoryLotLine != null) {
        // ✅ 修复：Bad item 不减少 inQty，而是标记为 unavailable
        // 因为 bad item 意味着这些物品质量有问题，不能使用
        inventoryLotLine.status = InventoryLotLineStatus.UNAVAILABLE
        inventoryLotLine.modified = LocalDateTime.now()
        inventoryLotLine.modifiedBy = "system"
        inventoryLotLineRepository.save(inventoryLotLine)
        
        println("Bad item only: Set lot ${lotId} status to UNAVAILABLE")
    }
    
    // ✅ 修复：更新 inventory 表的 unavailableQty
    updateInventoryUnavailableQty(itemId, badItemQty)
    
    // ✅ 修复：更新 stock_out_line 状态为 rejected
    updateStockOutLineStatus(request, "rejected")
    
    // 重新建议拣货批次
    try {
        resuggestPickOrder(request.pickOrderId)
        println("Resuggested pick order for bad item qty: ${badItemQty}")
    } catch (e: Exception) {
        println("Error during resuggest in handleBadItemOnly: ${e.message}")
    }
}

// ✅ 修复：Both miss and bad item 处理逻辑
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = [Exception::class])
private fun handleBothMissAndBadItem(request: PickExecutionIssueRequest, missQty: BigDecimal, badItemQty: BigDecimal) {
    println("=== HANDLING BOTH MISS AND BAD ITEM (FIXED LOGIC) ===")
    println("Miss Qty: ${missQty}, Bad Item Qty: ${badItemQty}")
    
    val lotId = request.lotId ?: return
    val itemId = request.itemId ?: return
    val inventoryLotLine = inventoryLotLineRepository.findById(lotId).orElse(null)
    val totalUnavailableQty = missQty.add(badItemQty)
    
    if (inventoryLotLine != null) {
        // ✅ 修复：Miss + Bad item 不减少 inQty，而是标记为 unavailable
        inventoryLotLine.status = InventoryLotLineStatus.UNAVAILABLE
        inventoryLotLine.modified = LocalDateTime.now()
        inventoryLotLine.modifiedBy = "system"
        inventoryLotLineRepository.save(inventoryLotLine)
        
        println("Both miss and bad item: Set lot ${lotId} status to UNAVAILABLE")
        println("  - Miss Qty: ${missQty}")
        println("  - Bad Item Qty: ${badItemQty}")
        println("  - Total Unavailable Qty: ${totalUnavailableQty}")
    }
    
    // ✅ 修复：更新 inventory 表的 unavailableQty
    updateInventoryUnavailableQty(itemId, totalUnavailableQty)
    
    // ✅ 修复：更新 stock_out_line 状态为 rejected
    updateStockOutLineStatus(request, "rejected")
    
    // 重新建议拣货批次
    try {
        resuggestPickOrder(request.pickOrderId)
        println("Resuggested pick order for both miss qty: ${missQty} and bad item qty: ${badItemQty}")
    } catch (e: Exception) {
        println("Error during resuggest in handleBothMissAndBadItem: ${e.message}")
    }
}

    // ✅ 修复：正常拣货处理逻辑
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = [Exception::class])
    private fun handleNormalPick(request: PickExecutionIssueRequest, actualPickQty: BigDecimal) {
        println("=== HANDLING NORMAL PICK ===")
        
        // ✅ 修复：更新 stock_out_line，但不要累积 qty
        val stockOutLines = stockOutLineRepository.findByPickOrderLineIdAndInventoryLotLineIdAndDeletedFalse(
            request.pickOrderLineId,
            request.lotId ?: 0L
        )
        
        stockOutLines.forEach { stockOutLine ->
            // ✅ 修复：直接设置 qty 为 actualPickQty，不要累积
            val requiredQty = request.requiredQty?.toDouble() ?: 0.0
            val actualPickQtyDouble = actualPickQty.toDouble()
            val newStatus = if (actualPickQtyDouble >= requiredQty) {
                "completed"
            } else {
                "partially_completed"
            }
            
            stockOutLine.status = newStatus
            stockOutLine.qty = actualPickQtyDouble // ✅ 直接设置，不累积
            stockOutLine.modified = LocalDateTime.now()
            stockOutLine.modifiedBy = "system"
            stockOutLineRepository.save(stockOutLine)
            
            println("Updated stock out line ${stockOutLine.id}: status=${newStatus}, qty=${actualPickQtyDouble}")
        }

        // ✅ 修复：更新 inventory_lot_line 的 outQty
        val lotId = request.lotId ?: return
        val inventoryLotLine = inventoryLotLineRepository.findById(lotId).orElse(null)
        if (inventoryLotLine != null) {
            // ✅ 修复：计算新的 outQty，考虑之前的 outQty
            val currentOutQty = inventoryLotLine.outQty ?: BigDecimal.ZERO
            val previousPickedQty = currentOutQty.minus(actualPickQty) // 计算之前已拣的数量
            val newOutQty = previousPickedQty.add(actualPickQty) // 更新为新的总拣货数量
            
            inventoryLotLine.outQty = newOutQty
            inventoryLotLine.modified = LocalDateTime.now()
            inventoryLotLine.modifiedBy = "system"
            inventoryLotLineRepository.save(inventoryLotLine)
            
            println("Updated inventory lot line ${lotId} outQty: ${currentOutQty} -> ${newOutQty}")
        }
    }

    // ✅ 新方法：统一更新 inventory 表的 unavailableQty
    private fun updateInventoryUnavailableQty(itemId: Long, unavailableQty: BigDecimal) {
        try {
            println("=== INVENTORY UNAVAILABLE QTY UPDATE (TRIGGER HANDLED) ===")
            println("Item ID: ${itemId}")
            println("Expected unavailableQty to be added by trigger: ${unavailableQty}")
            println("Note: Database trigger will handle unavailableQty calculation")
            println("=========================================================")
        } catch (e: Exception) {
            println("Error in updateInventoryUnavailableQty: ${e.message}")
        }
    }

    // ✅ 修复：更新 stock_out_line 状态
    private fun updateStockOutLineStatus(request: PickExecutionIssueRequest, status: String) {
        val stockOutLines = stockOutLineRepository.findByPickOrderLineIdAndInventoryLotLineIdAndDeletedFalse(
            request.pickOrderLineId,
            request.lotId ?: 0L
        )
        
        stockOutLines.forEach { stockOutLine ->
            stockOutLine.status = status
            
            // ✅ FIX: Update qty to actualPickQty before setting status to rejected
            if (status == "rejected" && request.actualPickQty != null) {
                stockOutLine.qty = request.actualPickQty.toDouble()
                println("Updated stock out line ${stockOutLine.id} qty to: ${request.actualPickQty}")
            }
            
            stockOutLine.modified = LocalDateTime.now()
            stockOutLine.modifiedBy = "system"
            stockOutLineRepository.save(stockOutLine)
            
            println("Updated stock out line ${stockOutLine.id} status to: ${status}")
        }
    }
    // ✅ 修复：使用 REQUIRES_NEW 传播级别，避免事务冲突
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = [Exception::class])
    private fun resuggestPickOrder(pickOrderId: Long?) {
        if (pickOrderId != null) {
            try {
                val resuggestResult = suggestedPickLotService.resuggestPickOrder(pickOrderId)
                println("Resuggest result: ${resuggestResult.code} - ${resuggestResult.message}")
                
                if (resuggestResult.code != "SUCCESS") {
                    println("Warning: Resuggest failed: ${resuggestResult.message}")
                }
            } catch (e: Exception) {
                println("Error during resuggest: ${e.message}")
                e.printStackTrace()
                // 不重新抛出异常，避免影响主事务
            }
        }
    }

    open fun getPickExecutionIssuesByPickOrder(pickOrderId: Long): List<PickExecutionIssue> {
        return pickExecutionIssueRepository.findByPickOrderIdAndDeletedFalse(pickOrderId)
    }

    open fun getPickExecutionIssuesByPickOrderLine(pickOrderLineId: Long): List<PickExecutionIssue> {
        return pickExecutionIssueRepository.findByPickOrderLineIdAndDeletedFalse(pickOrderLineId)
    }
    open fun getAllPickExecutionIssues(type: String? = null): List<PickExecutionIssue> {
        println("=== getAllPickExecutionIssues Debug ===")
        println("Requested type: $type")
        
        val result = when (type?.lowercase()) {
            "jo" -> {
                // Case 1: 只返回 Job Order 的 issues
                val joIssues = pickExecutionIssueRepository.findJoIssues()
                println("✅ Finding JO issues: ${joIssues.size} records")
                joIssues.forEach { 
                    println("  - ID=${it.id}, joPickOrderId=${it.joPickOrderId}, doPickOrderId=${it.doPickOrderId}") 
                }
                joIssues
            }
            "do" -> {
                // Case 2: 只返回 Delivery Order 的 issues
                val doIssues = pickExecutionIssueRepository.findDoIssues()
                println("✅ Finding DO issues: ${doIssues.size} records")
                doIssues.forEach { 
                    println("  - ID=${it.id}, joPickOrderId=${it.joPickOrderId}, doPickOrderId=${it.doPickOrderId}") 
                }
                doIssues
            }
            "material" -> {
                // Case 3: 只返回 Material 的 issues (普通 pick order)
                val materialIssues = pickExecutionIssueRepository.findMaterialIssues()
                println("✅ Finding Material issues: ${materialIssues.size} records")
                materialIssues.forEach { 
                    println("  - ID=${it.id}, joPickOrderId=${it.joPickOrderId}, doPickOrderId=${it.doPickOrderId}") 
                }
                materialIssues
            }
            else -> {
                // Case 4: 返回所有 issues
                val allIssues = pickExecutionIssueRepository.findByDeletedFalse()
                println("✅ Finding ALL issues: ${allIssues.size} records")
                allIssues
            }
        }
        
        println("=== End Debug ===")
        return result
    }
    /**
 * 为 batch release 失败的 delivery order 创建 issue 记录
 */
@Transactional(rollbackFor = [Exception::class])
open fun createBatchReleaseIssue(
    deliveryOrderId: Long,
    errorMessage: String,
    issueCategory: IssueCategory = IssueCategory.match_issue
): Int {
    try {
        println("=== Creating batch release issue ===")
        println("Delivery Order ID: $deliveryOrderId")
        println("Error Message: $errorMessage")
        println("Issue Category: $issueCategory")
        
        // 查询 delivery order
        val deliveryOrderSql = """
            SELECT do.id, do.code, do.estimatedArrivalDate
            FROM fpsmsdb.delivery_order do
            WHERE do.id = :deliveryOrderId
            AND do.deleted = 0
        """.trimIndent()
        
        val deliveryOrder = jdbcDao.queryForMap(
            deliveryOrderSql,
            mapOf("deliveryOrderId" to deliveryOrderId)
        ).orElse(null)
        
        if (deliveryOrder == null) {
            println("❌ Delivery Order not found: $deliveryOrderId")
            return 0
        }
        
        // 查询 delivery order lines
        val linesSql = """
            SELECT dol.id, dol.itemId, i.code as itemCode, i.name as itemName, dol.qty
            FROM fpsmsdb.delivery_order_line dol
            INNER JOIN fpsmsdb.item i ON i.id = dol.itemId
            WHERE dol.doId = :deliveryOrderId
            AND dol.deleted = 0
        """.trimIndent()
        
        val lines = jdbcDao.queryForList(linesSql, mapOf("deliveryOrderId" to deliveryOrderId))
        
        if (lines.isEmpty()) {
            println("⚠️ No delivery order lines found for DO: $deliveryOrderId")
            return 0
        }
        
        // 生成 issue number
        val issueNo = generateIssueNo()
        var createdCount = 0
        
        // 为每个 line 创建 issue 记录
        lines.forEach { line ->
            val itemId = (line["itemId"] as? Number)?.toLong() ?: 0L
            val itemCode = line["itemCode"] as? String
            val itemName = line["itemName"] as? String
            val qty = (line["qty"] as? Number)?.let { BigDecimal(it.toString()) } ?: BigDecimal.ZERO
            
            val issue = PickExecutionIssue(
                id = null,
                pickOrderId = 0L,  // batch release 失败时可能还没有 pick order
                pickOrderCode = deliveryOrder["code"] as? String ?: "",
                pickOrderCreateDate = LocalDate.now(),
                pickExecutionDate = LocalDate.now(),
                pickOrderLineId = 0L,  // batch release 失败时可能还没有 pick order line
                issueNo = issueNo,
                joPickOrderId = null,
                doPickOrderId = null,
                issueCategory = issueCategory,
                itemId = itemId,
                itemCode = itemCode,
                itemDescription = itemName,
                lotId = null,
                lotNo = null,
                storeLocation = null,
                requiredQty = qty,
                actualPickQty = BigDecimal.ZERO,
                missQty = qty,
                badItemQty = BigDecimal.ZERO,
                issueRemark = "Batch release failed: $errorMessage",
                pickerName = null,
                handleStatus = HandleStatus.pending,
                handleDate = null,
                handledBy = null,
                created = LocalDateTime.now(),
                createdBy = "SYSTEM",
                version = 0,
                modified = LocalDateTime.now(),
                modifiedBy = "SYSTEM",
                deleted = false
            )
            
            pickExecutionIssueRepository.save(issue)
            createdCount++
        }
        
        println("✅ Created $createdCount ${issueCategory.name} issues for DO $deliveryOrderId")
        return createdCount
        
    } catch (e: Exception) {
        println("❌ Failed to create batch release issue: ${e.message}")
        e.printStackTrace()
        return 0
    }
}
}