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

import java.util.Locale

/**
 * 車線搜尋正規化（search-do-lite-v2）。
 * 實際 [com.ffii.fpsms.modules.pickOrder.entity.Truck] 編碼主要為 `車線-…` 或 `P06B_…`；未指派預設列為 `車線-X`（shopId 可為 null）。
 */
object TruckLaneSearchSpec {
    const val UNASSIGNED_LANE_LABEL: String = "車線-X"

    sealed interface Mode {
        data object NoFilter : Mode
        /** 僅未指派：推算為 null／空白／字面量 車線-X（與預設車列一致） */
        data object UnassignedOnly : Mode
        /**
         * 一般關鍵字：以 [needleLower]（trim + [Locale.ROOT] lowercase）對推算車線做 [String.contains]。
         * 不再因「`車線-` 開頭」額外併入未指派，避免搜 `車線-待1` 卻出現 `車線-X`；廣義條件（無車線欄位）仍由 [NoFilter] 帶出含 X 的列。
         */
        data class Keyword(
            val needleLower: String,
        ) : Mode
    }

    fun parse(raw: String?): Mode {
        val trimmed = raw?.trim().orEmpty()
        if (trimmed.isEmpty()) return Mode.NoFilter
        if (isUnassignedSearchToken(trimmed)) return Mode.UnassignedOnly
        return Mode.Keyword(
            needleLower = trimmed.lowercase(Locale.ROOT),
        )
    }

    private fun isUnassignedSearchToken(trimmed: String): Boolean {
        if (trimmed.length == 1 && trimmed.equals("x", ignoreCase = true)) return true
        val normalized = trimmed.lowercase(Locale.ROOT).replace("车线", "車線")
        return normalized == "車線-x"
    }

    fun isUnassignedResolvedLane(calculated: String?): Boolean {
        if (calculated.isNullOrBlank()) return true
        return calculated.trim().equals(UNASSIGNED_LANE_LABEL, ignoreCase = true)
    }

    fun matches(mode: Mode, resolvedTruckLanceCode: String?): Boolean {
        when (mode) {
            Mode.NoFilter -> return true
            Mode.UnassignedOnly -> return isUnassignedResolvedLane(resolvedTruckLanceCode)
            is Mode.Keyword -> {
                val lane = resolvedTruckLanceCode?.trim()?.lowercase(Locale.ROOT).orEmpty()
                return lane.contains(mode.needleLower)
            }
        }
    }
}
