package com.lukouguoji.gjc.viewModel

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.holder.AssembleInfoViewHolder
import com.lukouguoji.gjc.holder.AssemblePositionViewHolder
import com.lukouguoji.gjc.holder.AssembleWaybillViewHolder
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.*
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.db.perference.SharedPreferenceUtil
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.model.ScanModel
import dev.utils.app.info.KeyValue
import kotlinx.coroutines.launch

/**
 * 国际出港-开始组装ViewModel（静态数据）
 */
class IntExpAssembleStartViewModel : BaseViewModel() {

    companion object {
        /**
         * 缓存用户上次选择的组装人
         * 生命周期：本次App打开期间有效，退出登录后清空
         */
        var lastSelectedOperator: String? = null
    }

    // ========== 搜索条件 ==========
    val searchText = MutableLiveData("")
    val uldSearchText = MutableLiveData("")  // ULD搜索框

    // ========== 组装参数（从选中运单自动提取）==========
    val assembleFlightNo = MutableLiveData("")      // 航班号
    val assembleFlightDate = MutableLiveData("")    // 航班日期

    // ========== 防抖标记 ==========
    private var lastQueriedAssembledParams = ""  // 避免重复查询

    // ========== 左侧组装信息列表 ==========
    val assembleInfoList = MutableLiveData<MutableList<AssembleInfoBean>>()
    val assembleInfoLayoutId = R.layout.item_assemble_info
    val assembleInfoViewHolder = AssembleInfoViewHolder::class.java

    // ========== 左侧组装位置列表 ==========
    val assemblePositionList = MutableLiveData<MutableList<AssemblePositionBean>>()
    val assemblePositionLayoutId = R.layout.item_assemble_position
    val assemblePositionViewHolder = AssemblePositionViewHolder::class.java

    // ========== 选中的组装位置 ==========
    val selectedPosition = MutableLiveData<AssemblePositionBean?>()

    // ========== 右侧运单列表 ==========
    val waybillList = MutableLiveData<MutableList<AssembleWaybillBean>>()
    val waybillLayoutId = R.layout.item_assemble_waybill
    val waybillViewHolder = AssembleWaybillViewHolder::class.java

    // ========== ULD信息 ==========
    val uldInfo = MutableLiveData(UldInfoBean())

    // ========== 运单信息 ==========
    val waybillInfo = MutableLiveData(WaybillInfoBean())

    // ========== 组装人（独立的LiveData，用于监听变化并更新缓存）==========
    val operator = MutableLiveData<String>("")

    // ========== 组装人列表 ==========
    val assemblerList = MutableLiveData<List<KeyValue>>(emptyList())

    // ========== 标记位，避免重复查询 ==========
    private var lastQueriedUldNo = ""

    /**
     * ULD编号锁定状态
     */
    val isUldNoLocked = MutableLiveData(false)

    /**
     * 装货按钮启用状态（非编辑模式时启用）
     */
    val isLoadEnabled = MutableLiveData(true)

    /**
     * 卸货按钮启用状态（编辑模式时启用）
     */
    val isUnloadEnabled = MutableLiveData(false)

    init {
        // 监听组装人变化，自动更新缓存和waybillInfo
        operator.observeForever { value ->
            if (!value.isNullOrEmpty()) {
                lastSelectedOperator = value
                // 同步到 waybillInfo
                waybillInfo.value?.operator = value
            }
        }

        // 监听ULD锁定状态，自动更新按钮启用状态
        isUldNoLocked.observeForever { isLocked ->
            if (isLocked == true) {
                // 编辑模式：只能卸货
                isLoadEnabled.value = false
                isUnloadEnabled.value = true
            } else {
                // 非编辑模式：只能装货
                isLoadEnabled.value = true
                isUnloadEnabled.value = false
            }
        }
    }


