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

import com.ffii.core.support.AbstractRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import org.springframework.stereotype.Repository
import java.time.LocalDate

@Repository
interface DoReplenishmentRepository : AbstractRepository<DoReplenishment, Long> {

    fun findByCodeAndDeletedIsFalse(code: String): DoReplenishment?

    fun existsBySourceDoLineIdAndStatusAndDeletedIsFalse(sourceDoLineId: Long, status: String): Boolean

    fun findFirstBySourceDoLineIdAndStatusAndDeletedIsFalse(
        sourceDoLineId: Long,
        status: String,
    ): DoReplenishment?

    fun findByTargetDoIdInAndDeletedIsFalse(targetDoIds: Collection<Long>): List<DoReplenishment>

    fun findFirstByPickOrderLineIdAndStatusAndDeletedIsFalse(
        pickOrderLineId: Long,
        status: String,
    ): DoReplenishment?

    fun findByDeliveryOrderPickOrderIdAndStatusAndDeletedIsFalse(
        deliveryOrderPickOrderId: Long,
        status: String,
    ): List<DoReplenishment>

    @Query(
        """
        SELECT r FROM DoReplenishment r
        LEFT JOIN DeliveryOrderPickOrder dopo ON dopo.id = r.deliveryOrderPickOrderId AND dopo.deleted = false
        WHERE r.deleted = false
          AND (
            :deliveryDate IS NULL
            OR (
              dopo.id IS NOT NULL
              AND dopo.requiredDeliveryDate = :deliveryDate
            )
            OR (
              dopo.id IS NULL
              AND r.deliveryDate = :deliveryDate
            )
          )
          AND (:status IS NULL OR r.status = :status)
        ORDER BY r.created DESC, r.id DESC
        """,
    )
    fun search(
        @Param("deliveryDate") deliveryDate: LocalDate?,
        @Param("status") status: String?,
    ): List<DoReplenishment>

    @Query(
        """
        SELECT r FROM DoReplenishment r
        WHERE r.deleted = false
          AND r.status = :status
          AND (
            :truckLaneCode IS NULL OR :truckLaneCode = ''
            OR LOWER(COALESCE(r.truckLaneCode, '')) LIKE LOWER(CONCAT('%', :truckLaneCode, '%'))
          )
          AND (
            :shopName IS NULL OR :shopName = ''
            OR LOWER(COALESCE(r.shopName, '')) LIKE LOWER(CONCAT('%', :shopName, '%'))
            OR LOWER(COALESCE(r.shopCode, '')) LIKE LOWER(CONCAT('%', :shopName, '%'))
          )
        ORDER BY r.shopName, r.shopCode, r.code
        """,
    )
    fun searchForBatchRelease(
        @Param("status") status: String,
        @Param("truckLaneCode") truckLaneCode: String?,
        @Param("shopName") shopName: String?,
    ): List<DoReplenishment>

    @Query(
        """
        SELECT r.code FROM DoReplenishment r
        WHERE r.deleted = false
          AND r.code LIKE CONCAT(:codePrefix, '%')
        """,
    )
    fun findCodesByPrefix(@Param("codePrefix") codePrefix: String): List<String>
}
