package com.ffii.fpsms.modules.deliveryOrder.service

import com.ffii.fpsms.modules.settings.entity.SettingsRepository
import org.springframework.stereotype.Service
import java.util.Locale

/** 供 DO 搜索／車線／報表 SQL 等共用的 2F／4F 供應商代碼（來自 `settings` CSV）。 */
@Service
open class DoFloorSupplierSettingsService(
    private val settingsRepository: SettingsRepository,
) {
    companion object {
        private const val SETTING_DO_FLOOR_SUPPLIERS_2F = "DO.floor.suppliers.2F"
        private const val SETTING_DO_FLOOR_SUPPLIERS_4F = "DO.floor.suppliers.4F"

        private val DEFAULT_SUPPLIERS_2F = listOf("P07", "P06D", "P06Y")
        private val DEFAULT_SUPPLIERS_4F = listOf("P06B")
    }

    open fun supplierCodesFromSetting(settingName: String, defaultList: List<String>): List<String> {
        val raw = settingsRepository.findByName(settingName).map { it.value }.orElse(null)
            ?.trim()
            .orEmpty()
        if (raw.isEmpty()) return defaultList
        val parsed = raw.split(",").map { it.trim() }.filter { it.isNotEmpty() }.distinct()
        return parsed.ifEmpty { defaultList }
    }

    open fun loadDoFloorSupplierLists(): Pair<List<String>, List<String>> {
        val suppliers2F = supplierCodesFromSetting(SETTING_DO_FLOOR_SUPPLIERS_2F, DEFAULT_SUPPLIERS_2F)
        val suppliers4F = supplierCodesFromSetting(SETTING_DO_FLOOR_SUPPLIERS_4F, DEFAULT_SUPPLIERS_4F)
        return suppliers2F to suppliers4F
    }

    open fun allowedSupplierCodesForFloor(floor: String?): List<String> {
        val f = floor?.trim()?.uppercase(Locale.ROOT).orEmpty()
        val (codes2F, codes4F) = loadDoFloorSupplierLists()
        return when {
            f.isEmpty() || f == "ALL" || f == "All" -> (codes2F + codes4F).distinct()
            f == "2F" -> codes2F
            f == "4F" -> codes4F
            else -> (codes2F + codes4F).distinct()
        }
    }

    /** 4F 清單優先；其餘預設 2F（與既有 DO 車線邏輯一致）。 */
    open fun preferredStoreFloorForSupplier(
        supplierCode: String?,
        suppliers2F: List<String>,
        suppliers4F: List<String>,
    ): String {
        val code = supplierCode?.trim().orEmpty()
        if (code.isEmpty()) return "2F"
        if (suppliers4F.contains(code)) return "4F"
        if (suppliers2F.contains(code)) return "2F"
        return "2F"
    }

    /** DO 揀貨建議：名單外供應商不限制 2F/4F。 */
    open fun preferredFloorForPickLotOrNull(
        supplierCode: String?,
        suppliers2F: List<String>,
        suppliers4F: List<String>,
    ): String? {
        val code = supplierCode?.trim().orEmpty()
        if (code.isEmpty()) return null
        if (suppliers4F.contains(code)) return "4F"
        if (suppliers2F.contains(code)) return "2F"
        return null
    }

    data class SqlPreferredFloorCases(
        /** 例如 `CASE WHEN s.code IN (...) THEN '4F' ... END`（單行，可嵌入原生 SQL） */
        val floorStringCase: String,
        val storeIdNumericCase: String,
    )

    /**
     * 依目前 settings 產生原生 SQL CASE（供 JDBC 字串拼接）。
     * @param codeExpr 已加別名的欄位，如 `s.code`、`supplier.code`
     */
    open fun sqlPreferredFloorCases(codeExpr: String = "s.code"): SqlPreferredFloorCases {
        val (s2f, s4f) = loadDoFloorSupplierLists()
        val in4 = joinSqlInList(s4f)
        val in2 = joinSqlInList(s2f)
        val floor =
            "CASE WHEN $codeExpr IN ($in4) THEN '4F' WHEN $codeExpr IN ($in2) THEN '2F' ELSE NULL END"
        val storeId =
            "CASE WHEN $codeExpr IN ($in4) THEN 4 WHEN $codeExpr IN ($in2) THEN 2 ELSE NULL END"
        return SqlPreferredFloorCases(floorStringCase = floor, storeIdNumericCase = storeId)
    }

    private fun joinSqlInList(codes: List<String>): String =
        codes.joinToString(", ") { "'" + it.replace("'", "''") + "'" }
}