    /**
     * 加载组装位置列表
     */
    fun loadAssemblePosition() {
        launchLoadingCollect({ NetApply.api.getDictListByLocation("GJCLOAD") }) {
            onSuccess = { result ->
                val list = result.data?.mapIndexed { index, dictBean ->
                    AssemblePositionBean().apply {
                        positionName = dictBean.name
                        isSelected = (index == 0)  // 默认选中第一项
                    }
                }?.toMutableList() ?: mutableListOf()

                assemblePositionList.value = list

                // 保存默认选中的第一项
                if (list.isNotEmpty()) {
                    selectedPosition.value = list[0]
                }
            }
        }
    }

    /**
     * 组装位置点击（单选切换）
     */
    fun onPositionItemClick(position: Int) {
        val list = assemblePositionList.value ?: return

        // 取消所有选中状态
        list.forEach { it.isSelected = false }

        // 选中当前项
        if (position in list.indices) {
            list[position].isSelected = true
            selectedPosition.value = list[position]
        }

        // 刷新列表
        assemblePositionList.value = list

        // 触发组装信息列表查询
        loadAssembledList()
    }

    /**
     * 运单点击（单选切换）
     */
    fun onWaybillItemClick(position: Int) {
        val list = waybillList.value ?: return

        // 选中新运单前，先检查是否切换了运单
        val previousWaybillNo = waybillInfo.value?.waybillNo ?: ""
        val selectedWaybill = if (position in list.indices) list[position] else null
        val isWaybillChanged = selectedWaybill != null && previousWaybillNo.isNotEmpty()
                                && selectedWaybill.waybillNo != previousWaybillNo

        // 取消所有运单的选中状态
        list.forEach { it.isSelected.set(false) }

        // 选中当前运单
        if (selectedWaybill != null) {
            selectedWaybill.isSelected.set(true)

            // 自动提取航班号和航班日期
            assembleFlightNo.value = selectedWaybill.fno
            assembleFlightDate.value = selectedWaybill.fdate

            // 保存当前的组装人（始终保留，从operator LiveData读取）
            val previousOperator = operator.value ?: ""

            // 判断是否需要保留组装件数和重量
            val previousAssembleCount: String
            val previousAssembleWeight: String

            if (isWaybillChanged) {
                // 运单切换了：清空组装件数和组装重量
                previousAssembleCount = ""
                previousAssembleWeight = ""

                // 解锁ULD编号
                isUldNoLocked.value = false
            } else {
                // 同一个运单：保留组装件数和组装重量
                previousAssembleCount = waybillInfo.value?.assembleCount ?: ""
                previousAssembleWeight = waybillInfo.value?.assembleWeight ?: ""
            }

            // 同步运单信息到表单
            waybillInfo.value = WaybillInfoBean().apply {
                waybillNo = selectedWaybill.waybillNo
                waybillPieces = selectedWaybill.pieces
                waybillWeight = selectedWaybill.weight
                assembleCount = previousAssembleCount
                assembleWeight = previousAssembleWeight
                operator = previousOperator  // 从operator LiveData获取的值
            }
        }

        // 刷新列表
        waybillList.value = list

        // 清除防抖标记，强制重新查询组装信息列表
        lastQueriedAssembledParams = ""

        // 触发组装信息列表查询
        loadAssembledList()
    }

    /**
     * 扫码运单
     */
    fun scanWaybill() {
        ScanModel.startScan(getTopActivity(), Constant.RequestCode.WAYBILL)
    }

