package com.lukouguoji.gjc.viewModel

import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.holder.IntExpMoveViewHolder
import com.lukouguoji.module_base.base.BasePageViewModel
import com.lukouguoji.module_base.bean.GjcMove
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.interfaces.IOnItemClickListener
import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.noNull
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.util.CheckUtil
import com.lukouguoji.module_base.util.DictUtils
import dev.utils.app.info.KeyValue

/**
 * 国际出港移库ViewModel
 */
class IntExpMoveViewModel : BasePageViewModel(), IOnItemClickListener {

    // ========== 搜索字段 ==========
    val awbType = MutableLiveData("")              // 运单类型
    val by1 = MutableLiveData("")                  // 承运人
    val dest1 = MutableLiveData("")                // 卸货站（仅平板筛选，手机版设计稿无此项）
    val moveState = MutableLiveData("")            // 移库状态
    val waybillNo = MutableLiveData("")            // 运单号

    // ========== 手机版（5.5 寸手持端）专用 ==========
    // 平板布局无对应控件，spCode 恒为空 → 不进请求，平板查询行为与改造前一致
    val spCode = MutableLiveData("")               // 特码

    /** 特码下拉数据（仅手机版筛选弹层使用，由 [initPhoneExtras] 触发加载） */
    val spCodeList = MutableLiveData<List<KeyValue>>(emptyList())

    /** 手机版状态 Tab 配置（设计稿只有两个 Tab，无「全部」） */
    val moveStateTabs = MutableLiveData(
        listOf(KeyValue("待移库", "0"), KeyValue("已移库", "1"))
    )

    /** 手机版状态 Tab 角标（与 [moveStateTabs] 等长） */
    val moveStateCounts = MutableLiveData(listOf("", ""))

    /** 已选数量（手机版底部操作条「已选 N 项」） */
    val selectedCount = MutableLiveData("0")

    /**
     * 是否启用手机版专属数据（Tab 角标计数、特码下拉）。
     * 平板端保持 false，不产生任何额外接口请求。
     */
    private var phoneExtrasEnabled = false

    /**
     * 开启手机版专属数据：默认停留「待移库」Tab、加载特码下拉、启用 Tab 角标计数。
     * 仅由手机形态的 Activity 调用。
     */
    fun initPhoneExtras() {
        phoneExtrasEnabled = true
        moveState.value = "0"
        // flag=1 国际；ieFlag 必须留空——传 "E" 后端返回空数组，
        // 与 GjcWeighingStartViewModel 等既有国际出港页面的调用方式保持一致
        DictUtils.getSpecialCodeList(addAll = false, flag = 1, ieFlag = "") { list ->
            spCodeList.postValue(list)
        }
    }

    // ========== 运单类型下拉数据 ==========
    val awbTypeList = MutableLiveData<List<KeyValue>>().apply {
        value = listOf(
            KeyValue("全部", ""),
            KeyValue("转国内出港", "IOCO")
        )
    }

    // ========== 移库状态下拉数据 ==========
    val moveStateList = MutableLiveData<List<KeyValue>>().apply {
        value = listOf(
            KeyValue("全部", ""),
            KeyValue("未移库", "0"),
            KeyValue("已移库", "1")
        )
    }

    // ========== 底部统计 ==========
    val totalCount = MutableLiveData("0")       // 合计票数
    val totalPieces = MutableLiveData("0")      // 总件数
    val totalWeight = MutableLiveData("0")      // 总重量

    // ========== 全选状态 ==========
    val isAllChecked = MutableLiveData(false)

    // ========== 适配器配置 ==========
    val itemViewHolder = IntExpMoveViewHolder::class.java

    // 布局 id 不区分设备，平板/手机由资源限定符自动选择（layout-sw600dp/ 与 layout/ 下的同名布局）
    val itemLayoutId = R.layout.item_int_exp_move

    /**
     * 搜索按钮点击
     */
    fun searchClick() {
        refresh()
    }

    /**
     * 扫码运单号（在Activity中实现）
     */
    fun scanWaybill() {
        // 由Activity处理扫码逻辑
    }

    /**
     * 全选/取消全选
     */
    fun toggleSelectAll() {
        val adapter = pageModel.rv?.commonAdapter() ?: return
        val list = adapter.items.filterIsInstance<GjcMove>()

        // 使用CheckUtil处理全选逻辑
        CheckUtil.handleAllCheck(list)

        // 更新全选状态
        updateCheckAllStatus()

        // 刷新UI
        adapter.notifyDataSetChanged()
    }

