package com.ffii.fpsms.m18.service

import com.ffii.core.utils.JwtTokenUtil
import com.ffii.fpsms.api.service.ApiCallerService
import com.ffii.fpsms.m18.M18Config
import com.ffii.fpsms.m18.enums.M18DataLogStatus
import com.ffii.fpsms.m18.model.*
import com.ffii.fpsms.m18.model.SyncResult
import com.ffii.fpsms.m18.utils.CommonUtils
import com.ffii.fpsms.m18.web.models.M18CommonRequest
import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderLineStatus
import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderStatus
import com.ffii.fpsms.modules.deliveryOrder.service.DeliveryOrderLineService
import com.ffii.fpsms.modules.deliveryOrder.service.DeliveryOrderService
import com.ffii.fpsms.modules.deliveryOrder.entity.DeliveryOrderRepository
import com.ffii.fpsms.modules.deliveryOrder.web.models.SaveDeliveryOrderLineRequest
import com.ffii.fpsms.modules.deliveryOrder.web.models.SaveDeliveryOrderRequest
import com.ffii.fpsms.modules.master.entity.ItemUom
import com.ffii.fpsms.modules.master.service.ItemUomService
import com.ffii.fpsms.modules.master.service.ItemsService
import com.ffii.fpsms.modules.master.service.ShopService
import com.ffii.fpsms.modules.master.web.models.ConvertUomByItemRequest
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import java.sql.SQLException
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import kotlin.reflect.full.memberProperties
import kotlin.text.substring

@Service
open class M18DeliveryOrderService(
    val m18Config: M18Config,
    val apiCallerService: ApiCallerService,
    val m18DataLogService: M18DataLogService,
    val deliveryOrderService: DeliveryOrderService,
    val deliveryOrderRepository: DeliveryOrderRepository,
    val deliveryOrderLineService: DeliveryOrderLineService,
    val itemsService: ItemsService,
    val shopService: ShopService,
    val itemUomService: ItemUomService,
    val m18MasterDataService: M18MasterDataService,
) {
    val commonUtils = CommonUtils()
    val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java)

    val lastModifyDateStart = "2025-05-14 14:00:00"
    val lastModifyDateEnd = "2025-05-14 14:30:00"
