package com.lukouguoji.gjc.viewModel

import android.content.Intent
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.GjcCheckInRecord
import com.lukouguoji.module_base.bean.GjcWeighingRecordBean
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.launchLoadingCollect
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
import kotlinx.coroutines.launch

/**
 * 国际出港计重明细 ViewModel
 * 严格按照设计图实现三个独立部分：运单信息、计重记录列表、底部统计与按钮
 */
class GjcWeighingRecordDetailsViewModel : BaseViewModel() {

    ///////////////////////////////////////////////////////////////////////////
    // 数据字段
    ///////////////////////////////////////////////////////////////////////////

    // 运单信息Bean（从列表页传入）
    val waybillBean = MutableLiveData<GjcWeighingRecordBean>()

    // 编辑模式：false=只读，true=编辑
    val isEditMode = MutableLiveData(false)

    // 计重记录列表
    val recordList = MutableLiveData<List<GjcCheckInRecord>>(emptyList())

    // 备份数据（用于取消时恢复）
    private var backupList: List<GjcCheckInRecord> = emptyList()

    ///////////////////////////////////////////////////////////////////////////
    // 第一部分：运单信息字段（顶部显示区域）
    ///////////////////////////////////////////////////////////////////////////

    val waybillNo = MutableLiveData("")        // 运单号（prefix-no）
    val prePc = MutableLiveData("")            // 预配件数
    val preWeight = MutableLiveData("")        // 预配重量
    val goodsName = MutableLiveData("")        // 品名（中文）

    ///////////////////////////////////////////////////////////////////////////
    // 第三部分：底部统计字段
    ///////////////////////////////////////////////////////////////////////////

    val totalPc = MutableLiveData("0")         // 总件数
    val totalWeight = MutableLiveData("0.0")   // 总重量
    val weightError = MutableLiveData("0.0%")  // 重量误差百分比
    val totalCarWeight = MutableLiveData("0")  // 托盘总重（5.5寸手机版顶部卡片，平板布局不引用）

    // 传递参数（用于API调用）
    private var prefix = ""
    private var no = ""
    private var opDate = ""

    init {
        // 监听 recordList 变化，自动触发统计计算
        recordList.observeForever {
            calculateStatistics()
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // 初始化
    ///////////////////////////////////////////////////////////////////////////

    fun initOnCreated(intent: Intent) {
        // 接收传入的完整 Bean 对象
        val bean = intent.getSerializableExtra(Constant.Key.BEAN) as? GjcWeighingRecordBean
        bean?.let {
            waybillBean.value = it

            // 提取运单信息字段
            waybillNo.value = it.wbNo
            prePc.value = it.pc.toString()
            preWeight.value = it.weight.toString()
            goodsName.value = it.goodsCn

            // 保存参数用于API调用
            prefix = it.prefix
            no = it.no
            opDate = it.opDate

            // 加载计重记录数据
            loadData()
        } ?: run {
            showToast("参数错误")
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // 数据加载
    ///////////////////////////////////////////////////////////////////////////

    private fun loadData() {
        val params = mapOf(
            "prefix" to prefix,
            "no" to no,
            "opDate" to opDate
        ).toRequestBody()

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

                // 为每个记录设置数据变化回调
                list.forEach { record ->
                    record.onDataChanged = {
                        // 数据变化时重新计算统计
                        calculateStatistics()
                    }
                }

                recordList.value = list

                if (list.isEmpty()) {
                    showToast("暂无计重记录")
                }
            }
            onFailed = { code, msg ->
                showToast("加载失败：$msg")
            }
        }
    }

    /**
     * 计算统计数据：总件数、总重量、重量误差
     */
    private fun calculateStatistics() {
        val records = recordList.value ?: emptyList()

        // 计算总件数
        val sumPc = records.sumOf { it.pc }
        totalPc.value = sumPc.toString()

        // 计算总重量
        val sumWeight = records.sumOf { it.weight }
        totalWeight.value = String.format("%.2f", sumWeight)

        // 计算托盘总重（手机版顶部卡片）
        val sumCarWeight = records.sumOf { it.carWeight.toDoubleOrNull() ?: 0.0 }
        totalCarWeight.value = String.format("%.2f", sumCarWeight)

        // 计算重量误差百分比
        val preWeightValue = preWeight.value?.toDoubleOrNull() ?: 0.0
        val error = if (sumWeight > 0 && preWeightValue > 0) {
            ((sumWeight - preWeightValue) / preWeightValue * 100)
        } else {
            0.0
        }
        weightError.value = String.format("%.1f%%", error)
    }

    ///////////////////////////////////////////////////////////////////////////
    // 按钮事件
    ///////////////////////////////////////////////////////////////////////////

    /**
     * 点击"修改"按钮
     */
    fun onModifyClick() {
        // 备份当前数据（深拷贝）
        backupList = recordList.value?.map { it.copy() } ?: emptyList()
        // 进入编辑模式
        isEditMode.value = true
    }

    /**
     * 点击"取消"按钮
     */
    fun onCancelClick() {
        // 恢复备份数据（深拷贝）
        recordList.value = backupList.map { it.copy() }
        // 退出编辑模式
        isEditMode.value = false
        // 重新计算统计（会自动触发）
    }

    /**
     * 点击"保存"按钮
     */
    fun onSaveClick() {
        val records = recordList.value ?: return

        // 验证数据
        if (!validateRecords(records)) return

        // 调用批量更新接口
        saveRecords(records)
    }

    /**
     * 5.5寸手机版「修改记录」覆层保存：与 [onSaveClick] 相同的批量更新接口，
     * 但保存成功后留在本页（收起覆层 + 重新加载），不关闭页面。仅手机布局调用。
     */
    fun onPhoneSaveClick() {
        val records = recordList.value ?: return

        if (!validateRecords(records)) return

        launchLoadingCollect({
            NetApply.api.updateGjcCheckInRecordList(records)
        }) {
            onSuccess = { result ->
                if (result.data == true) {
                    showToast("保存成功")
                    // 收起编辑覆层
                    isEditMode.value = false
                    // 通知列表页刷新
                    viewModelScope.launch {
                        FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
                    }
                    // 重新加载本页数据
                    loadData()
                } else {
                    showToast("保存失败")
                }
            }
            onFailed = { code, msg ->
                showToast("保存失败：$msg")
            }
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // 业务逻辑
    ///////////////////////////////////////////////////////////////////////////

    /**
     * 验证数据
     */
    private fun validateRecords(records: List<GjcCheckInRecord>): Boolean {
        records.forEachIndexed { index, record ->
            if (record.pc <= 0) {
                showToast("第${index + 1}条记录的件数必须大于0")
                return false
            }
            if (record.weight <= 0.0) {
                showToast("第${index + 1}条记录的重量必须大于0")
                return false
            }
        }
        return true
    }

    /**
     * 批量保存计重记录
     */
    private fun saveRecords(records: List<GjcCheckInRecord>) {
        launchLoadingCollect({
            NetApply.api.updateGjcCheckInRecordList(records)
        }) {
            onSuccess = { result ->
                if (result.data == true) {
                    showToast("保存成功")
                    // 退出编辑模式
                    isEditMode.value = false
                    // 发送刷新事件通知列表页
                    viewModelScope.launch {
                        FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
                    }
                    // 关闭页面
                    getTopActivity().finish()
                } else {
                    showToast("保存失败")
                }
            }
            onFailed = { code, msg ->
                showToast("保存失败：$msg")
            }
        }
    }
}
