package com.ffii.fpsms.py

import com.ffii.fpsms.modules.jobOrder.entity.JobOrderRepository
import com.ffii.fpsms.py.entity.PyJobOrderPrintSubmit
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.server.ResponseStatusException

@Service
open class PyJobOrderPrintSubmitService(
    private val repository: PyJobOrderPrintSubmitRepository,
    private val jobOrderRepository: JobOrderRepository,
) {

    /**
     * Cumulative printed qty per job order, split by channel (打袋 / 標籤 / 激光).
     */
    open fun sumPrintedQtyByJobOrderIds(ids: List<Long>): Map<Long, PrintedQtyByChannel> {
        if (ids.isEmpty()) return emptyMap()
        val rows = repository.sumQtyGroupedByJobOrderIdAndChannel(ids)
        val out = mutableMapOf<Long, PrintedQtyByChannel>()
        for (row in rows) {
            val jobOrderId = (row[0] as Number).toLong()
            val channel = (row[1] as String).trim()
            val qty = (row[2] as Number).toLong()
            val cur = out.getOrDefault(jobOrderId, PrintedQtyByChannel())
            out[jobOrderId] =
                when (channel) {
                    PyPrintChannel.DATAFLEX -> cur.copy(bagPrintedQty = qty)
                    PyPrintChannel.LABEL -> cur.copy(labelPrintedQty = qty)
                    PyPrintChannel.LASER -> cur.copy(laserPrintedQty = qty)
                    else -> cur
                }
        }
        return out
    }

    private fun sumPrintedByJobOrderIdsAndChannel(ids: List<Long>, channel: String): Map<Long, Long> {
        if (ids.isEmpty()) return emptyMap()
        val rows = repository.sumQtyGroupedByJobOrderId(ids, channel)
        return rows.associate { row ->
            (row[0] as Number).toLong() to (row[1] as Number).toLong()
        }
    }

    /**
     * Persist one submit row and return cumulative print total for that job order and channel.
     */
    @Transactional
    open fun recordPrint(jobOrderId: Long, qty: Int, printChannel: String): PyJobOrderPrintSubmitResponse {
        if (qty < 1) {
            throw ResponseStatusException(HttpStatus.BAD_REQUEST, "qty must be at least 1")
        }
        val jo = jobOrderRepository.findById(jobOrderId).orElseThrow {
            ResponseStatusException(HttpStatus.NOT_FOUND, "Job order not found: $jobOrderId")
        }
        val row = PyJobOrderPrintSubmit().apply {
            jobOrder = jo
            this.qty = qty
            this.printChannel = printChannel
        }
        repository.save(row)
        val total = sumPrintedByJobOrderIdsAndChannel(listOf(jobOrderId), printChannel)[jobOrderId] ?: qty.toLong()
        return PyJobOrderPrintSubmitResponse(
            jobOrderId = jobOrderId,
            submittedQty = qty,
            printChannel = printChannel,
            cumulativeQtyForChannel = total,
        )
    }
}
