package com.ffii.fpsms.modules.productProcess.entity

import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import java.time.LocalDateTime

interface JobOrderLineStatusAggregate {
    val jobOrderId: Long
    val totalLines: Long
    val doneLines: Long
}

@Repository
interface ProductProcessLineRepository : JpaRepository<ProductProcessLine, Long> {
    fun findByProductProcess_Id(productProcessId: Long): List<ProductProcessLine>
    fun findByProductProcess_IdAndHandler_Id(productProcessId: Long, handlerId: Long): List<ProductProcessLine>
    fun findByHandler_IdAndStartTimeIsNotNullAndEndTimeIsNull(handlerId: Long): List<ProductProcessLine>
    fun findByProductProcess_IdIn(ids: List<Long>): List<ProductProcessLine>

    @Query("""
        SELECT l
        FROM ProductProcessLine l
        LEFT JOIN FETCH l.operator
        LEFT JOIN FETCH l.equipment
        WHERE l.deleted = false
          AND l.productProcess.id IN :ids
    """)
    fun findByProductProcess_IdInWithOperatorAndEquipment(@Param("ids") ids: List<Long>): List<ProductProcessLine>

    @Query(
        """
        SELECT 
            p.jobOrder.id AS jobOrderId,
            COUNT(l.id) AS totalLines,
            SUM(CASE WHEN l.status IN ('Completed', 'Pass') THEN 1 ELSE 0 END) AS doneLines
        FROM ProductProcessLine l
        JOIN l.productProcess p
        WHERE l.deleted = false
          AND p.deleted = false
          AND p.jobOrder IS NOT NULL
          AND p.jobOrder.id IN :jobOrderIds
        GROUP BY p.jobOrder.id
        """
    )
    fun countLineStatusByJobOrderIds(@Param("jobOrderIds") jobOrderIds: Collection<Long>): List<JobOrderLineStatusAggregate>

    @Query("SELECT l FROM ProductProcessLine l LEFT JOIN FETCH l.equipment WHERE l.productProcess.id = :productProcessId")
    fun findByProductProcess_IdWithEquipment(productProcessId: Long): List<ProductProcessLine>

    // 用於 Operator KPI：抓取在指定時間範圍內有重疊的所有行
    @Query(
        """
        SELECT l FROM ProductProcessLine l
        WHERE l.deleted = false
          AND l.startTime IS NOT NULL
          AND (
            (l.startTime <= :endOfDay AND (l.endTime IS NULL OR l.endTime >= :startOfDay))
          )
        """
    )
    fun findAllOverlappingWithDateRange(startOfDay: LocalDateTime, endOfDay: LocalDateTime): List<ProductProcessLine>

    // 用於 Equipment 狀態：查詢指定 equipmentDetailId 目前仍未完成的所有行
    fun findByEquipmentDetailIdAndDeletedFalseAndEndTimeIsNull(equipmentDetailId: Long): List<ProductProcessLine>
}