package com.ffii.fpsms.modules.jobOrder.service

import OperatorRequest
import com.ffii.core.response.RecordsRes
import com.ffii.core.support.AbstractBaseEntityService
import com.ffii.core.support.JdbcDao
import com.ffii.fpsms.m18.entity.M18DataLogRepository
import com.ffii.fpsms.modules.jobOrder.entity.JobOrderProcess
import com.ffii.fpsms.modules.jobOrder.entity.JobOrderProcessRepository
import com.ffii.fpsms.modules.jobOrder.entity.JobOrderRepository
import com.ffii.fpsms.modules.jobOrder.web.model.CreateJobOrderProcessRequest
import com.ffii.fpsms.modules.jobOrder.web.model.MachineRequest
import com.ffii.fpsms.modules.jobOrder.web.model.OperatorResponse
import com.ffii.fpsms.modules.master.entity.ProcessRepository
import com.ffii.fpsms.modules.master.entity.ShopRepository
import com.ffii.fpsms.modules.master.service.CurrencyService
import com.ffii.fpsms.modules.master.service.ShopService
import com.ffii.fpsms.modules.master.web.models.MessageResponse
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrder
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderLineRepository
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderRepository
import com.ffii.fpsms.modules.purchaseOrder.entity.projections.PoLineWithStockInLine
import com.ffii.fpsms.modules.purchaseOrder.entity.projections.PurchaseOrderDataClass
import com.ffii.fpsms.modules.purchaseOrder.entity.projections.PurchaseOrderInfo
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType
import com.ffii.fpsms.modules.purchaseOrder.web.model.PagingRequest
import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderRequest
import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderResponse
import com.ffii.fpsms.modules.stock.entity.StockInLine
import com.ffii.fpsms.modules.stock.entity.StockInLineRepository
import com.ffii.fpsms.modules.stock.entity.StockInRepository
import com.ffii.fpsms.modules.stock.web.model.StockInLineStatus
import com.ffii.fpsms.modules.user.entity.UserRepository
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.io.IOException
import java.math.BigDecimal
import java.util.HashMap
import java.util.Objects
import kotlin.jvm.optionals.getOrDefault
import kotlin.jvm.optionals.getOrNull

@Service
open class JobOrderProcessService(
    private val jdbcDao: JdbcDao,
    private val jobOrderProcessRepository: JobOrderProcessRepository,
    private val userRepository: UserRepository, private val processRepository: ProcessRepository,
    private val jobOrderRepository: JobOrderRepository,
) : AbstractBaseEntityService<JobOrderProcess, Long, JobOrderProcessRepository>(jdbcDao, jobOrderProcessRepository) {

    open fun createJobOrderProcessRequests(joId: Long): List<CreateJobOrderProcessRequest> {
        val zero = BigDecimal.ZERO
        val jo = jobOrderRepository.findById(joId).getOrNull() ?: throw NoSuchElementException()

        val jopRequests = jo.bom?.bomProcesses?.map { bp ->
            CreateJobOrderProcessRequest(
                joId = jo.id,
                processId = bp.process?.id,
                seqNo = bp.seqNo,
            )
        } ?: listOf();

        return jopRequests
    }

    open fun createJobOrderProcesses(request: List<CreateJobOrderProcessRequest>): MessageResponse{
        val joProcesses = request.map { req ->
            val jo = req.joId?.let { jobOrderRepository.findById(it).getOrNull() }
            val process = req.processId?.let { processRepository.findById(it).getOrNull() }

            JobOrderProcess().apply {
                this.jo = jo
                this.process = process
                status = req.status
                seqNo = req.seqNo
                remarks = req.remarks
            }
        }

        jobOrderProcessRepository.saveAll(joProcesses)

        return MessageResponse(
            id = null,
            name = null,
            code = null,
            type = null,
            message = "Success",
            errorPosition = null
        )
    }

    open fun isOperatorExist(request: OperatorRequest): MessageResponse{
        val User =  userRepository.findByUsernameAndDeletedFalse(request.username)

        if(User.isPresent){
            return MessageResponse(
                id = User.get().id,
                name = User.get().name,
                code = null,
                type = null,
                message = "Success",
                errorPosition = null,
                entity = User.get().let { user ->
                    OperatorResponse(
                        id = user.id,
                        name = user.name,
                        username = user.username
                    )
                }
            )
        }else{
            return MessageResponse(
                id = null,
                name = null,
                code = null,
                type = null,
                message = "Unsuccess",
                errorPosition = null,
                entity = null,
            )
        }
    }

    fun createJobOrderProcessesByJoId(joId: Long): MessageResponse {
        return createJobOrderProcesses(createJobOrderProcessRequests(joId));
    }

//    open fun isCorrectMachineUsed(request: MachineRequest): MessageResponse{
//        // Further development, this with check equipment for the job process
//
//        if(User.isPresent){
//            return MessageResponse(
//                id = User.get().id,
//                name = User.get().name,
//                code = null,
//                type = null,
//                message = "Success",
//                errorPosition = null,
//                entity = User.get().let { user ->
//                    OperatorResponse(
//                        id = user.id,
//                        name = user.name,
//                        username = user.username
//                    )
//                }
//            )
//        }else{
//            return MessageResponse(
//                id = null,
//                name = null,
//                code = null,
//                type = null,
//                message = "Unsuccess",
//                errorPosition = null,
//                entity = null,
//            )
//        }
//    }

}