package com.ffii.fpsms.modules.master.service

import com.ffii.core.support.AbstractBaseEntityService
import com.ffii.core.support.JdbcDao
import com.ffii.fpsms.modules.master.entity.EquipmentType
import com.ffii.fpsms.modules.master.entity.EquipmentTypeRepository
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import com.ffii.fpsms.modules.master.web.models.NewEquipmentTypeRequest
@Service
open class EquipmentTypeService(
    private val jdbcDao: JdbcDao,
    private val equipmentTypeRepository: EquipmentTypeRepository,
) : AbstractBaseEntityService<EquipmentType, Long, EquipmentTypeRepository>(jdbcDao, equipmentTypeRepository) {

    open fun allEquipmentTypes(): List<EquipmentType> {
        return equipmentTypeRepository.findAll()
    }

    open fun getEquipmentTypesByPage(args: Map<String, Any>): List<Map<String, Any>> {
        val sql = StringBuilder(
            "SELECT e.id, e.code, e.name, e.description FROM equipment_type e WHERE e.deleted = FALSE"
        )
        if (args.containsKey("code")) {
            sql.append(" AND e.code like :code ")
        }
        if (args.containsKey("id")) {
            sql.append(" AND e.id like :id ")
        }
        if (args.containsKey("name")) {
            sql.append(" AND e.name like :name ")
        }
        if (args.containsKey("description")) {
            sql.append(" AND e.description like :description ")
        }
        return jdbcDao.queryForList(sql.toString(), args)
    }

    open fun findById(id: Long): EquipmentType? {
        return equipmentTypeRepository.findByIdAndDeletedFalse(id)
    }

    open fun findByCode(code: String): EquipmentType? {
        return equipmentTypeRepository.findByCodeAndDeletedIsFalse(code)
    }

    open fun findByName(name: String): EquipmentType? {
        return equipmentTypeRepository.findByNameAndDeletedIsFalse(name)
    }

    open fun findByDescription(description: String): EquipmentType? {
        return equipmentTypeRepository.findByDescriptionAndDeletedIsFalse(description)
    }

    @Transactional
    open fun saveEquipmentType(request: NewEquipmentTypeRequest): EquipmentType {

        if (request.code.isNullOrBlank()) {
            throw IllegalArgumentException("Equipment type code cannot be null or blank")
        }
        val duplicated = equipmentTypeRepository.findByCodeAndDeletedFalse(request.code!!)
        if (duplicated != null && duplicated.id != request.id) {
            throw IllegalArgumentException("Equipment type code already exists")
        }


        val entity = if (request.id != null && request.id > 0) {

            equipmentTypeRepository.findByIdAndDeletedFalse(request.id) ?: EquipmentType()
        } else {
            EquipmentType()
        }


        entity.code = request.code
        entity.name = request.name
        entity.description = request.description

        return equipmentTypeRepository.saveAndFlush(entity)
    }

    @Transactional
    open fun deleteEquipmentType(id: Long) {
        val equipmentType = equipmentTypeRepository.findByIdAndDeletedFalse(id)
        equipmentType?.let { et ->
            et.deleted = true
            equipmentTypeRepository.saveAndFlush(et)
        }
    }
}