package com.ffii.fpsms.modules.master.service

import com.ffii.fpsms.m18.model.M18BomShopBatchSyncSummary
import com.ffii.fpsms.modules.common.SettingNames
import com.ffii.fpsms.modules.master.entity.BomRepository
import com.ffii.fpsms.modules.settings.entity.Settings
import com.ffii.fpsms.modules.settings.service.SettingsService
import org.springframework.stereotype.Service

/**
 * Calls [BomService.pushBomToM18ShopIfAllowed] for each BOM id via the injected proxied bean
 * so `@Transactional` applies per BOM (avoids same-class self-invocation).
 *
 * BOM shop toggle is read via [settingsService] here (not [BomService]) so callers never hit Kotlin
 * `internal` accessors on [BomService] CGLIB proxies, which could leave delegated dependencies null.
 */
@Service
open class BomM18ShopBulkPushService(
    private val bomRepository: BomRepository,
    private val bomService: BomService,
    private val settingsService: SettingsService,
) {

    /** Pushes all non-deleted BOMs to M18 when {@link SettingNames#M18_BOM_SHOP_SYNC_ENABLED} is true. */
    open fun pushAllBomsToM18ShopIfAllowed(): M18BomShopBatchSyncSummary {
        if (!isM18BomShopSyncEnabledSetting()) {
            return M18BomShopBatchSyncSummary(
                totalProcessed = 0,
                synced = 0,
                notSynced = 0,
                skippedBecauseFeatureDisabled = true,
            )
        }
        val ids = bomRepository.findAllIdsByDeletedIsFalse()
        var synced = 0
        var notSynced = 0
        for (id in ids) {
            val result = bomService.pushBomToM18ShopIfAllowed(id)
            if (result.synced) synced++ else notSynced++
        }
        return M18BomShopBatchSyncSummary(
            totalProcessed = ids.size,
            synced = synced,
            notSynced = notSynced,
            skippedBecauseFeatureDisabled = false,
        )
    }

    private fun isM18BomShopSyncEnabledSetting(): Boolean =
        settingsService.findByName(SettingNames.M18_BOM_SHOP_SYNC_ENABLED)
            .map { Settings.VALUE_BOOLEAN_TRUE == it.value }
            .orElse(false)
}