    /**
     * 更新全选状态
     */
    fun updateCheckAllStatus() {
        val adapter = pageModel.rv?.commonAdapter() ?: return
        val list = adapter.items.filterIsInstance<GjcMove>()

        if (list.isNotEmpty()) {
            isAllChecked.value = list.all { it.checked.get() }
        } else {
            isAllChecked.value = false
        }

        selectedCount.value = list.count { it.checked.get() }.toString()
    }

    /**
     * 单个item选择变化时调用(从Activity接收事件)
     */
    fun onItemCheckChanged() {
        updateCheckAllStatus()
    }

    /**
     * 获取选中的运单
     */
    fun getSelectedItems(): List<GjcMove> {
        val adapter = pageModel.rv?.commonAdapter() ?: return emptyList()
        return adapter.items.filterIsInstance<GjcMove>().filter { it.checked.get() }
    }

    /**
     * 提交移库（在Activity中显示确认对话框后调用）
     */
    fun submitMove() {
        val selectedItems = getSelectedItems()

        if (selectedItems.isEmpty()) {
            showToast("请至少选择一条运单")
            return
        }

        val params = selectedItems.toRequestBody()

        launchLoadingCollect({ NetApply.api.submitIntExpMove(params) }) {
            onSuccess = {
                showToast("移库成功")
                refresh()  // 刷新列表
            }
            onFailed = { _, msg ->
                showToast(msg.noNull("移库失败"))
            }
        }
    }

    /**
     * 获取列表数据
     */
    override fun getData() {
        // 构建筛选参数（只传递非空值）
        val filterParams = mutableMapOf<String, Any>()

        awbType.value?.takeIf { it.isNotEmpty() }?.let { filterParams["awbType"] = it }
        by1.value?.takeIf { it.isNotEmpty() }?.let { filterParams["by1"] = it }
        dest1.value?.takeIf { it.isNotEmpty() }?.let { filterParams["dest1"] = it }
        moveState.value?.takeIf { it.isNotEmpty() }?.let { filterParams["moveState"] = it }
        waybillNo.value?.takeIf { it.isNotEmpty() }?.let { filterParams["wbNo"] = it }
        // 手机版新增筛选维度，平板端恒为空故不参与查询
        spCode.value?.takeIf { it.isNotEmpty() }?.let { filterParams["spCode"] = it }

        // 列表参数（含分页）
        val listParams = (filterParams + mapOf(
            "pageNum" to pageModel.page,
            "pageSize" to pageModel.limit
        )).toRequestBody()

        // 统计参数（无分页）
        val totalParams = filterParams.toRequestBody()

        // 获取列表（显示loading）
        launchLoadingCollect({ NetApply.api.getIntExpMoveList(listParams) }) {
            onSuccess = {
                pageModel.handleListBean(it) { updateCheckAllStatus() }
            }
        }

        // 获取统计（后台调用）
        getTotalData(totalParams)

        // 手机版 Tab 角标计数（平板端不触发，无额外请求）
        if (phoneExtrasEnabled) {
            loadTabCounts(filterParams)
        }
    }

    /**
     * 加载「待移库 / 已移库」Tab 角标数量。
     *
     * 复用统计接口，分别以 moveState=0 / 1 各查一次，并沿用当前其余筛选条件，
     * 保证角标与列表口径一致。仅手机版调用。
     */
    private fun loadTabCounts(filterParams: Map<String, Any>) {
        listOf("0", "1").forEachIndexed { index, state ->
            val params = (filterParams + mapOf("moveState" to state)).toRequestBody()
            launchCollect({ NetApply.api.getIntExpMoveTotal(params) }) {
                onSuccess = { result ->
                    val count = (result.data?.wbNumber ?: 0).toString()
                    val current = moveStateCounts.value?.toMutableList() ?: mutableListOf("", "")
                    if (index < current.size) {
                        current[index] = count
                        moveStateCounts.value = current
                    }
                }
            }
        }
    }

    /**
     * 获取统计数据（无Loading）
     */
    private fun getTotalData(params: okhttp3.RequestBody) {
        launchCollect({ NetApply.api.getIntExpMoveTotal(params) }) {
            onSuccess = { result ->
                val data = result.data
                totalCount.value = (data?.wbNumber ?: 0).toString()
                totalPieces.value = (data?.totalPc ?: 0L).toString()
                totalWeight.value = (data?.totalWeight ?: 0.0).toString()
            }
        }
    }

    /**
     * Item点击事件处理（现已改为图标点击，此方法暂时保留兼容）
     */
    override fun onItemClick(position: Int, type: Int) {
        // 图标点击已在ViewHolder中处理，此处不再需要
    }
}
