package com.lukouguoji.gjc.viewModel

import android.app.Activity
import android.content.Intent
import android.view.View
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.GjcMaWb
import com.lukouguoji.module_base.bean.GjcWeighingBean
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.http.net.DiBangWeightModel
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.ktx.formatDate
import com.lukouguoji.module_base.ktx.getActivity
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.ktx.verifyNullOrEmpty
import com.lukouguoji.module_base.model.ScanModel
import com.lukouguoji.module_base.util.Common
import com.lukouguoji.module_base.util.DictUtils
import dev.utils.app.info.KeyValue
import dev.utils.common.DateUtils
import kotlinx.coroutines.launch
import java.util.Calendar
import java.util.Date

/**
 * 国际出港计重-开始计重 ViewModel
 */
class GjcWeighingStartViewModel : BaseViewModel() {

    // 运单ID（从列表页传入，或通过运单号查询获得）
    var maWbId: Long = 0

    // 运单数据Bean
    val maWbBean = MutableLiveData(GjcMaWb())

    // 用于防止重复查询的标记
    private var lastQueriedWbNo: String = ""
    private var lastQueriedCarId: String = ""

    // 航班日期（格式化为字符串用于DataBinding）
    val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate())

    // 地磅集成（已改为手动输入，暂时注释）
    // val diBangModel = DiBangWeightModel()
    val channel = MutableLiveData("")  // 通道号

    // 地磅称重显示（手动输入，单向同步到运抵重量）
    val diBangWeight = MutableLiveData("0")  // 地磅重量（右上角黄色显示区域）

    // 可编辑字段（用于双向绑定）
    val realTimePc = MutableLiveData("")          // 实时件数
    val realTimeWeight = MutableLiveData("")      // 实时重量
    val realTimeVolume = MutableLiveData("")      // 实时体积
    val arrivePc = MutableLiveData("")            // 运抵件数
    val arriveWeight = MutableLiveData("")        // 运抵重量
    val arriveVolume = MutableLiveData("")        // 运抵体积

    val pageRemark = MutableLiveData("")    // 备注

    // 下拉选择数据源
    val channelList = MutableLiveData<List<KeyValue>>()        // 通道号列表
    val agentList = MutableLiveData<List<KeyValue>>()          // 代理人列表
    val spCodeList = MutableLiveData<List<KeyValue>>()         // 特码列表
    val businessTypeList = MutableLiveData<List<KeyValue>>()   // 业务类型列表

    // 托盘车自重（平板：托盘车号查询回填只读；手机：手输，见下方 initPhoneExtras）
    val carWeight = MutableLiveData("0")

    // ========== 5.5寸手机版专属（平板不调用 initPhoneExtras，行为零变化） ==========

    /** 托盘数量（设计稿字段，后端暂无对应入参，提交时传 palletNumber 预留参数，见接口问题清单） */
    val palletNumber = MutableLiveData("")

    /** 手机形态标记：为 true 时提交体额外携带 palletNumber / carWeight（后端静默忽略） */
    private var phoneMode = false

    /** 仅由手机形态的 Activity 调用 */
    fun initPhoneExtras() {
        phoneMode = true
    }

    /**
     * 初始化
     */
    fun initOnCreated(activity: Activity, intent: Intent) {
        // 获取传入的运单ID
        maWbId = intent.getLongExtra(Constant.Key.MAWB_ID, 0)

        // 监听地磅称重输入，单向同步到运抵重量
        diBangWeight.observe(activity as LifecycleOwner) { weight ->
            // 同步到运抵重量（单向，不做反向同步）
            arriveWeight.value = weight ?: "0"
        }

        // 监听运抵重量变化，自动计算运抵体积
        arriveWeight.observe(activity as LifecycleOwner) { weightStr ->
            // 将字符串转换为 Double，如果转换失败或为空则使用 0.0
            val weight = weightStr?.toDoubleOrNull() ?: 0.0

            // 计算体积：运抵体积 = 运抵重量 / 220
            val volume = if (weight > 0) weight / 220.0 else 0.0

            // 格式化为两位小数并更新 LiveData
            arriveVolume.value = String.format("%.2f", volume)
        }

        // 加载下拉列表数据
        loadChannelList()
        loadAgentList()
        loadSpCodeList()
        loadBusinessTypeList()

        // 加载运单数据
        if (maWbId > 0) {
            loadWeighingData()
            loadRealTimeRecord()  // 新增: 加载实时计重数据
        }
    }

    /**
     * 加载通道号列表 (国际出港专用)
     */
    private fun loadChannelList() {
        DictUtils.getGjcChannelList {
            channelList.value = it
        }
    }

    /**
     * 加载代理人列表 (国际出港专用)
     */
    private fun loadAgentList() {
        launchCollect({
            NetApply.api.getIntExpAgentList()
        }) {
            onSuccess = { result ->
                val list = (result.data ?: emptyList()).map { it.toKeyValue() }
                agentList.value = list
            }
        }
    }

    /**
     * 加载特码列表
     */
    private fun loadSpCodeList() {
        DictUtils.getSpecialCodeList(
            flag = 1,           // 国际
            ieFlag = "",        // 空字符串
            parentcode = ""     // 无父级
        ) {
            spCodeList.value = it
        }
    }

    /**
     * 加载业务类型列表
     */
    private fun loadBusinessTypeList() {
        DictUtils.getBusinessTypeList(
            type = "IO",        // IO = 国际出港
            addAll = false      // 不添加"全部"选项
        ) {
            businessTypeList.value = it
        }
    }

    /**
     * 加载运单详情数据
     */
    private fun loadWeighingData() {
        launchLoadingCollect({ NetApply.api.getIntExpCheckInWbById(maWbId) }) {
            onSuccess = { result ->
                maWbBean.value = result.data ?: GjcMaWb()
                pageRemark.value = maWbBean.value?.remark
                // 更新航班日期字符串
                flightDate.value = result.data?.fdate?.formatDate() ?: ""
            }
        }
    }

    /**
     * 加载实时计重数据 (仅调用一次)
     */
    private fun loadRealTimeRecord() {
        launchCollect({ NetApply.api.getIntExpRealTimeRecord(maWbId) }) {
            onSuccess = { result ->
                val record = result.data
                realTimePc.value = (record?.pc ?: 0).toString()
                realTimeWeight.value = String.format("%.2f", record?.weight ?: 0.0)
                realTimeVolume.value = String.format("%.3f", record?.volume ?: 0.0)
            }
        }
    }

    /**
     * 运单号输入完成时调用（添加模式专用）
     * 当用户输入完整运单号后，自动根据运单号查询并填充表单
     */
    fun onWaybillNoInputComplete() {
        val wbNo = maWbBean.value?.wbNo ?: ""

        // 验证运单号是否为空
        if (wbNo.isEmpty()) {
            return
        }

        // 防止重复查询
        if (wbNo == lastQueriedWbNo) {
            return
        }

        // 验证运单号长度（11位）
        if (wbNo.length != 11) {
            showToast("请输入完整的11位运单号")
            return
        }

        // 更新查询标记
        lastQueriedWbNo = wbNo

        // 直接根据运单号查询运单详情
        launchLoadingCollect({ NetApply.api.getIntExpCheckInWbByNo(wbNo) }) {
            onSuccess = { result ->
                val data = result.data
                if (data != null) {
                    // 保存 maWbId
                    maWbId = data.maWbId ?: 0

                    // 更新整个 maWbBean
                    maWbBean.value = data

                    // 更新航班日期字符串
                    flightDate.value = data.fdate?.formatDate() ?: ""

                    // 更新备注
                    pageRemark.value = data.remark

                    // 加载实时计重数据（如果 maWbId 有效）
                    if (maWbId > 0) {
                        loadRealTimeRecord()
                    }
                } else {
                    showToast("未找到该运单信息")
                    // 清空查询标记，允许重新查询
                    lastQueriedWbNo = ""
                }
            }
            onFailed = { code, msg ->
                showToast("查询失败: $msg")
                // 清空查询标记，允许重新查询
                lastQueriedWbNo = ""
            }
        }
    }

    /**
     * 航班日期点击
     */
    fun flightDateClick(view: View) {
        Common.onYearMonthDay(
            view.context.getActivity(),
            maWbBean.value?.fdate?.formatDate()
        ) { year, month, day ->
            val calendar = Calendar.getInstance()
            calendar.set(year, month - 1, day)
            val date = calendar.time
            maWbBean.value = maWbBean.value?.apply { fdate = date }
            flightDate.value = date.formatDate()
        }
    }

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

    /**
     * 航班号扫码
     */
    fun flightScanClick() {
        ScanModel.startScan(getTopActivity(), Constant.RequestCode.FLIGHT_NO)
    }

    /**
     * 托盘车号扫码
     */
    fun carIdScanClick() {
        ScanModel.startScan(getTopActivity(), Constant.RequestCode.CAR)
    }

    /**
     * 托盘车号输入完成时调用
     * 当用户输入完整托盘车号后，自动查询平板车信息并填充自重
     */
    fun onCarIdInputComplete() {
        val carId = maWbBean.value?.carId ?: ""

        // 验证托盘车号是否为空
        if (carId.isEmpty()) {
            return
        }

        // 防止重复查询
        if (carId == lastQueriedCarId) {
            return
        }

        // 更新查询标记
        lastQueriedCarId = carId

        // 调用接口查询平板车信息
        queryCarWeight(carId)
    }

    /**
     * 托盘车号输入后查询自重
     */
    fun queryCarWeight(carId: String) {
        if (carId.isEmpty()) {
            carWeight.value = "0"
            return
        }

        launchCollect({
            NetApply.api.getFlatcarInfo(carId)
        }) {
            onSuccess = { result ->
                val data = result.data
                if (data != null) {
                    // 填充托盘车自重
                    carWeight.value = data.carWeight.ifEmpty { "0" }
                } else {
                    showToast("未找到该平板车信息")
                    carWeight.value = "0"
                    // 清空查询标记，允许重新查询
                    lastQueriedCarId = ""
                }
            }
            onFailed = { code, msg ->
                showToast("查询平板车失败: $msg")
                carWeight.value = "0"
                // 清空查询标记，允许重新查询
                lastQueriedCarId = ""
            }
        }
    }

    /**
     * 分托计重按钮点击
     */
    fun sortingWeighingClick() {
        val bean = maWbBean.value ?: return

        // 1. 验证必填字段
        if (bean.no.verifyNullOrEmpty("请输入运单号")) return
        if (bean.fno.verifyNullOrEmpty("请输入航班号")) return
        if (channel.value.verifyNullOrEmpty("请选择通道号")) return

        // 2. 校验运抵件数、运抵重量必填
        if (arrivePc.value.verifyNullOrEmpty("请输入运抵件数")) return
        if (arriveWeight.value.verifyNullOrEmpty("请输入运抵重量")) return

        // 3. 校验件数: 运抵件数 + 实时件数 不能大于 预配件数
        val realTimePcVal = realTimePc.value?.toLongOrNull() ?: 0L
        val arrivePcVal = arrivePc.value?.toLongOrNull() ?: bean.arrivePc ?: 0L
        val preallocatedPc = bean.pc ?: 0L

        if (arrivePcVal + realTimePcVal > preallocatedPc) {
            showToast("运抵件数 + 实时件数不能大于预配件数")
            return
        }

        // 4. 校验重量: 运抵重量 + 实时重量 不能超过预配重量的3%
        val realTimeWeightVal = realTimeWeight.value?.toDoubleOrNull() ?: 0.0
        val arriveWeightCheckVal = arriveWeight.value?.toDoubleOrNull() ?: 0.0
        val preallocatedWeight = bean.weight ?: 0.0

        if (arriveWeightCheckVal + realTimeWeightVal > preallocatedWeight * 1.03) {
            showToast("运抵重量 + 实时重量不能超过预配重量的3%")
            return
        }

        // 5. 收集当前表单数据，更新到 bean
        bean.apply {
            // 更新运抵数据（如果用户已编辑）
            arrivePc = this@GjcWeighingStartViewModel.arrivePc.value?.toLongOrNull() ?: arrivePc
            arriveWeight =
                this@GjcWeighingStartViewModel.arriveWeight.value?.toDoubleOrNull() ?: arriveWeight
            arriveVolume =
                this@GjcWeighingStartViewModel.arriveVolume.value?.toDoubleOrNull() ?: arriveVolume
            // 添加通道号
            passageWay = this@GjcWeighingStartViewModel.channelList.value?.firstOrNull{ it.value == channel.value }?.key ?: ""
            passageWayId = this@GjcWeighingStartViewModel.channel.value

            remark = pageRemark.value

            // 手机版专属：托盘数量/托盘自重（后端暂无对应入参，静默忽略；平板 phoneMode 恒 false，字段为 null 不进请求体）
            if (this@GjcWeighingStartViewModel.phoneMode) {
                palletNumber = this@GjcWeighingStartViewModel.palletNumber.value?.ifEmpty { null }
                carWeight = this@GjcWeighingStartViewModel.carWeight.value?.ifEmpty { null }
            }
        }

        // 3. 构建请求数据（GjcMaWb转RequestBody，包含通道号）
        val params = bean.toRequestBody(removeEmptyOrNull = true)

        // 4. 调用接口
        launchLoadingCollect({
            NetApply.api.splitCheckIn(params)
        }) {
            onSuccess = { result ->
                if (result.verifySuccess()) {
                    showToast("分托计重成功")

                    // 发送刷新事件
                    viewModelScope.launch {
                        FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
                    }

                    // 刷新实时计重数据（第5行的只读字段）
                    loadRealTimeRecord()

                    // 清空表单字段，等待下一次计重
                    arrivePc.value = ""
                    arriveWeight.value = ""
                    arriveVolume.value = ""

                    pageRemark.value = ""

                    maWbBean.value = maWbBean.value?.apply {
                        carId = null
                        remark = null
                        palletNumber = null
                    }
                    carWeight.value = "0"
                    this@GjcWeighingStartViewModel.palletNumber.value = ""
                } else {
                    showToast(result.msg.noNull("分托计重失败"))
                }
            }
        }
    }

    /**
     * 完成计重按钮点击
     */
    fun completeCheckInClick() {
        val bean = maWbBean.value ?: return

        // 验证必填字段
        if (bean.no.verifyNullOrEmpty("请输入运单号")) return
        if (bean.fno.verifyNullOrEmpty("请输入航班号")) return
        if (channel.value.verifyNullOrEmpty("请选择通道号")) return

        // 校验运抵件数、运抵重量必填
        if (arrivePc.value.verifyNullOrEmpty("请输入运抵件数")) return
        if (arriveWeight.value.verifyNullOrEmpty("请输入运抵重量")) return

        // 校验件数: 运抵件数 + 实时件数 不能大于 预配件数
        val realTimePcVal = realTimePc.value?.toLongOrNull() ?: 0L
        val arrivePcVal = arrivePc.value?.toLongOrNull() ?: bean.arrivePc ?: 0L
        val preallocatedPc = bean.pc ?: 0L

        if (arrivePcVal + realTimePcVal > preallocatedPc) {
            showToast("运抵件数 + 实时件数不能大于预配件数")
            return
        }

        // 校验重量: 运抵重量 + 实时重量 不能超过预配重量的3%
        val realTimeWeightVal = realTimeWeight.value?.toDoubleOrNull() ?: 0.0
        val arriveWeightCheckVal = arriveWeight.value?.toDoubleOrNull() ?: 0.0
        val preallocatedWeight = bean.weight ?: 0.0

        if (arriveWeightCheckVal + realTimeWeightVal > preallocatedWeight * 1.03) {
            showToast("运抵重量 + 实时重量不能超过预配重量的3%")
            return
        }

        // 从编辑字段获取数值
        val arriveWeightVal = arriveWeight.value?.toDoubleOrNull() ?: bean.arriveWeight
        val arriveVolumeVal = arriveVolume.value?.toDoubleOrNull() ?: bean.arriveVolume

        // 提交数据到接口（添加通道号参数）
        val params = mapOf(
            "maWbId" to bean.maWbId,
            "no" to bean.no,
            "prefix" to bean.prefix,
            "wbNo" to bean.wbNo,
            "agentCode" to bean.agentCode,
            "agentName" to bean.agentName,
            "fid" to bean.fid,
            "fdate" to bean.fdate,
            "fno" to bean.fno,
            "flight" to bean.flight,
            "range" to bean.range,
            "dep" to bean.dep,
            "dest" to bean.dest,
            "dest1" to bean.dest1,
            "dest2" to bean.dest2,
            "pc" to bean.pc,
            "weight" to bean.weight,
            "volume" to bean.volume,
            "arrivePc" to arrivePcVal,
            "arriveWeight" to arriveWeightVal,
            "arriveVolume" to arriveVolumeVal,
            "spCode" to bean.spCode,
            "goods" to bean.goods,
            "goodsCn" to bean.goodsCn,
            "businessType" to bean.businessType,
            "carId" to bean.carId,
            "remark" to pageRemark.value,
            "checkIn" to "1",  // 收运状态设置为已收运
            "passageWayId" to channel.value,  // 通道号参数
            "passageWay" to (channelList.value?.firstOrNull{ it.value == channel.value }?.key ?: ""),
            // 手机版专属预留参数（平板 phoneMode 恒 false → null → removeEmptyOrNull 移除，请求体不变）
            "palletNumber" to (if (phoneMode) palletNumber.value?.ifEmpty { null } else null),
            "carWeight" to (if (phoneMode) carWeight.value?.ifEmpty { null } else null)
        ).toRequestBody(removeEmptyOrNull = true)

        launchLoadingCollect({
            NetApply.api.completeCheckIn(params)
        }) {
            onSuccess = { result ->
                if (result.verifySuccess()) {
                    showToast("计重完成")
                    // 发送刷新事件
                    viewModelScope.launch {
                        FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
                    }
                    getTopActivity().finish()
                } else {
                    showToast(result.msg.noNull("计重失败"))
                }
            }

            onFailed = { code, msg ->
                showToast(msg)
            }
        }
    }

    /**
     * 处理扫码结果
     */
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (resultCode == Activity.RESULT_OK && data != null) {
            val content = data.getStringExtra(Constant.Result.CODED_CONTENT).noNull()
            when (requestCode) {
                Constant.RequestCode.WAYBILL -> {
                    maWbBean.value = maWbBean.value?.apply { no = content }
                }

                Constant.RequestCode.FLIGHT_NO -> {
                    maWbBean.value = maWbBean.value?.apply { fno = content }
                }

                Constant.RequestCode.CAR -> {
                    maWbBean.value = maWbBean.value?.apply { carId = content }
                    // 查询托盘车自重
                    queryCarWeight(content)
                }
            }
        }
    }

    /**
     * 清理资源
     */
    override fun onCleared() {
        super.onCleared()
        // diBangModel.cancelLooperGet()  // 已改为手动输入，不再使用地磅自动读取
    }
}