    /**
     * 加载待组装运单列表
     */
    fun loadWaitingAssembleWaybills() {
        val wbNo = searchText.value?.trim() ?: ""

        // 发起网络请求（空参数时相当于刷新列表）
        launchLoadingCollect({ NetApply.api.queryWaitingAssemble(wbNo) }) {
            onSuccess = { result ->
                // 数据转换: GjcWarehouse -> AssembleWaybillBean
                val warehouseList = result.data ?: mutableListOf()
                val waybillBeanList = warehouseList.map { warehouse ->
                    AssembleWaybillBean().apply {
                        waybillNo = warehouse.wbNo
                        pieces = warehouse.pc.toString()
                        weight = String.format("%.1f", warehouse.weight)
                        flight = warehouse.flight
                        fno = warehouse.fno
                        fdate = warehouse.fdate
                        whId = warehouse.whId  // 添加运单ID
                        isMarked = false
                    }
                }.toMutableList()

                // 更新列表
                waybillList.value = waybillBeanList

                // 检查当前填充的运单是否在新列表中
                val currentWaybillNo = waybillInfo.value?.waybillNo ?: ""
                if (currentWaybillNo.isNotEmpty()) {
                    val existsInNewList = waybillBeanList.any { it.waybillNo == currentWaybillNo }
                    if (!existsInNewList) {
                        // 当前运单不在新列表中，清空表单
                        val previousOperator = operator.value ?: ""
                        waybillInfo.value = WaybillInfoBean().apply {
                            operator = previousOperator
                        }
                    }
                }

                // 结果反馈
                if (waybillBeanList.isEmpty()) {
                    showToast("未找到待组装运单")
                } else {
                    showToast("查询成功，共${waybillBeanList.size}条记录")
                }
            }
            onFailed = { code, message ->
                showToast("查询失败: $message")
                waybillList.value = mutableListOf()
            }
        }
    }

    /**
     * 初始化加载待组装运单列表（页面打开时调用）
     */
    fun loadInitialWaitingAssemble() {
        launchLoadingCollect({ NetApply.api.queryWaitingAssemble("") }) {
            onSuccess = { result ->
                val warehouseList = result.data ?: mutableListOf()
                val waybillBeanList = warehouseList.map { warehouse ->
                    AssembleWaybillBean().apply {
                        waybillNo = warehouse.wbNo
                        pieces = warehouse.pc.toString()
                        weight = String.format("%.1f", warehouse.weight)
                        flight = warehouse.flight
                        fno = warehouse.fno
                        fdate = warehouse.fdate
                        whId = warehouse.whId  // 添加运单ID
                        isMarked = false
                    }
                }.toMutableList()

                waybillList.value = waybillBeanList

                // 检查当前填充的运单是否在新列表中
                val currentWaybillNo = waybillInfo.value?.waybillNo ?: ""
                if (currentWaybillNo.isNotEmpty()) {
                    val existsInNewList = waybillBeanList.any { it.waybillNo == currentWaybillNo }
                    if (!existsInNewList) {
                        // 当前运单不在新列表中，清空表单
                        val previousOperator = operator.value ?: ""
                        waybillInfo.value = WaybillInfoBean().apply {
                            operator = previousOperator
                        }
                    }
                }

                if (waybillBeanList.isEmpty()) {
                    showToast("暂无待组装运单")
                }
            }
            onFailed = { code, message ->
                showToast("加载失败: $message")
                waybillList.value = mutableListOf()
            }
        }
    }

    /**
     * 加载组装人列表
     */
    fun loadAssemblerList() {
        launchCollect({ NetApply.api.getIntExpAssemblerList() }) {
            onSuccess = { result ->
                val list = result.data ?: emptyList()
                // 转换为 KeyValue 列表
                val keyValueList = list.map { KeyValue(it, it) }
                assemblerList.value = keyValueList

                // 使用缓存的组装人，如果缓存存在且在列表中则自动填充
                if (!lastSelectedOperator.isNullOrEmpty() && list.contains(lastSelectedOperator)) {
                    operator.value = lastSelectedOperator  // 设置到operator LiveData，会自动触发observer更新缓存和waybillInfo
                }
                // 如果缓存为空或不在列表中，保持为空（显示hint "请选择组装人"）
            }
            onFailed = { code, message ->
                showToast("加载组装人列表失败: $message")
                assemblerList.value = emptyList()
            }
        }
    }


    /**
     * ULD编号输入完成时调用
     */
    fun onUldNoInputComplete() {
        val uld = uldInfo.value?.uldNo?.trim() ?: ""
        if (uld.isNotEmpty() && uld != lastQueriedUldNo) {
            lastQueriedUldNo = uld
            queryUldInfo(uld)
        }
    }

