package com.ffii.fpsms.modules.logistic.service

import com.ffii.fpsms.modules.logistic.entity.Logistic
import com.ffii.fpsms.modules.logistic.entity.LogisticRepository
import com.ffii.fpsms.modules.logistic.web.models.SaveLogisticRequest
import jakarta.transaction.Transactional
import org.springframework.stereotype.Service
import org.springframework.web.server.ResponseStatusException
import org.springframework.http.HttpStatus

@Service
open class LogisticService(
    private val logisticRepository: LogisticRepository,
) {
    open fun findAll(): List<Logistic> {
        return logisticRepository.findAllByDeletedFalseOrderByIdAsc()
    }

    open fun findById(id: Long): Logistic? {
        return logisticRepository.findByIdAndDeletedFalse(id)
    }

    open fun requireById(id: Long): Logistic {
        return logisticRepository.findByIdAndDeletedFalse(id)
            ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Logistic not found with id: $id")
    }

    @Transactional
    open fun save(request: SaveLogisticRequest): Logistic {
        val entity = request.id?.let { requireById(it) } ?: Logistic()

        entity.apply {
            logisticName = request.logisticName.trim()
            carPlate = request.carPlate.trim()
            driverName = request.driverName.trim()
            driverNumber = request.driverNumber
        }

        return logisticRepository.save(entity)
    }

    /**
     * 批次「新增」物流主檔：同一交易內寫入，任一筆失敗則整批 rollback。
     * 供看板一次儲存多筆暫存主檔，避免逐筆 POST 中途失敗留下孤兒列。
     */
    @Transactional
    open fun saveBatchCreate(requests: List<SaveLogisticRequest>): List<Logistic> {
        if (requests.isEmpty()) return emptyList()
        if (requests.size > 100) {
            throw ResponseStatusException(
                HttpStatus.BAD_REQUEST,
                "Batch size exceeds limit (100)",
            )
        }
        requests.forEach { r ->
            if (r.id != null) {
                throw ResponseStatusException(
                    HttpStatus.BAD_REQUEST,
                    "save-batch only accepts new rows (id must be null)",
                )
            }
        }
        return requests.map { req ->
            val entity = Logistic().apply {
                logisticName = req.logisticName.trim()
                carPlate = req.carPlate.trim()
                driverName = req.driverName.trim()
                driverNumber = req.driverNumber
            }
            logisticRepository.save(entity)
        }
    }

    @Transactional
    open fun deleteById(id: Long): String {
        val entity = requireById(id)
        entity.deleted = true
        logisticRepository.save(entity)
        return "Logistic deleted successfully with id: $id"
    }
}

