package com.ffii.fpsms.modules.stock.service

import com.ffii.core.support.AbstractBaseEntityService
import com.ffii.core.support.JdbcDao
import com.ffii.fpsms.modules.master.web.models.MessageResponse
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrder
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderRepository
import com.ffii.fpsms.modules.stock.entity.*
import com.ffii.fpsms.modules.stock.web.model.SaveStockInRequest
import com.ffii.fpsms.modules.stock.web.model.StockInStatus
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.io.IOException
import kotlin.jvm.optionals.getOrNull
import java.time.LocalDate
import java.time.LocalDateTime
import java.util.*

@Service
open class StockInService(
    private val jdbcDao: JdbcDao,
    private val stockInRepository: StockInRepository,
    private val purchaseOrderRepository: PurchaseOrderRepository,
    private val stockTakeRepository: StockTakeRepository,
): AbstractBaseEntityService<StockIn, Long, StockInRepository>(jdbcDao, stockInRepository) {

    @Throws(IOException::class)
    @Transactional
    open fun create(request: SaveStockInRequest): MessageResponse {
        val stockIn = StockIn()
        stockIn.apply {
            status = StockInStatus.PENDING.status
            orderDate = LocalDateTime.now()
            code = request.code ?: LocalDateTime.now().toString().take(19)
        }
        if (request.purchaseOrderId != null) {
            val purchaseOrder : PurchaseOrder = purchaseOrderRepository.findByIdAndDeletedFalse(request.purchaseOrderId).orElseThrow();
            stockIn.apply {
                code = purchaseOrder.code
                supplier = purchaseOrder.supplier
                this.purchaseOrder = purchaseOrder
                //            shop = purchaseOrder.shop
                orderDate = purchaseOrder.orderDate
                estimatedCompleteDate = purchaseOrder.estimatedArrivalDate?.toLocalDate()
                completeDate = purchaseOrder.completeDate
            }
        }
        if (request.stockTakeId != null) {
            val stockTake = request.stockTakeId.let { stockTakeRepository.findByIdAndDeletedIsFalse(it) }
            stockIn.apply {
                this.stockTake = stockTake
            }
        }

        val savedStockIn = saveAndFlush(stockIn)
        return MessageResponse(
            id = savedStockIn.id,
            code = savedStockIn.code,
            name = savedStockIn.code,
            type = "stock in created: status = ${savedStockIn.status}",
            message = "save success",
            errorPosition = null,
            entity = savedStockIn
        )
    }
}