    /**
     * 查询ULD信息（状态和耗材重量）
     */
    private fun queryUldInfo(uldNo: String) {
        launchCollect({ NetApply.api.getUldWithConsumeWeight(uldNo) }) {
            onSuccess = { result ->
                val uldBean = result.data
                if (uldBean != null) {
                    // 更新ULD状态和耗材重量
                    uldInfo.value = uldInfo.value?.apply {
                        // status: 0-正常, 1-故障
                        uldStatus = when (uldBean.status) {
                            "0" -> "正常"
                            "1" -> "故障"
                            else -> uldBean.status ?: ""
                        }
                        // 耗材重量保持可编辑，仅在为空时填充
                        if (materialWeight.isEmpty()) {
                            materialWeight = uldBean.consumeWeight?.toString() ?: ""
                        }
                        // 保存useId（用于装货/卸货接口）
                        useId = uldBean.useId
                    }
                }
            }
            onFailed = { code, message ->
                showToast("查询ULD信息失败: $message")
            }
        }
    }

    /**
     * 卸货按钮点击
     */
    fun onUnloadClick() {
        performAssembleOperation(isLoad = false)
    }

    /**
     * 装货按钮点击
     */
    fun onLoadClick() {
        performAssembleOperation(isLoad = true)
    }

    /**
     * 执行组装操作（卸货或装货）
     * @param isLoad true-装货，false-卸货
     */
    private fun performAssembleOperation(isLoad: Boolean) {
        // 1. 验证必填字段
        val uldNo = uldInfo.value?.uldNo?.trim() ?: ""
        if (uldNo.isEmpty()) {
            showToast("请输入ULD编号")
            return
        }

        val materialWeight = uldInfo.value?.materialWeight?.trim() ?: ""
        if (materialWeight.isEmpty()) {
            showToast("请输入耗材重量")
            return
        }

        val waybillNo = waybillInfo.value?.waybillNo?.trim() ?: ""
        if (waybillNo.isEmpty()) {
            showToast("请选择运单")
            return
        }

        val assembleCount = waybillInfo.value?.assembleCount?.trim() ?: ""
        if (assembleCount.isEmpty()) {
            val countFieldName = if (isLoad) "装货件数" else "卸货件数"
            showToast("请输入${countFieldName}")
            return
        }

        // 校验件数范围
        val waybillPieces = waybillInfo.value?.waybillPieces?.trim() ?: ""
        val assembleCountInt = assembleCount.toLongOrNull() ?: 0L
        val waybillPiecesInt = waybillPieces.toLongOrNull() ?: 0L

        if (assembleCountInt > waybillPiecesInt) {
            val errorMessage = if (isLoad) {
                "装货件数不能大于运单件数"
            } else {
                "卸货件数不能大于已装货件数"
            }
            showToast(errorMessage)
            return
        }

        val assembleWeight = waybillInfo.value?.assembleWeight?.trim() ?: ""
        // 组装重量为非必填，不进行验证

        val operatorValue = operator.value?.trim() ?: ""
        if (operatorValue.isEmpty()) {
            showToast("请选择组装人")
            return
        }

        val loadArea = selectedPosition.value?.positionName?.trim() ?: ""
        if (loadArea.isEmpty()) {
            showToast("请选择组装位置")
            return
        }

        // 2. 获取或构建运单Bean
        // 从运单列表中获取选中的运单
        val currentWaybillList = waybillList.value
        if (currentWaybillList == null) {
            showToast("运单列表为空")
            return
        }

        val selectedWaybill = currentWaybillList.firstOrNull { it.isSelected.get() }
        if (selectedWaybill == null) {
            showToast("请选择运单")
            return
        }

        // 3. 构建useInfo（ULD信息）
        val useInfo = mapOf(
            "uld" to uldNo,
            "consumeWeight" to materialWeight.toDoubleOrNull(),
            "status" to when (uldInfo.value?.uldStatus) {
                "正常" -> "0"
                "故障" -> "1"
                else -> ""
            },
            "loadArea" to loadArea,
            "useId" to if (uldInfo.value?.useId == 0L) null else uldInfo.value?.useId  // 添加useId（来自getUld接口）
        )

        // 4. 构建wbInfo（运单信息）
        // 使用原始运单件数/重量（如果有），否则使用当前件数/重量
        val waybillPc = if (selectedWaybill.originalPieces.isNotEmpty()) {
            selectedWaybill.originalPieces.toLongOrNull()
        } else {
            selectedWaybill.pieces.toLongOrNull()
        }
        val waybillWeight = if (selectedWaybill.originalWeight.isNotEmpty()) {
            selectedWaybill.originalWeight.toDoubleOrNull()
        } else {
            selectedWaybill.weight.toDoubleOrNull()
        }

        val wbInfo = mapOf(
            "wbNo" to selectedWaybill.waybillNo,
            "pc" to waybillPc,
            "weight" to waybillWeight,
            "fdate" to selectedWaybill.fdate,
            "fno" to selectedWaybill.fno,
            "whId" to selectedWaybill.whId
        )

        // 5. 构建完整请求参数
        val params = mapOf(
            "abPc" to assembleCount.toLongOrNull(),
            "abWeight" to assembleWeight.toDoubleOrNull(),
            "consumeWeight" to materialWeight.toDoubleOrNull(),
            "ldId" to operatorValue,
            "loadArea" to loadArea,
            "useInfo" to useInfo,
            "wbInfo" to wbInfo,
            "userId" to SharedPreferenceUtil.getString(Constant.Share.account)
        ).toRequestBody()

        // 6. 调用接口（带Loading，等待接口返回）
        val operationName = if (isLoad) "装货" else "卸货"
        launchLoadingCollect({
            if (isLoad) {
                NetApply.api.assembleLoadCargo(params)
            } else {
                NetApply.api.assembleDropCargo(params)
            }
        }) {
            onSuccess = { result ->
                // 接口成功后才显示成功提示并刷新列表
                handleOperationSuccess(operationName, isLoad, uldNo, selectedWaybill, assembleCount, assembleWeight)
            }
            onFailed = { code, message ->
                showToast("${operationName}失败: $message")
            }
        }
    }

