package com.lukouguoji.gjc.viewModel

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.dialog.IntExpArriveDeleteDialogModel
import com.lukouguoji.gjc.dialog.IntExpArriveResetDialogModel
import com.lukouguoji.gjc.holder.IntExpArriveViewHolder
import com.lukouguoji.module_base.base.BasePageViewModel
import com.lukouguoji.module_base.bean.GjcDeclareParam
import com.lukouguoji.module_base.bean.GjcHaWb
import com.lukouguoji.module_base.bean.GjcMaWb
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.impl.FlowBus
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.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.model.ScanModel
import dev.utils.app.info.KeyValue
import dev.utils.common.DateUtils
import com.lukouguoji.module_base.ktx.formatDate
import kotlinx.coroutines.launch

/**
 * 国际出港-出港运抵 ViewModel
 */
class IntExpArriveViewModel : BasePageViewModel() {

    // ========== 搜索条件 ==========
    val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate())        // 航班日期
    val flightNo = MutableLiveData("")          // 航班号
    val waybillNo = MutableLiveData("")         // 运单号
    val hno = MutableLiveData("")               // 分单号

    // ========== 统计信息 ==========
    val totalCount = MutableLiveData("0")       // 合计票数
    val totalPc = MutableLiveData("0")          // 总件数
    val totalWeight = MutableLiveData("0")      // 总重量

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

    fun onItemCheckChanged() {
        updateCheckAllStatus()
        updateCheckAllStatusPhone()
    }

    fun updateCheckAllStatus() {
        val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
        isAllChecked.value = list.isNotEmpty() && list.all { it.checked.get() }
    }

    // ========== 5.5寸手机版专属（平板布局不引用，零影响） ==========

    /** 当前 Tab："pending"(待运抵) / "shipped"(已运抵)。接口无申报状态查询参数，Tab 由客户端对已加载数据拆分 */
    val currentTab = MutableLiveData("pending")

    /** Tab 配置 */
    val arriveTabs = MutableLiveData(
        listOf(KeyValue("待运抵", "pending"), KeyValue("已运抵", "shipped"))
    )

    /** 两个 Tab 的角标计数（当前已加载数据的客户端统计，非全量，见接口问题清单） */
    val arriveTabCounts = MutableLiveData(listOf("0", "0"))

    /** 手机版空态（当前 Tab 过滤后无数据时显示，对应设计稿 empty-pending） */
    val emptyVisiblePhone = MutableLiveData(false)
    val emptyTextPhone = MutableLiveData("暂无待运抵的运单")

    /** 手机版全选状态（仅统计待运抵 Tab 内的项，与 Pad 端 [isAllChecked] 统计口径不同） */
    val isAllCheckedPhone = MutableLiveData(false)

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

    /** 手机版筛选弹层「代理」（后端 pageQuery 支持 agentCode 入参，复用既有 agentCode 语义查询） */
    val agentCodePhone = MutableLiveData("")
    val agentListPhone = MutableLiveData<List<KeyValue>>(emptyList())

    private var phoneExtrasEnabled = false

    /**
     * 完整已加载列表（跨分页累计，未按 Tab 过滤）。
     *
     * ⚠️ RecyclerView/LinearLayoutManager 不会像普通 ViewGroup 那样让 `View.GONE` 的子项
     * 自动塌陷为 0 高度——它仍按子项的测量高度参与滚动区域计算，导致"隐藏"的卡片在列表里
     * 留下一段空白（已实机截图验证）。因此 Tab 切换不能靠给 item 加 visibility 绑定，
     * 必须真正地把适配器的数据集替换成过滤后的子集（[applyTabFilterPhone]）。
     */
    private var allLoadedList: List<GjcMaWb> = emptyList()

    /**
     * 开启手机版专属数据：加载「代理」筛选下拉。仅由手机形态的 Activity 调用。
     */
    fun initPhoneExtras() {
        phoneExtrasEnabled = true
        launchCollect({ NetApply.api.getIntExpAgentList() }) {
            onSuccess = { result ->
                agentListPhone.postValue(
                    listOf(KeyValue("全部", "")) + (result.data ?: emptyList()).map { KeyValue(it.name ?: "", it.code ?: "") }
                )
            }
        }
    }

    /**
     * 手机版 Tab 切换：将适配器数据集替换为过滤后的子集（不重新请求）。
     * 由 Activity 在 [com.lukouguoji.module_base.ui.weight.phone.PhoneStatusTab] 的
     * 双向绑定写入 currentTab 后调用。
     */
    fun onTabChangedPhone() {
        applyTabFilterPhone()
    }

    private fun applyTabFilterPhone() {
        val isPendingTab = currentTab.value == "pending"
        val filtered = allLoadedList.filter { it.isPending == isPendingTab }
        pageModel.rv?.commonAdapter()?.refresh(filtered)
        emptyVisiblePhone.value = filtered.isEmpty()
        emptyTextPhone.value = if (isPendingTab) "暂无待运抵的运单" else "暂无已运抵的运单"
        updateCheckAllStatusPhone()
    }

    /**
     * 根据完整已加载列表重新计算 Tab 角标计数（每次数据变化后调用）。
     */
    private fun updatePhoneTabCounts() {
        val pending = allLoadedList.count { it.isPending }.toString()
        val shipped = allLoadedList.count { !it.isPending }.toString()
        arriveTabCounts.value = listOf(pending, shipped)
    }

    /**
     * 手机版全选（适配器此时已只包含当前 Tab 的子集，待运抵 Tab 下即为全部可选项）。
     */
    fun checkAllClickPhone() {
        val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
        val shouldCheckAll = !isAllCheckedPhone.value!!
        list.forEach { it.checked.set(shouldCheckAll) }
        isAllCheckedPhone.value = shouldCheckAll
        updateCheckAllStatusPhone()
        pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
    }

    /**
     * 更新手机版全选状态与已选计数（基于适配器当前子集，即当前 Tab 的数据）。
     */
    fun updateCheckAllStatusPhone() {
        val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
        isAllCheckedPhone.value = list.isNotEmpty() && list.all { it.checked.get() }
        selectedCountPhone.value = list.count { it.checked.get() }.toString()
    }

    // ========== 全局展开状态 ==========
    /**
     * 全局展开状态
     * - true: 全部展开
     * - false: 全部收起
     */
    val isAllExpanded = MutableLiveData(false)

    // ========== 适配器配置 ==========
    val itemViewHolder = IntExpArriveViewHolder::class.java
    val itemLayoutId = R.layout.item_int_exp_arrive

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

    /**
     * 全选按钮点击 (切换全选状态)
     */
    fun checkAllClick() {
        val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return

        // 切换全选状态
        val shouldCheckAll = !isAllChecked.value!!
        list.forEach { it.checked.set(shouldCheckAll) }
        isAllChecked.value = shouldCheckAll

        pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
    }

    /**
     * 切换全局展开/收起状态
     */
    fun toggleAllExpand() {
        val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return

        // 切换全局状态
        val shouldExpand = !isAllExpanded.value!!
        isAllExpanded.value = shouldExpand

        list.forEach { bean ->
            bean.showMore.set(shouldExpand)
        }

        // 刷新列表UI
        pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
    }

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

    /**
     * 扫码分单号
     */
    fun scanHaWb() {
        ScanModel.startScan(getTopActivity(), Constant.RequestCode.CODE)
    }

    /**
     * 状态重置
     */
    fun resetDeclareClick() {
        val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return

        // 收集选中的主单
        val selectedMaWbList = list.filter { it.isSelected }

        // 收集选中的分单
        val selectedHaWbList = mutableListOf<GjcHaWb>()
        list.forEach { maWb ->
            maWb.haWbList?.forEach { haWb ->
                if (haWb.isSelected) {
                    selectedHaWbList.add(haWb)
                }
            }
        }

        // 检查是否有选中项
        if (selectedMaWbList.isEmpty() && selectedHaWbList.isEmpty()) {
            showToast("请选择要重置的运单")
            return
        }

        // 创建并显示弹框
        val dialog = IntExpArriveResetDialogModel { dialogModel ->
            // 弹框确认后的回调
            // 构建请求参数（区分主单和分单）
            val params = mutableMapOf<String, Any?>()
            if (selectedMaWbList.isNotEmpty()) {
                params["maWbList"] = selectedMaWbList
            }
            if (selectedHaWbList.isNotEmpty()) {
                params["haWbList"] = selectedHaWbList
            }

            // 根据选择添加restStatus参数
            // 选择"正常"时传递 "01"，选择"未申报"时不传递此参数
            if (dialogModel.resetStatusCode != null) {
                params["restStatus"] = dialogModel.resetStatusCode
            }

            val requestData = params.toRequestBody()

            // 调用重置接口
            launchLoadingCollect({ NetApply.api.resetArriveDeclare(requestData) }) {
                onSuccess = {
                    showToast("状态重置成功")
                    viewModelScope.launch {
                        FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
                    }
                    refresh()
                }
            }
        }

        dialog.show()
    }

    /**
     * 删除申报
     */
    fun deleteDeclareClick() {
        val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return

        // 收集选中的主单
        val selectedMaWbList = list.filter { it.isSelected }

        // 收集选中的分单
        val selectedHaWbList = mutableListOf<GjcHaWb>()
        list.forEach { maWb ->
            maWb.haWbList?.forEach { haWb ->
                if (haWb.isSelected) {
                    selectedHaWbList.add(haWb)
                }
            }
        }

        // 检查是否有选中项（主单和分单分开判断，互不影响）
        if (selectedMaWbList.isEmpty() && selectedHaWbList.isEmpty()) {
            showToast("请选择要删除申报的记录")
            return
        }

        // 校验申报状态：只有申报状态为 01 的记录才能删除申报
        if (selectedMaWbList.any { it.declareStatus != "01" } ||
            selectedHaWbList.any { it.arrivalStatus != "01" }
        ) {
            showToast("只能删除申报状态为01的运单")
            return
        }

        // 从接口获取删除原因列表
        launchLoadingCollect({ NetApply.api.getDelReasonList() }) {
            onSuccess = { result ->
                val changeReasonList = result.data?.map { it.toKeyValue() } ?: emptyList()

                // 创建并显示弹框
                val dialog = IntExpArriveDeleteDialogModel(changeReasonList) { dialogModel ->
                    // 弹框确认后的回调（区分主单和分单）
                    val param = GjcDeclareParam(
                        dcode = dialogModel.changeReason.value,
                        dcontactsName = dialogModel.contactName.value,
                        dcontactsTel = dialogModel.contactPhone.value,
                        maWbList = if (selectedMaWbList.isNotEmpty()) selectedMaWbList else null,
                        haWbList = if (selectedHaWbList.isNotEmpty()) selectedHaWbList else null
                    )

                    val requestData = param.toRequestBody()

                    // 调用删除接口
                    launchLoadingCollect({ NetApply.api.deleteArriveDeclare(requestData) }) {
                        onSuccess = {
                            showToast("删除申报成功")
                            viewModelScope.launch {
                                FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
                            }
                            refresh()
                        }
                    }
                }

                dialog.show()
            }
        }
    }

    /**
     * 运抵申报
     */
    fun arriveReportClick() {
        val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return

        // 收集选中的主单
        val selectedMaWbList = list.filter { it.isSelected }

        // 收集选中的分单
        val selectedHaWbList = mutableListOf<GjcHaWb>()
        list.forEach { maWb ->
            maWb.haWbList?.forEach { haWb ->
                if (haWb.isSelected) {
                    selectedHaWbList.add(haWb)
                }
            }
        }

        // 检查是否有选中项
        if (selectedMaWbList.isEmpty() && selectedHaWbList.isEmpty()) {
            showToast("请选择要申报的运单")
            return
        }

        // 构建请求参数（区分主单和分单）
        val params = mutableMapOf<String, Any?>()
        if (selectedMaWbList.isNotEmpty()) {
            params["maWbList"] = selectedMaWbList
        }
        if (selectedHaWbList.isNotEmpty()) {
            params["haWbList"] = selectedHaWbList
        }

        val requestData = params.toRequestBody()

        launchLoadingCollect({ NetApply.api.arriveDeclare(requestData) }) {
            onSuccess = {
                showToast("运抵申报成功")
                viewModelScope.launch {
                    FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
                }
                refresh()
            }
        }
    }

    /**
     * 手机版：卡片长按菜单「重置」（单条，已运抵 Tab 专用，对应设计稿长按浮层）。
     */
    fun resetSingleDeclareClick(bean: GjcMaWb) {
        bean.actionMenuVisible.set(false)

        val dialog = IntExpArriveResetDialogModel { dialogModel ->
            val params = mutableMapOf<String, Any?>("maWbList" to listOf(bean))
            if (dialogModel.resetStatusCode != null) {
                params["restStatus"] = dialogModel.resetStatusCode
            }
            launchLoadingCollect({ NetApply.api.resetArriveDeclare(params.toRequestBody()) }) {
                onSuccess = {
                    showToast("状态重置成功")
                    viewModelScope.launch {
                        FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
                    }
                    refresh()
                }
            }
        }
        dialog.show()
    }

    /**
     * 获取数据 (重写BasePageViewModel)
     */
    override fun getData() {
        // 构建搜索条件
        val filterParams = mutableMapOf<String, Any?>(
            "fdate" to flightDate.value?.ifEmpty { null },
            "fno" to flightNo.value?.ifEmpty { null },
            "wbNo" to waybillNo.value?.ifEmpty { null },
            "hno" to hno.value?.ifEmpty { null }
        )

        // 手机版专属条件（平板 phoneExtrasEnabled 恒为 false，请求体与改造前完全一致）
        if (phoneExtrasEnabled) {
            // 搜索分流（与出港计重页一致）：11 位数字精确匹配 wbNo，其余走 likeNo 模糊
            val key = waybillNo.value?.trim() ?: ""
            if (key.isNotEmpty() && key.length != 11) {
                filterParams["wbNo"] = null
                filterParams["likeNo"] = key
            }
            filterParams["agentCode"] = agentCodePhone.value?.ifEmpty { null }
        }

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

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

        // 获取列表 (带Loading)
        launchLoadingCollect({ NetApply.api.getIntExpArriveList(listParams) }) {
            onSuccess = { result ->
                // 手机版：自行维护完整累计列表（不依赖 adapter.items 的历史状态，见 allLoadedList 注释）
                if (phoneExtrasEnabled) {
                    val newPageItems = result.list ?: emptyList()
                    allLoadedList = if (pageModel.page <= 1) newPageItems else allLoadedList + newPageItems
                }

                pageModel.handleListBean(result) {
                    updateCheckAllStatus()
                    if (phoneExtrasEnabled) {
                        // 用完整列表强制覆盖 adapter 数据集为当前 Tab 的过滤子集
                        applyTabFilterPhone()
                        updatePhoneTabCounts()
                    }
                }
                // 数据加载完成后，重置全局展开状态为收起
                isAllExpanded.value = false
            }
        }

        // 获取统计信息 (后台请求)
        launchCollect({ NetApply.api.getIntExpArriveTotal(totalParams) }) {
            onSuccess = { result ->
                val data = result.data
                totalCount.value = (data?.wbNumber ?: 0).toString()
                totalPc.value = (data?.totalPc ?: 0).toString()
                totalWeight.value = (data?.totalWeight ?: 0.0).toString()
            }
        }
    }
}
