package com.ffii.fpsms.modules.stock.entity

import com.ffii.core.support.AbstractRepository
import com.ffii.fpsms.modules.stock.entity.projection.StockOutLineInfo
import com.ffii.fpsms.modules.stock.web.model.StockOutStatus
import org.springframework.stereotype.Repository
import org.springframework.data.repository.query.Param
import java.time.LocalDate
import org.springframework.data.jpa.repository.Query

@Repository
interface StockOutLIneRepository: AbstractRepository<StockOutLine, Long> {
    fun findAllByStockOutIdAndDeletedFalse(stockOutId: Long): List<StockOutLine>
//    fun findAllByStockOutIdAndDeletedFalse(stockOutId: Long, status: StockOutStatus): List<StockOutLine>
    fun findAllByPickOrderLineIdAndDeletedFalse(pickOrderLineId: Long): List<StockOutLineInfo>

    fun findAllByIdIn(id: List<Long>): List<StockOutLineInfo>

    fun findStockOutLineInfoById(id: Long): StockOutLineInfo

    fun findAllByStockOutId(stockOutId: Long): List<StockOutLine>
    fun findByPickOrderLineIdAndInventoryLotLineIdAndDeletedFalse(
        pickOrderLineId: Long, 
        inventoryLotLineId: Long
    ): List<StockOutLine>
    fun existsByPickOrderLineIdAndInventoryLotLineIdAndDeletedFalse(pickOrderLineId: Long, inventoryLotLineId: Long): Boolean
    @Query("""
    SELECT sol FROM StockOutLine sol 
    WHERE sol.deleted = false
    AND sol.type IS NOT NULL
    AND (:startDate IS NULL OR DATE(sol.created) >= :startDate)
    AND (:endDate IS NULL OR DATE(sol.created) <= :endDate)
    AND (:itemCode IS NULL OR sol.item.code LIKE %:itemCode%)
    AND (:itemName IS NULL OR sol.item.name LIKE %:itemName%)
    AND (:type IS NULL OR sol.type = :type)
    ORDER BY sol.created DESC
""")
fun searchStockOutLines(
    @Param("startDate") startDate: LocalDate?,
    @Param("endDate") endDate: LocalDate?,
    @Param("itemCode") itemCode: String?,
    @Param("itemName") itemName: String?,
    @Param("type") type: String?
): List<StockOutLine>
    @Query("SELECT sol FROM StockOutLine sol WHERE sol.item.id = :itemId AND sol.deleted = false")
    fun findAllByItemIdAndDeletedFalse(itemId: Long): List<StockOutLine>

    @Query("SELECT sol FROM StockOutLine sol WHERE sol.item.id IN :itemIds AND sol.deleted = false")
fun findAllByItemIdInAndDeletedFalse(itemIds: List<Long>): List<StockOutLine>


@Query("""
    SELECT sol FROM StockOutLine sol 
    WHERE sol.pickOrderLine.id IN :pickOrderLineIds 
    AND sol.deleted = false
""")
fun findAllByPickOrderLineIdInAndDeletedFalse(
    @Param("pickOrderLineIds") pickOrderLineIds: List<Long>
): List<StockOutLine>

    /** Workbench: bulk load SOL as projection to avoid N+1 in suggestion rebuild. */
    @Query(
        """
        SELECT sol FROM StockOutLine sol
        WHERE sol.pickOrderLine.id IN :pickOrderLineIds
          AND sol.deleted = false
        """
    )
    fun findAllInfoByPickOrderLineIdInAndDeletedFalse(
        @Param("pickOrderLineIds") pickOrderLineIds: List<Long>
    ): List<StockOutLineInfo>

// 添加批量查询方法：按 (pickOrderLineId, inventoryLotLineId) 组合查询
@Query("""
    SELECT sol FROM StockOutLine sol 
    WHERE sol.pickOrderLine.id IN :pickOrderLineIds
    AND sol.inventoryLotLine.id IN :inventoryLotLineIds
    AND sol.deleted = false
""")
fun findAllByPickOrderLineIdInAndInventoryLotLineIdInAndDeletedFalse(
    @Param("pickOrderLineIds") pickOrderLineIds: List<Long>,
    @Param("inventoryLotLineIds") inventoryLotLineIds: List<Long>
): List<StockOutLine>

// 查找所有使用指定 lot 的 stockOutLines（排除已完成和已拒绝的）
@Query("""
    SELECT sol FROM StockOutLine sol 
    WHERE sol.inventoryLotLine.id IN :inventoryLotLineIds
    AND sol.deleted = false
    AND sol.status NOT IN ('completed', 'rejected', 'COMPLETE', 'REJECTED')
""")
fun findAllByInventoryLotLineIdInAndNotCompletedOrRejected(
    @Param("inventoryLotLineIds") inventoryLotLineIds: List<Long>
): List<StockOutLine>


fun findByInventoryLotLineIdAndStatusAndDeletedFalse(
    inventoryLotLineId: Long,
    status: String
): List<StockOutLine>

@Query(
    """
    SELECT sil FROM StockInLine sil
    WHERE sil.jobOrder.id IN :jobOrderIds AND sil.deleted = false
    ORDER BY sil.id ASC
    """
)
fun findAllByJobOrder_IdInAndDeletedFalse(@Param("jobOrderIds") jobOrderIds: List<Long>): List<StockInLine>
}