    /**
     * 处理装货/卸货操作成功
     */
    private fun handleOperationSuccess(
        operationName: String,
        isLoad: Boolean,
        uldNo: String,
        selectedWaybill: AssembleWaybillBean,
        assembleCount: String,
        assembleWeight: String
    ) {
        showToast("${operationName}成功")

        // 发送刷新事件，通知出港组装列表页面更新数据
        viewModelScope.launch {
            FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
        }

        // 重新查询组装信息列表（刷新数据）
        loadAssembledList()

        // 刷新运单列表
        loadInitialWaitingAssemble()

        // 清空表单
        clearForm()
    }

    /**
     * 组装信息列表点击事件
     * 1. 点击一级ULD行：展开/折叠（按需加载运单列表）
     * 2. 点击二级运单行：填充表单（编辑模式）
     */
    fun onAssembleInfoItemClick(position: Int) {
        val list = assembleInfoList.value ?: return
        if (position !in list.indices) return

        val clickedItem = list[position]

        when (clickedItem.itemType) {
            AssembleInfoBean.ItemType.ULD_HEADER -> {
                // 一级ULD行：切换展开/折叠
                val newExpandState = !clickedItem.isExpanded.get()
                clickedItem.isExpanded.set(newExpandState)

                if (newExpandState) {
                    // 展开：查询该ULD的运单列表
                    loadWaybillsByUld(position, clickedItem)
                } else {
                    // 折叠：移除二级运单行
                    removeWaybillRows(position)
                }
            }

            AssembleInfoBean.ItemType.WAYBILL_DETAIL -> {
                // 二级运单行：填充表单（编辑模式）
                fillFormFromWaybillDetail(clickedItem)
            }
        }
    }

