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

import com.ffii.core.support.AbstractRepository
import com.ffii.fpsms.modules.master.entity.projections.DetailedProdScheduleLineBomMaterial
import com.ffii.fpsms.modules.master.entity.projections.DetailedProdScheduleLineBomMaterialInterface
import org.springframework.data.jpa.repository.Query
import org.springframework.stereotype.Repository
import java.time.LocalDateTime

@Repository
interface ProductionScheduleLineRepository : AbstractRepository<ProductionScheduleLine, Long> {
    @Query(nativeQuery = true,
        value = """
            with prod_prop as (
                select 
                    psl.id as pslId,
                    -- round(coalesce(psl.prodQty, 0) / coalesce(b.outputQty, 1), 5) as proportion
                    1 as proportion
                from production_schedule_line psl
                left join bom b on b.itemId = psl.itemId
                where psl.id = :id and b.id is not null
            )
            select
                psl.id as pslId,
                bm.id,
                b.outputQty as bomOutputQty,
                bmi.code,
                bmi.name,
                bmi.`type`,
                coalesce(i.onHandQty, 0) - coalesce(i.onHoldQty, 0) - coalesce(i.unavailableQty, 0) as availableQty,
                ceil(coalesce(bm.qty, 0) * pp.proportion) as demandQty
            from production_schedule_line psl
            left join prod_prop pp on pp.pslId = psl.id
            left join bom b on b.itemId = psl.itemId 
            left join bom_material bm on bm.bomId = b.id
            left join items bmi on bmi.id = bm.itemId
            left join inventory i on i.itemId = bmi.id
            where psl.id = :id and bmi.id is not null
            group by psl.id, bm.id, i.id, pp.proportion
        """)
    fun getBomMaterials(id: Long): List<DetailedProdScheduleLineBomMaterialInterface>?
    
    @Query("""
    SELECT psl FROM ProductionScheduleLine psl 
    JOIN psl.productionSchedule ps 
    WHERE psl.item.id = :itemId 
    AND ps.produceAt = :produceAt 
    AND psl.type = :type 
    AND ps.deleted = false
    ORDER BY psl.itemPriority ASC
    """)
    fun findByItemIdAndProduceAtAndType(
        itemId: Long, 
        produceAt: LocalDateTime, 
        type: String
    ): ProductionScheduleLine?
}