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

import com.ffii.core.response.RecordsRes
import com.ffii.fpsms.modules.jobOrder.entity.JobOrder
import com.ffii.fpsms.modules.jobOrder.entity.JobOrderRepository
import com.ffii.fpsms.modules.jobOrder.entity.projections.JobOrderInfo
import com.ffii.fpsms.modules.jobOrder.web.model.CreateJobOrderRequest
import com.ffii.fpsms.modules.jobOrder.web.model.SearchJobOrderInfoRequest
import com.ffii.fpsms.modules.master.entity.ProductionScheduleLineRepository
import com.ffii.fpsms.modules.master.service.BomService
import com.ffii.fpsms.modules.master.web.models.MessageResponse
import com.ffii.fpsms.modules.user.service.UserService
import org.springframework.data.domain.PageRequest
import org.springframework.stereotype.Service
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import kotlin.jvm.optionals.getOrNull

@Service
open class JobOrderService(
    val jobOrderRepository: JobOrderRepository,
    val bomService: BomService,
    val userService: UserService,
    val productionScheduleLineRepository: ProductionScheduleLineRepository,
) {
    open fun allJobOrdersByPage(request: SearchJobOrderInfoRequest): RecordsRes<JobOrderInfo> {
        val pageable = PageRequest.of(request.pageNum ?: 0, request.pageSize ?: 10);

        val response = jobOrderRepository.findJobOrderInfoByCodeContainsAndBomNameContainsAndDeletedIsFalseOrderByIdDesc(
            code = request.code ?: "",
            bomName = request.name ?: "",
            pageable = pageable
        )

        val records = response.content
        val total = response.totalElements
        return RecordsRes<JobOrderInfo>(records, total.toInt());
    }
    open fun assignJobNo(): String {
        val suffixFormat = "%03d"
        val pattern = "yyyyMMdd"
        val formatter = DateTimeFormatter.ofPattern(pattern)

        val prefix = "JO"
        val midfix = LocalDate.now().format(formatter)
        val suffix = String.format(suffixFormat, 1)

        val latestCode = jobOrderRepository.findLatestCodeByPrefix("${prefix}-${midfix}")
        if (latestCode != null) {
            val splitLatestCode = latestCode.split("-")
            if (splitLatestCode.size > 2) {
                val latestNo = splitLatestCode[2].toInt()
                return listOf<String>(prefix, midfix, String.format(suffixFormat, latestNo + 1)).joinToString("-")
            }
        }

        return listOf<String>(prefix, midfix, suffix).joinToString("-")
    }

    open fun createJobOrder(request: CreateJobOrderRequest): MessageResponse {
        val jo = JobOrder()
        val bom = request.bomId?.let { bomService.findById(it) }
        val approver = request.approverId?.let { userService.find(it).getOrNull() }
        val prodScheduleLine = request.prodScheduleLineId?.let { productionScheduleLineRepository.findById(it).getOrNull() }
        val code = assignJobNo()

        jo.apply {
            this.code = code
            this.bom = bom
            //TODO: planStart & planEnd
            planStart = LocalDateTime.now()
            planEnd = LocalDateTime.now()
            reqQty = request.reqQty
            status = request.status
            type = request.type
            this.approver = approver
            this.prodScheduleLine = prodScheduleLine
        }

        val savedJo = jobOrderRepository.saveAndFlush(jo);

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