    /**
     * 加载指定ULD的运单列表
     */
    private fun loadWaybillsByUld(uldPosition: Int, uldItem: AssembleInfoBean) {
        val uldBean = uldItem.tag as? GjcUldUseBean ?: return

        // 检查是否已缓存
        if (uldBean.waybillDetails != null) {
            // 已缓存，直接展开
            insertWaybillRows(uldPosition, uldBean.waybillDetails!!)
            return
        }

        // 未缓存，调用接口查询
        val params = uldBean.toRequestBody()

        launchLoadingCollect({ NetApply.api.getAssembledWaybillsByUld(params) }) {
            onSuccess = { result ->
                val waybillList = result.data ?: emptyList()

                if (waybillList.isEmpty()) {
                    showToast("该ULD暂无运单记录")
                    // 折叠回去
                    uldItem.isExpanded.set(false)
                } else {
                    // 缓存到GjcUldUseBean
                    uldBean.waybillDetails = waybillList.toMutableList()

                    // 插入二级运单行
                    insertWaybillRows(uldPosition, waybillList)
                }
            }
            onFailed = { code, message ->
                showToast("查询失败: $message")
                // 折叠回去
                uldItem.isExpanded.set(false)
            }
        }
    }

    /**
     * 在指定位置后插入二级运单行
     */
    private fun insertWaybillRows(uldPosition: Int, waybillList: List<GjcWarehouse>) {
        val list = assembleInfoList.value?.toMutableList() ?: return
        val uldItem = list[uldPosition]

        // 生成二级运单行
        val waybillRows = waybillList.map { warehouse ->
            AssembleInfoBean().apply {
                itemType = AssembleInfoBean.ItemType.WAYBILL_DETAIL
                parentUldNo = uldItem.uldNo
                wbNo = warehouse.wbNo
                waybillPieces = warehouse.pc.toInt()
                waybillWeight = warehouse.weight
                showIndent = true
                showIndex = false

                // 转换为AssembleWaybillBean（用于填充表单）
                waybillData = AssembleWaybillBean().apply {
                    waybillNo = warehouse.wbNo
                    pieces = warehouse.pc.toString()
                    weight = String.format("%.1f", warehouse.weight)
                    flight = warehouse.flight
                    fno = warehouse.fno
                    fdate = warehouse.fdate
                    whId = warehouse.whId
                }
            }
        }

        // 插入到ULD行后面
        list.addAll(uldPosition + 1, waybillRows)
        assembleInfoList.value = list
    }

    /**
     * 移除指定ULD后的二级运单行
     */
    private fun removeWaybillRows(uldPosition: Int) {
        val list = assembleInfoList.value?.toMutableList() ?: return
        val uldItem = list[uldPosition]

        // 移除该ULD的所有二级行
        list.removeAll {
            it.itemType == AssembleInfoBean.ItemType.WAYBILL_DETAIL &&
            it.parentUldNo == uldItem.uldNo
        }

        assembleInfoList.value = list
    }

    /**
     * 从二级运单行填充表单（编辑模式）
     * 1. 填充ULD信息（并锁定ULD编号）
     * 2. 填充运单信息（使用原始运单件数/重量，只读）
     * 3. 保留组装件数、组装重量、组装人为可编辑
     */
    private fun fillFormFromWaybillDetail(item: AssembleInfoBean) {
        val waybill = item.waybillData ?: return

        // 1. 填充ULD信息
        uldInfo.value = uldInfo.value?.apply {
            uldNo = item.parentUldNo
            // 耗材重量、ULD状态保持不变
        }

        // 保存当前的组装人（在创建新对象前，从operator LiveData读取）
        val previousOperator = operator.value ?: ""

        // 2. 填充运单信息
        waybillInfo.value = WaybillInfoBean().apply {
            waybillNo = waybill.waybillNo
            waybillPieces = waybill.originalPieces  // 使用原始运单件数
            waybillWeight = waybill.originalWeight  // 使用原始运单重量
            // 填充已累积的组装件数和组装重量（可编辑）
            assembleCount = waybill.pieces
            assembleWeight = waybill.weight
            operator = previousOperator  // 保留之前选择的组装人
        }

        // 3. 锁定ULD编号
        isUldNoLocked.value = true

        // 4. 查询ULD信息（如果需要）
        if (item.parentUldNo != lastQueriedUldNo) {
            lastQueriedUldNo = item.parentUldNo
            queryUldInfo(item.parentUldNo)
        }
    }

