package com.ffii.fpsms.modules.deliveryOrder.entity

import com.ffii.core.support.AbstractRepository
import com.ffii.fpsms.modules.deliveryOrder.entity.models.DeliveryOrderInfo
import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderStatus
import com.ffii.fpsms.modules.deliveryOrder.enums.DoPickOrderStatus
import com.ffii.fpsms.modules.master.entity.projections.SearchId
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import org.springframework.stereotype.Repository
import java.io.Serializable
import java.time.LocalDateTime
import java.time.LocalDate
@Repository
interface DoPickOrderRepository : JpaRepository<DoPickOrder, Long> {
    fun findByTicketNoStartingWith(prefix: String): List<DoPickOrder>
    fun findByStoreIdAndTicketStatusOrderByTruckDepartureTimeAsc(
        storeId: String, 
        status: DoPickOrderStatus
    ): List<DoPickOrder>
    fun findByPickOrderId(pickOrderId: Long): List<DoPickOrder>

    fun findByTicketStatusIn(statuses: List<DoPickOrderStatus>): List<DoPickOrder>
    // 在 DoPickOrderRepository 中添加这个方法
fun findByHandledByAndTicketStatusIn(handledBy: Long, status: List<DoPickOrderStatus>): List<DoPickOrder>
fun findByStoreIdAndTicketStatusIn(storeId: String, status: List<DoPickOrderStatus>): List<DoPickOrder>
fun findByStoreIdAndRequiredDeliveryDateAndTicketStatusIn(
    storeId: String, 
    requiredDeliveryDate: LocalDate,
    status: List<DoPickOrderStatus>
): List<DoPickOrder>

   @Query("SELECT d FROM DoPickOrder d WHERE d.deleted = false ORDER BY d.requiredDeliveryDate ASC, d.truckDepartureTime ASC")
   fun findAllByDeletedFalseOrderByTicketReleaseTimeDesc(): List<DoPickOrder>

    @Query("SELECT d FROM DoPickOrder d WHERE d.deleted = false AND d.requiredDeliveryDate BETWEEN :startDate AND :endDate ORDER BY d.ticketReleaseTime DESC NULLS LAST")
    fun findAllByDeletedFalseAndRequiredDeliveryDateBetween(
        @Param("startDate") startDate: LocalDate,
        @Param("endDate") endDate: LocalDate
    ): List<DoPickOrder>
     fun findByShopIdAndStoreIdAndReleaseTypeAndTicketStatusAndDeletedFalse(
        shopId: Long?,
        storeId: String?,
        releaseType: String,
        ticketStatus: DoPickOrderStatus
    ): List<DoPickOrder>

    fun findFirstByHandledByAndDeletedFalseAndTicketStatusIn(
        handledBy: Long,
        ticketStatus: List<String>
    ): DoPickOrder?
    fun findByRequiredDeliveryDateAndTicketStatusIn(
        requiredDeliveryDate: LocalDate,
        ticketStatus: List<DoPickOrderStatus>
    ): List<DoPickOrder>

    /**
     * Batch release: existing ticket same shop, same floor ([storeId]), same delivery date, still active.
     * [storeId] null means default-truck / XF-style row (matches NULL store_id on entity).
     */
    @Query(
        """
        SELECT d FROM DoPickOrder d
        WHERE d.deleted = false
          AND d.releaseType = 'batch'
          AND d.shopId = :shopId
          AND d.requiredDeliveryDate = :requiredDate
          AND d.ticketStatus IN :statuses
          AND (
            (:storeId IS NULL AND d.storeId IS NULL)
            OR (d.storeId = :storeId)
          )
        """
    )
    fun findMergeableBatchDoPickOrders(
        @Param("shopId") shopId: Long,
        @Param("storeId") storeId: String?,
        @Param("requiredDate") requiredDate: LocalDate,
        @Param("statuses") statuses: List<DoPickOrderStatus>,
    ): List<DoPickOrder>

    @Query("""
    SELECT dpo FROM DoPickOrder dpo
    WHERE dpo.storeId = :storeId
      AND dpo.requiredDeliveryDate = :requiredDeliveryDate
      AND dpo.ticketStatus IN :statuses
      AND EXISTS (
          SELECT 1 FROM DoPickOrderLine dpol 
          WHERE dpol.doPickOrderId = dpo.id
            AND dpol.deleted = false
            AND (dpol.status IS NULL OR dpol.status != 'issue')
      )
""")
fun findByStoreIdAndRequiredDeliveryDateAndTicketStatusInWithNonIssueLines(
    storeId: String,
    requiredDeliveryDate: LocalDate,
    statuses: List<DoPickOrderStatus>
): List<DoPickOrder>
}