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

import com.ffii.fpsms.modules.master.entity.Printer
import com.ffii.fpsms.modules.master.entity.PrinterRepository
import com.ffii.fpsms.modules.master.entity.projections.PrinterCombo
import jakarta.persistence.OptimisticLockException
import org.slf4j.Logger
import org.slf4j.LoggerFactory
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 PrinterService(
    val printerRepository: PrinterRepository
) {
    private val logger: Logger = LoggerFactory.getLogger(PrinterService::class.java)
    
    open fun getPrinters(): List<Printer> {
        return printerRepository.findAllByDeletedIsFalse();
    }
    
    open fun findCombo(): List<PrinterCombo> {
        return printerRepository.findPrinterComboByDeletedFalse();
    }

    open fun findById(id: Long): Printer? {
        return printerRepository.findByIdAndDeletedFalse(id)
    }
    
    open fun getDistinctDescriptions(): List<String> {
        return printerRepository.findDistinctDescriptionsByDeletedIsFalse()
    }
    
    @Transactional
    open fun createPrinter(request: com.ffii.fpsms.modules.master.web.PrinterCreateRequest): Printer {
        try {
            val printer = Printer().apply {
                name = request.name
                code = request.code
                type = request.type
                brand = if (request.type == "Label") "Zebra" else request.brand
                description = request.description
                ip = request.ip
                port = request.port
                dpi = request.dpi
            }

            return printerRepository.save(printer)
        } catch (e: OptimisticLockException) {
            logger.error("Optimistic lock exception when creating printer", e)
            throw ResponseStatusException(
                HttpStatus.CONFLICT,
                "Printer was modified by another user. Please refresh and try again."
            )
        } catch (e: ResponseStatusException) {
            throw e
        } catch (e: Exception) {
            logger.error("Error creating printer", e)
            throw ResponseStatusException(
                HttpStatus.INTERNAL_SERVER_ERROR,
                "Failed to create printer: ${e.message ?: "Unknown error"}"
            )
        }
    }

    @Transactional
    open fun updatePrinter(id: Long, request: com.ffii.fpsms.modules.master.web.PrinterUpdateRequest): Printer {
        try {
            val printer = printerRepository.findById(id).orElseThrow {
                ResponseStatusException(HttpStatus.NOT_FOUND, "Printer with id $id not found")
            }
            
            request.name?.let { printer.name = it }
            request.code?.let { printer.code = it }
            request.type?.let { printer.type = it }
            request.type?.let { newType ->
                printer.type = newType
                if (newType == "Label") {
                    printer.brand = "Zebra"
                }
            }

            request.brand?.let { newBrand ->
                if (printer.type != "Label") {
                    printer.brand = newBrand
                }
            }
            request.description?.let { printer.description = it }
            request.ip?.let { printer.ip = it }
            request.port?.let { printer.port = it }
            request.dpi?.let { printer.dpi = it }
            
            return printerRepository.save(printer)
        } catch (e: OptimisticLockException) {
            logger.error("Optimistic lock exception when updating printer with id $id", e)
            throw ResponseStatusException(
                HttpStatus.CONFLICT,
                "Printer was modified by another user. Please refresh and try again."
            )
        } catch (e: ResponseStatusException) {
            throw e
        } catch (e: Exception) {
            logger.error("Error updating printer with id $id", e)
            throw ResponseStatusException(
                HttpStatus.INTERNAL_SERVER_ERROR,
                "Failed to update printer: ${e.message ?: "Unknown error"}"
            )
        }
    }
    
    @Transactional
    open fun markDeleted(id: Long): List<Printer> {
        try {
            val printer = printerRepository.findById(id).orElseThrow {
                ResponseStatusException(HttpStatus.NOT_FOUND, "Printer with id $id not found")
            }
            
            printer.deleted = true
            printerRepository.save(printer)
            
            return getPrinters()
        } catch (e: OptimisticLockException) {
            logger.error("Optimistic lock exception when deleting printer with id $id", e)
            throw ResponseStatusException(
                HttpStatus.CONFLICT,
                "Printer was modified by another user. Please refresh and try again."
            )
        } catch (e: ResponseStatusException) {
            throw e
        } catch (e: Exception) {
            logger.error("Error deleting printer with id $id", e)
            throw ResponseStatusException(
                HttpStatus.INTERNAL_SERVER_ERROR,
                "Failed to delete printer: ${e.message ?: "Unknown error"}"
            )
        }
    }
}