    /**
     * 查询已组装的ULD列表
     * 参数来源：
     * - fno/fdate：从当前选中的运单自动提取
     * - loadArea：从当前选中的组装位置获取
     * - uld：从ULD搜索框获取（可选）
     */
    fun loadAssembledList() {
        // 1. 参数验证
        val fno = assembleFlightNo.value ?: ""
        val fdate = assembleFlightDate.value ?: ""
        val loadArea = selectedPosition.value?.positionName ?: ""
        val uldSearch = uldSearchText.value ?: ""

        // 必填参数检查
        if (fno.isEmpty() || fdate.isEmpty() || loadArea.isEmpty()) {
            // 参数缺失，清空列表（静默处理）
            assembleInfoList.value = mutableListOf()
            return
        }

        // 2. 防抖检查（避免重复查询）
        val currentParams = "$fno|$fdate|$loadArea|$uldSearch"
        if (currentParams == lastQueriedAssembledParams) {
            return
        }
        lastQueriedAssembledParams = currentParams

        // 3. 构建请求参数
        val params = mapOf(
            "fno" to fno,
            "fdate" to fdate,
            "loadArea" to loadArea,
            "uld" to uldSearch.ifEmpty { null }  // 空值时传null
        ).toRequestBody()

        // 4. 调用接口
        launchLoadingCollect({ NetApply.api.getAssembledList(params) }) {
            onSuccess = { result ->
                val uldList = result.data ?: emptyList()

                if (uldList.isEmpty()) {
                    showToast("暂无已组装记录")
                    assembleInfoList.value = mutableListOf()
                } else {
                    // 转换为AssembleInfoBean列表
                    convertToAssembleInfoBeans(uldList)
                }
            }
            onFailed = { code, message ->
                showToast("查询失败: $message")
                assembleInfoList.value = mutableListOf()
            }
        }
    }

    /**
     * 数据转换: List<GjcAssembled> → List<AssembleInfoBean>
     * 只生成一级ULD行，不包含二级运单行
     * 同时将运单列表缓存到uldBean.waybillDetails
     */
    private fun convertToAssembleInfoBeans(assembledList: List<GjcAssembled>) {
        val infoList = assembledList.mapIndexed { index, assembled ->
            val uldBean = assembled.uldUse
            val warehouseList = assembled.warehouseList

            if (uldBean == null) {
                return@mapIndexed null
            }

            // 缓存运单列表到uldBean（展开时不需要再次查询）
            if (warehouseList != null && warehouseList.isNotEmpty()) {
                uldBean.waybillDetails = warehouseList
            }

            // 计算总件数和总重量（从运单列表求和）
            val calculatedPieces = warehouseList?.sumOf { it.pc.toInt() } ?: 0
            val calculatedWeight = warehouseList?.sumOf { it.weight } ?: 0.0

            AssembleInfoBean().apply {
                itemType = AssembleInfoBean.ItemType.ULD_HEADER
                uldNo = uldBean.uld
                uldIndex = index + 1

                // 使用计算的总件数和总重量
                totalPieces = calculatedPieces
                totalWeight = calculatedWeight

                hasArrow = true
                showIndex = true
                isExpanded.set(false)  // 默认折叠

                // 关联原始ULD数据（用于点击展开时查询）
                tag = uldBean  // 使用tag存储GjcUldUseBean对象
            }
        }.filterNotNull().toMutableList()

        assembleInfoList.value = infoList
    }

    /**
     * ULD搜索框输入完成回调
     */
    fun onUldSearchInputComplete() {
        loadAssembledList()
    }

    /**
     * 清空表单并退出编辑模式
     */
    private fun clearForm() {
        // 保留组装人的值（用户期望保留上一次的选择，从operator LiveData读取）
        val previousOperator = operator.value ?: ""

        waybillInfo.value = WaybillInfoBean().apply {
            operator = previousOperator  // 恢复组装人
        }
        isUldNoLocked.value = false
    }

    /**
     * 清空缓存的组装人（登出时调用）
     */
    fun clearCachedOperator() {
        lastSelectedOperator = null
    }
}