//    val lastModifyDateConds =
//        "lastModifyDate=largerOrEqual=${lastModifyDateStart}=and=lastModifyDate=lessOrEqual=${lastModifyDateEnd}"
//    val lastModifyDate = LocalDateTime.now().minusMinutes(30)
//    val commonConds =
//        "(beId=equal=${m18Config.BEID_PF}=or=beId=equal=${m18Config.BEID_PP}=or=beId=equal=${m18Config.BEID_TOA})=and=lastModifyDate=largerOrEqual=${lastModifyDate}"

    // M18 API
    // Sharing same API with po
    val M18_LOAD_PURCHASE_ORDER_API = "/root/api/read/po"
    val M18_FETCH_PURCHASE_ORDER_LIST_API = "/search/search"

    // Include shop po
    open fun getDeliveryOrdersWithType(request: M18CommonRequest): M18PurchaseOrderListResponseWithType? {
        val deliveryOrders = M18PurchaseOrderListResponseWithType(mutableListOf())
        val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")

        val lastDateConds = if (request.modifiedDateFrom != null && request.modifiedDateTo != null) {
            val dateFrom = LocalDateTime.parse(request.modifiedDateFrom, formatter).toString()
            val dateTo = LocalDateTime.parse(request.modifiedDateTo, formatter).toString()
            
            "lastModifyDate=largerOrEqual=$dateFrom=and=lastModifyDate=lessOrEqual=$dateTo"
        } else {
            ""
        }

        val dDateConds = if (request.dDateFrom != null && request.dDateTo != null) {
            val dateFrom = LocalDateTime.parse(request.dDateFrom, formatter).toLocalDate().toString()
            val dateTo = LocalDateTime.parse(request.dDateTo, formatter).toLocalDate().toString()
            
            "dDate=largerOrEqual=$dateFrom=and=dDate=lessOrEqual=$dateTo"
        } else {
            ""
        }

        val dDateEqualConds = if (request.dDateEqual != null) {
            val dDateEqual = LocalDateTime.parse(request.dDateEqual, formatter).toLocalDate().toString()
            
            "dDate=equal=$dDateEqual"
        } else {
            ""
        }
        
        // Shop PO
        val shopPoBuyers = commonUtils.listToString(listOf(m18Config.BEID_TOA), "beId=equal=", "=or=")
        val shopPoSupplier = commonUtils.listToString(
            shopService.findM18VendorIdsByCodeRegexp(m18Config.SHOP_PO_SUPPLIER),
            "venId=equal=",
            "=or="
        )
        var shopPoConds = "(${shopPoBuyers})=and=(${shopPoSupplier})"

        if (request.modifiedDateFrom != null && request.modifiedDateTo != null) {
            shopPoConds += "=and=(${lastDateConds})"
        }
        if (request.dDateFrom != null && request.dDateTo != null) {
            shopPoConds += "=and=(${dDateConds})"
        }
        if (request.dDateEqual != null) {
            shopPoConds += "=and=(${dDateEqualConds})"
        }
        logger.info("shopPoConds: ${shopPoConds}")
        
        val shopPoParams = M18PurchaseOrderListRequest(
            params = null,
            conds = shopPoConds
        )

        try {
            deliveryOrders.valuesWithType += Pair(
                PurchaseOrderType.SHOP, apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>(
                    M18_FETCH_PURCHASE_ORDER_LIST_API,
                    shopPoParams
                ).block()
            )
        } catch (e: Exception) {
            logger.error("(Getting Shop Po list) Error on Function - ${e.stackTrace}")
            logger.error(e.message)
        }
        
        deliveryOrders.query = shopPoConds

        return deliveryOrders
    }

    open fun getDeliveryOrder(id: Long): M18PurchaseOrderResponse? {
        val deliveryOrderParams = M18PurchaseOrderRequest(
            id = id
        )

        var deliveryOrder: M18PurchaseOrderResponse? = null

        try {
            deliveryOrder = apiCallerService.get<M18PurchaseOrderResponse, M18PurchaseOrderRequest>(
                M18_LOAD_PURCHASE_ORDER_API,
                deliveryOrderParams
            ).block()
        } catch (e: Exception) {
            logger.error("(Getting Po Detail) Error on Function - ${e.stackTrace}")
            logger.error(e.message)
        }

        return deliveryOrder
    }

    open fun saveDeliveryOrders(request: M18CommonRequest): SyncResult {
        val deliveryOrdersWithType = getDeliveryOrdersWithType(request)
        return saveDeliveryOrdersWithPreparedList(deliveryOrdersWithType, syncisExtra = false)
    }

    /**
     * Sync a single M18 shop PO / delivery order by document [code], same search pattern as
     * [com.ffii.fpsms.m18.service.M18PurchaseOrderService.savePurchaseOrderByCode].
     *
     * @param isExtraSync when true, persist local `delivery_order.isExtra=true` (manual DO(加單) sync).
     *                  No M18-side "加單" filtering is used.
     * @param newOnly when true, skip if a non-deleted local DO already exists with the same `code`.
     */
    open fun saveDeliveryOrderByCode(
        code: String,
        isExtraSync: Boolean = false,
        newOnly: Boolean = false,
    ): SyncResult {
        if (newOnly && deliveryOrderRepository.existsByCodeAndDeletedIsFalse(code)) {
            return SyncResult(
                totalProcessed = 1,
                totalSuccess = 0,
                totalFail = 0,
                query = "skipped (newOnly=true): delivery_order.code already exists: $code",
            )
        }
        val conds = "(code=equal=$code)"
        val searchRequest = M18PurchaseOrderListRequest(
            stSearch = "po",
            params = null,
            conds = conds
        )
        val doListResponse = try {
            apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>(
                M18_FETCH_PURCHASE_ORDER_LIST_API,
                searchRequest
            ).block()
        } catch (e: Exception) {
            logger.error("(Getting DO list By Code) Error on Function - ${e.stackTrace}")
            logger.error(e.message)
            null
        }

        val doValues = doListResponse?.values
        if (doValues.isNullOrEmpty()) {
            return SyncResult(
                totalProcessed = 1,
                totalSuccess = 0,
                totalFail = 1,
                query = conds
            )
        }

        val prepared = M18PurchaseOrderListResponseWithType(
            valuesWithType = mutableListOf(Pair(PurchaseOrderType.SHOP, doListResponse)),
            query = conds
        )

        return saveDeliveryOrdersWithPreparedList(prepared, syncisExtra = isExtraSync)
    }

    private fun saveDeliveryOrdersWithPreparedList(
        deliveryOrdersWithType: M18PurchaseOrderListResponseWithType?,
        syncisExtra: Boolean = false,
    ): SyncResult {
        logger.info("--------------------------------------------Start - Saving M18 Delivery Order--------------------------------------------")

        val successList = mutableListOf<Long>()
        val successDetailList = mutableListOf<Long>()
        val failList = mutableListOf<Long>()
        val failDetailList = mutableListOf<Long>()
        val failItemDetailList = mutableListOf<Long>()
        val uomByM18IdCache = mutableMapOf<Long, ItemUom?>()
        val itemIdCache = mutableMapOf<Long, Long?>()
        val stockUomIdCache = mutableMapOf<Pair<Long, Long>, Long?>()

        val doRefType = "Delivery Order"
        val doLineRefType = "Delivery Order Line"

        if (deliveryOrdersWithType != null) {
            // Loop for Delivery Orders (values)
            deliveryOrdersWithType.valuesWithType.forEach { deliveryOrderWithType ->
                val type = deliveryOrderWithType.first
                // if success
                val deliveryOrdersValues = deliveryOrderWithType.second?.values
                // if fail
                val deliveryOrdersMessages = deliveryOrderWithType.second?.messages

                if (deliveryOrdersValues != null) {
                    deliveryOrdersValues.forEach { deliveryOrder ->
                        val deliveryOrderDetail = getDeliveryOrder(deliveryOrder.id)

                        var deliveryOrderId: Long? = null //FP-MTMS

                        // Process for Delivery Order (mainpo)
                        // Assume only one DO in the DO (search by DO ID)
                        val mainpo = deliveryOrderDetail?.data?.mainpo?.get(0)
//                        logger.info("deliveryOrderDetail: data is null? ${deliveryOrderDetail?.data == null} | mainpo is null? ${deliveryOrderDetail?.data?.mainpo == null} | get(0) is null? ${deliveryOrderDetail?.data?.mainpo?.get(0) == null}")
                        val pot = deliveryOrderDetail?.data?.pot
                        val deliveryOrderLineMessage = deliveryOrderDetail?.messages

                        // delivery_order + m18_data_log table
                        if (mainpo != null) {
                            // Find the latest m18 data log by m18 id & type
//                            logger.info("${doRefType}: Finding For Latest M18 Data Log...")
                            val latestDeliveryOrderLog =
                                m18DataLogService.findLatestM18DataLogWithSuccess(deliveryOrder.id, doRefType)
                            //logger.info(latestDeliveryOrderLog.toString())
                            // Save to m18_data_log table
//                            logger.info("${doRefType}: Saving for M18 Data Log...")
                            val mainpoJson =
                                mainpo::class.memberProperties.associate { prop -> prop.name to prop.getter.call(mainpo) }
                                    .toMutableMap()

                            val saveM18DeliveryOrderLogRequest = SaveM18DataLogRequest(
                                id = null,
                                refType = doRefType,
                                m18Id = deliveryOrder.id,
                                m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
//                                dataLog = mainpoJson,
                                statusEnum = M18DataLogStatus.NOT_PROCESS
                            )

                            val saveM18DeliveryOrderLog =
                                m18DataLogService.saveM18DataLog(saveM18DeliveryOrderLogRequest)
//                    logger.info("${doRefType}: Saved M18 Data Log. ID: ${saveM18DeliveryOrderLog.id}")

                            try {
                                // Find the delivery_order if exist
//                                logger.info("${doRefType}: Finding exising delivery order...")
                                val existingDeliveryOrder =
                                    latestDeliveryOrderLog?.id?.let { deliveryOrderService.findByM18DataLogId(it) }
//                                logger.info("${doRefType}: Exising delivery order ID: ${existingDeliveryOrder?.id}")

                                // Save to delivery_order table
//                                logger.info("${doRefType}: Saving delivery order...")
                                val saveDeliveryOrderRequest = SaveDeliveryOrderRequest(
                                    id = existingDeliveryOrder?.id,
                                    code = mainpo.code,
                                    m18SupplierId = mainpo.venId,
                                    m18ShopId = mainpo.virDeptId,
                                    m18CurrencyId = mainpo.curId,
                                    orderDate = commonUtils.timestampToLocalDateTime(mainpo.tDate),
                                    estimatedArrivalDate = commonUtils.timestampToLocalDateTime(mainpo.dDate),
                                    completeDate = null,
                                    status = DeliveryOrderStatus.PENDING.value,
                                    type = type.value,
                                    m18DataLogId = saveM18DeliveryOrderLog.id,
                                    handlerId = null,
                                    m18BeId = mainpo.beId,
                                    deleted = mainpo.udfIsVoid == true,
                                    isExtra = syncisExtra,
                                )

                                val saveDeliveryOrderResponse =
                                    deliveryOrderService.saveDeliveryOrder(saveDeliveryOrderRequest)
                                deliveryOrderId = saveDeliveryOrderResponse.id

                                // Update m18_data_log with success
                                val successSaveM18DeliveryOrderLogRequest = SaveM18DataLogRequest(
                                    id = saveM18DeliveryOrderLog.id,
                                    dataLog = mainpoJson,
                                    statusEnum = M18DataLogStatus.SUCCESS
                                )

                                m18DataLogService.saveM18DataLog(successSaveM18DeliveryOrderLogRequest)

                                // log success info
                                successList.add(deliveryOrder.id)
                                logger.info("${doRefType}: Saved delivery order. ID: ${saveDeliveryOrderResponse.id} | M18 ${doRefType} ID: ${deliveryOrder.id}")

                            } catch (e: Exception) {
                                failList.add(deliveryOrder.id)
//                                logger.error("${doRefType}: Saving Failure!")
                                logger.error("Error on Function - ${e.stackTrace} | Type: ${doRefType} | M18 ID: ${deliveryOrder.id} | Different? ${mainpo.id}")
                                logger.error(e.message)

                                val errorSaveM18DeliveryOrderLogRequest = SaveM18DataLogRequest(
                                    id = saveM18DeliveryOrderLog.id,
                                    dataLog = mutableMapOf(Pair("Exception Message", e.message)),
                                    statusEnum = M18DataLogStatus.FAIL
                                )

                                m18DataLogService.saveM18DataLog(errorSaveM18DeliveryOrderLogRequest)
//                                logger.error("${doRefType}: M18 Data Log Updated! Please see the error. ID: ${saveM18DeliveryOrderLogRequest.id}")
                            }

                            // delivery_order_line + m18_data_log
                            if (pot != null) {
                                val m18LineIds = pot.map { it.id }.toSet()
                                // Loop for Delivery Order Lines (pot)
                                pot.forEach { line ->

                                    // Find the latest m18 data log by m18 id & type
//                                    logger.info("${doLineRefType}: Finding For Latest M18 Data Log...")
                                    val latestDeliveryOrderLineLog =
                                        m18DataLogService.findLatestM18DataLogWithSuccess(line.id, doLineRefType)
                                    // logger.info("${doLineRefType}: Latest M18 Data Log ID: ${latestDeliveryOrderLineLog?.id}")

                                    // Save to m18_data_log table
//                                    logger.info("${doLineRefType}: Saving for M18 Data Log...")
                                    val lineJson =
                                        line::class.memberProperties.associate { prop ->
                                            prop.name to prop.getter.call(
                                                line
                                            )
                                        }
                                            .toMutableMap()
                                    val saveM18DeliveryOrderLineLogRequest = SaveM18DataLogRequest(
                                        id = null,
                                        refType = doLineRefType,
                                        m18Id = line.id,
                                        m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
//                                        dataLog = lineJson,
                                        statusEnum = M18DataLogStatus.NOT_PROCESS
                                    )

                                    val saveM18DeliveryOrderLineLog =
                                        m18DataLogService.saveM18DataLog(saveM18DeliveryOrderLineLogRequest)

                                    // logger.info("${doLineRefType}: Saved M18 Data Log. ID: ${saveM18DeliveryOrderLineLog.id}")
//                                    logger.info("${doLineRefType}: Finding item...")
                                    val itemId: Long? = itemIdCache.getOrPut(line.proId) {
                                        val item = itemsService.findByM18Id(line.proId)
                                        if (item == null) {
                                            m18MasterDataService.saveProduct(line.proId)?.id
                                        } else {
                                            item.id
                                        }
                                    }

                                    val stockUomId: Long? = if (itemId != null) {
                                        val key = line.proId to line.unitId   // safe key
                                        stockUomIdCache.getOrPut(key) {
                                            val uom = itemUomService.findByM18Id(line.unitId)
                                            itemUomService.findStockUnitByItemId(itemId)?.uom?.id
                                        }
                                    } else null

//                                    logger.info("${doLineRefType}: Item ID: ${itemId} | M18 Item ID: ${line.proId}")

                                    try {
                                        // Find the delivery_order_line if exist
//                                        logger.info("${doLineRefType}: Finding exising delivery order line...")
                                        val existingDeliveryOrderLine = latestDeliveryOrderLineLog?.id?.let {
                                            deliveryOrderLineService.findDeliveryOrderLineByM18Id(it)
                                        }
//                                        logger.info("${doLineRefType}: Exising delivery order line ID: ${existingDeliveryOrderLine?.id}")

                                        // Save to delivery_order_line table
//                                        logger.info("${doLineRefType}: Saving delivery order line...")
                                        val itemUom = uomByM18IdCache.getOrPut(line.unitId) {
                                            itemUomService.findByM18Id(line.unitId)
                                        }

                                        val saveDeliveryOrderLineRequest = SaveDeliveryOrderLineRequest(
                                            id = existingDeliveryOrderLine?.id,
                                            itemId = itemId,
                                            uomIdM18 = itemUom?.uom?.id,
                                            uomId= stockUomId,
                                            deliveryOrderId = deliveryOrderId,
                                            qtyM18 = line.qty,
                                            qty = itemUomService.convertQtyToStockQty(itemId?:0, itemUom?.uom?.id?: 0, line.qty),
                                            up = line.up,
                                            price = line.amt,
//                                            m18CurrencyId = mainpo.curId,
                                            status = existingDeliveryOrderLine?.status?.value
                                                ?: DeliveryOrderLineStatus.PENDING.value,
                                            m18DataLogId = saveM18DeliveryOrderLineLog.id,
                                            m18Discount = line.disc,
                                            m18Lot = line.lot
                                        )

                                        val saveDeliveryOrderLineResponse =
                                            deliveryOrderLineService.saveDeliveryOrderLine(saveDeliveryOrderLineRequest)

                                        // Update m18_data_log with success
                                        val successSaveM18DeliveryOrderLineLogRequest = SaveM18DataLogRequest(
                                            id = saveM18DeliveryOrderLineLog.id,
                                            dataLog = lineJson,
                                            statusEnum = M18DataLogStatus.SUCCESS
                                        )

                                        m18DataLogService.saveM18DataLog(successSaveM18DeliveryOrderLineLogRequest)

                                        // log success info
                                        successDetailList.add(line.id)
//                                        logger.info("${doLineRefType}: Delivery order ID: ${deliveryOrderId} | M18 ID: ${deliveryOrder.id}")
                                        //logger.info("${doLineRefType}: Saved delivery order line. ID: ${saveDeliveryOrderLineResponse.id} | M18 Line ID: ${line.id} | Delivery order ID: ${deliveryOrderId} | M18 ID: ${deliveryOrder.id}")
                                    } catch (e: SQLException) {
                                        failDetailList.add(line.id)
                                        failItemDetailList.add(line.proId)
//                                        logger.error("${doLineRefType}: Saving Failure!")
                                        logger.error("Error on Function - ${e.stackTrace} | Type: ${doLineRefType} | M18 ID: ${line.id}")
                                        logger.error(e.message)

                                        val errorSaveM18DeliveryOrderLineLogRequest = SaveM18DataLogRequest(
                                            id = saveM18DeliveryOrderLineLog.id,
                                            dataLog = mutableMapOf(Pair("Exception Message", e.message)),
                                            statusEnum = M18DataLogStatus.FAIL
                                        )

                                        m18DataLogService.saveM18DataLog(errorSaveM18DeliveryOrderLineLogRequest)
//                                        logger.error("${doLineRefType}: M18 Data Log Updated! Please see the error. ID: ${saveM18DeliveryOrderLineLog.id}")
                                    }
                                }

                                if (deliveryOrderId != null) {
                                    val markedDeleted = deliveryOrderLineService.markDeletedLinesMissingFromM18(
                                        deliveryOrderId = deliveryOrderId,
                                        existingM18LineIds = m18LineIds,
                                        m18RefType = doLineRefType
                                    )
                                    if (markedDeleted > 0) {
                                        logger.info("${doLineRefType}: Marked ${markedDeleted} stale line(s) as deleted for deliveryOrderId=${deliveryOrderId}")
                                    }
                                    val dupesRemoved = deliveryOrderLineService.markDuplicateDeliveryOrderLinesForSameM18LineId(
                                        deliveryOrderId = deliveryOrderId,
                                        existingM18LineIds = m18LineIds,
                                        m18RefType = doLineRefType
                                    )
                                    if (dupesRemoved > 0) {
                                        logger.info("${doLineRefType}: Marked ${dupesRemoved} duplicate line(s) as deleted (same M18 line id) for deliveryOrderId=${deliveryOrderId}")
                                    }
                                }
                            } else {
                                // pot
//                                logger.error("${doLineRefType}: Saving Failure!")
                                val saveM18DeliveryOrderLineLogRequest = SaveM18DataLogRequest(
                                    id = null,
                                    refType = "${doLineRefType}",
                                    m18Id = deliveryOrder.id,
                                    m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
//                                    dataLog = mutableMapOf(Pair("Error Message", "${doLineRefType} is null")),
                                    dataLog = mutableMapOf(
                                        Pair(
                                            "${doLineRefType} Error Message",
                                            "pot is null"
                                        ),
                                        Pair(
                                            "${doLineRefType} Error Code",
                                            deliveryOrderLineMessage?.get(0)?.msgCode ?: "No Msg Code from M18"
                                        ),
                                        Pair(
                                            "${doLineRefType} Error Detail",
                                            deliveryOrderLineMessage?.get(0)?.msgDetail ?: "No Msg Detail from M18"
                                        ),
                                    ),
                                    statusEnum = M18DataLogStatus.FAIL
                                )

                                val errorLog = m18DataLogService.saveM18DataLog(saveM18DeliveryOrderLineLogRequest)
                                logger.error("${doLineRefType}: M18 Data Log Updated! Please see the error. ID: ${errorLog.id}")
                            }
                        } else {
                            // mainpo
                            failList.add(deliveryOrder.id)
//                            logger.error("${doRefType}: Saving Failure!")
                            val saveM18DataLogRequest = SaveM18DataLogRequest(
                                id = null,
                                refType = "${doRefType}",
                                m18Id = deliveryOrder.id,
                                // m18LastModifyDate = if(mainpo?.lastModifyDate != null) commonUtils.instantToLocalDateTime(mainpo.lastModifyDate) else LocalDateTime.now(),
                                m18LastModifyDate = LocalDateTime.now(),
                                dataLog = mutableMapOf(
                                    Pair(
                                        "${doRefType} Error",
                                        "mainpo is null"
                                    ),
                                    Pair(
                                        "${doRefType} Error Code",
                                        deliveryOrdersMessages?.get(0)?.msgCode ?: "No Msg Code from M18"
                                    ),
                                    Pair(
                                        "${doRefType} Error Detail",
                                        deliveryOrdersMessages?.get(0)?.msgDetail ?: "No Msg Detail from M18"
                                    ),
                                ),
                                statusEnum = M18DataLogStatus.FAIL
                            )

                            val errorLog = m18DataLogService.saveM18DataLog(saveM18DataLogRequest)
                            logger.error("${doLineRefType}: M18 Data Log Updated! Please see the error. ID: ${errorLog.id}")
                        }
                    }
                } else {
                    logger.error("${doRefType} List is null. May occur errors.")
                }
            }
        } else {
            logger.error("${doRefType} List is null. May occur errors.")
        }

        // End of save. Check result
        logger.info("Total Success (${doRefType}) (${successList.size})")
        logger.error("Total Fail (${doRefType}) (${failList.size}): $failList")

        logger.info("Total Success (${doLineRefType}) (${successDetailList.size})")
        logger.error("Total Fail (${doLineRefType}) (${failDetailList.size}): $failDetailList")

        // Fee cleanup for DO lines (currently disabled; keep for future use)
        // val feeMarked = deliveryOrderLineService.markDeletedLinesWithFeeItems()
        // if (feeMarked > 0) {
        //     logger.info("Marked $feeMarked DO line(s) as deleted (isFee items).")
        // }

        logger.info("--------------------------------------------End - Saving M18 Delivery Order--------------------------------------------")

        return SyncResult(
            totalProcessed = successList.size + failList.size,
            totalSuccess = successList.size,
            totalFail = failList.size,
            query = deliveryOrdersWithType?.query ?: ""
        )
    }
}