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.entity.ItemsRepository
import com.ffii.fpsms.modules.master.web.models.MessageResponse
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLineRepository
import com.ffii.fpsms.modules.stock.entity.*
import com.ffii.fpsms.modules.stock.entity.projection.StockOutLineInfo
import com.ffii.fpsms.modules.stock.web.model.SaveStockOutLineRequest
import com.ffii.fpsms.modules.stock.web.model.SaveStockOutRequest
import com.ffii.fpsms.modules.stock.web.model.StockOutLineStatus
import com.ffii.fpsms.modules.stock.web.model.StockOutStatus
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.io.IOException
import java.time.LocalDate
import java.time.LocalDateTime

@Service
open class StockOutLineService(
    private val jdbcDao: JdbcDao,
    private val pickOrderLineRepository: PickOrderLineRepository,
    private val stockOutRepository: StockOutRepository,
    private val stockOutLineRepository: StockOutLIneRepository,
    private val itemRepository: ItemsRepository,
    private val inventoryRepository: InventoryRepository,
    private val inventoryLotLineRepository: InventoryLotLineRepository
    ): AbstractBaseEntityService<StockOutLine, Long, StockOutLIneRepository>(jdbcDao, stockOutLineRepository)  {
    @Throws(IOException::class)
    @Transactional
    open fun findAllByStockOutId(stockOutId: Long): List<StockOutLine> {
        return stockOutLineRepository.findAllByStockOutIdAndDeletedFalse(stockOutId)
    }
    @Throws(IOException::class)
    @Transactional
    open fun deleteById(id: Long): String {
        val deleteStockOutline = stockOutLineRepository.findById(id).orElseThrow().apply {
            deleted = true
        }
        val updateItem = stockOutLineRepository.save(deleteStockOutline)
        val response = "mark deleted item: ${updateItem.id}"
        return response
    }
    @Throws(IOException::class)
    @Transactional
    open fun deleteByStockOutId(id: Long): String {
        val deleteStockOutline = stockOutLineRepository.findAllByStockOutIdAndDeletedFalse(id).map {sol ->
            sol.apply {
                deleted = true
            }
        }
        val updateItemIds = stockOutLineRepository.saveAllAndFlush(deleteStockOutline).map { it.id }
        val response = "mark deleted items: $updateItemIds"
        return response
    }

    @Transactional
    open fun getAllStockOutLineByPickOrderLineId(pickOrderLineId: Long): List<StockOutLineInfo> {
        return stockOutLineRepository.findAllByPickOrderLineIdAndDeletedFalse(pickOrderLineId)
    }

    @Transactional
    open fun create(request: SaveStockOutLineRequest): MessageResponse {
        val stockOut = stockOutRepository.findByConsoPickOrderCode(request.consoCode).orElseThrow()
        val pickOrderLine = pickOrderLineRepository.findById(request.pickOrderLineId).orElseThrow()
        val item = itemRepository.findById(request.itemId).orElseThrow()
        val inventoryLotLine = inventoryLotLineRepository.findById(request.inventoryLotLineId).orElseThrow()
        val stockOutLine = StockOutLine()
            .apply {
                this.item = item
                this.qty = request.qty
                this.stockOut = stockOut
                this.inventoryLotLine
                this.pickOrderLine = pickOrderLine
                this.status = StockOutLineStatus.PENDING.status
            }
        val savedStockOutLine = saveAndFlush(stockOutLine)
        return MessageResponse(
            id = savedStockOutLine.id,
            name = savedStockOutLine.inventoryLotLine!!.inventoryLot!!.lotNo,
            code = savedStockOutLine.stockOut!!.consoPickOrderCode,
            type = savedStockOutLine.status,
            message = "success",
            errorPosition = null,
            entity = savedStockOutLine,
        )
    }

    @Transactional
    open fun update(request: SaveStockOutLineRequest) {
        val stockOutLine = stockOutLineRepository.findById(request.id!!).orElseThrow()
        
    }
}