package com.ffii.fpsms.modules.master.entity

import com.ffii.core.support.AbstractRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.stereotype.Repository
import java.io.Serializable

@Repository
interface ItemUomRespository : AbstractRepository<ItemUom, Long> {
    fun findAllByItemIdAndDeletedIsFalse(itemId: Serializable): List<ItemUom>

    /** All active item_uom rows with uom_conversion (single round-trip for master-data scans). */
    @Query(
        """
        SELECT iu FROM ItemUom iu
        JOIN FETCH iu.uom
        JOIN FETCH iu.item i
        WHERE iu.deleted = false AND i.deleted = false
        """,
    )
    fun findAllActiveWithUom(): List<ItemUom>

    /** Soft-deleted item_uom rows (for master-data issue snapshots). */
    @Query(
        """
        SELECT iu FROM ItemUom iu
        JOIN FETCH iu.uom
        JOIN FETCH iu.item i
        WHERE iu.deleted = true AND i.deleted = false
        """,
    )
    fun findAllDeletedWithUom(): List<ItemUom>

    fun findByIdAndDeletedIsFalse(id: Serializable): ItemUom?

    fun findByM18IdAndDeletedIsFalse(m18Id: Serializable): ItemUom?

    /** Includes soft-deleted rows — used by [com.ffii.fpsms.modules.master.service.ItemUomService.saveItemUom] to reactivate. */
    fun findFirstByM18IdOrderByIdDesc(m18Id: Long): ItemUom?

    fun deleteAllByIdIn(id: List<Serializable>)

    fun findByItemIdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemId: Serializable): ItemUom?

    fun findByItemIdAndSalesUnitIsTrueAndDeletedIsFalse(itemId: Serializable): ItemUom?
    fun findByItemIdAndStockUnitIsTrueAndDeletedIsFalse(itemId: Serializable): ItemUom?

    fun findByItemIdAndBaseUnitIsTrueAndDeletedIsFalse(itemId: Serializable): ItemUom?
    fun findByItemIdAndPickingUnitIsTrueAndDeletedIsFalse(itemId: Serializable): ItemUom?

    fun findByItemM18IdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemM18Id: Long): ItemUom?
    fun findBaseUnitByItemIdAndStockUnitIsTrueAndDeletedIsFalse(itemId: Long): ItemUom?
    fun findFirstByItemIdAndUomIdAndDeletedIsFalse(itemId: Long, uomId: Long): ItemUom?
    fun findByItemIdAndUomIdAndStockUnitAndDeletedIsFalse(itemId: Long, uomId: Long, stockUnit: Boolean): ItemUom?

    fun findFirstByItemIdAndStockUnitIsTrueAndDeletedIsFalseOrderByIdAsc(itemId: Long): ItemUom?
    fun findAllByItemIdInAndStockUnitIsTrueAndDeletedIsFalse(itemIds: Collection<Long>): List<ItemUom>

    @Query(
        """
        SELECT DISTINCT iu.item.m18Id
        FROM ItemUom iu
        WHERE iu.deleted = false
          AND iu.item.deleted = false
          AND iu.item.m18Id IS NOT NULL
          AND EXISTS (
            SELECT 1
            FROM ItemUom iub
            WHERE iub.item.id = iu.item.id
              AND iub.deleted = false
              AND iub.baseUnit = true
              AND iub.uom.id = 4
          )
          AND (
            (iu.uom.id = 4 AND NOT (iu.ratioN = 1 AND iu.ratioD = 1))
            OR
            (iu.uom.id = 785 AND NOT (iu.ratioN = 2268 AND iu.ratioD = 5))
          )
        """
    )
    fun findDistinctProblemItemM18IdsForUomResync(): List<Long>
}