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.GjcUldUseBean
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.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.BluetoothDialogModel
import com.lukouguoji.module_base.model.ScanModel
import com.lukouguoji.module_base.util.Common
import com.lukouguoji.module_base.util.PrinterUtils
import dev.utils.app.info.KeyValue
import kotlinx.coroutines.launch
import java.util.Calendar
import java.util.Date

/**
 * 国际出港板箱过磅添加 ViewModel
 */
class GjcBoxWeighingAddViewModel : BaseViewModel() {

    // 数据Bean
    val dataBean = MutableLiveData(GjcUldUseBean())

    // 保存 queryUsingUldByUld 返回的数据（用于复磅场景）
    private var usingUldData: GjcUldUseBean? = null

    // 地磅集成 - 暂时注释
    // val diBangModel = DiBangWeightModel()
    val channel = MutableLiveData("")  // 通道号（用于控制地磅key）

    // 地磅称重输入（独立字段，单向同步到总重）
    val diBangWeight = MutableLiveData("0")

    // 计算字段显示
    val totalWeight = MutableLiveData("0")      // 总重（红色）
    val netWeight = MutableLiveData("0")        // 装机重（蓝色）
    val cargoWeight = MutableLiveData("0")      // 货重（绿色）

    // 需要自动查询的独立字段（用于监听输入变化）
    val carId = MutableLiveData("")             // 架子车号
    val uldNo = MutableLiveData("")             // ULD编号
    val flightNo = MutableLiveData("")          // 航班号
    val flightDate = MutableLiveData("")        // 航班日期

    // 下拉选择数据源
    val passagewayList = MutableLiveData<List<KeyValue>>()  // 通道号列表
    val plCloseList = MutableLiveData<List<KeyValue>>()     // 探板收口列表

    // 打印挂签
    val printTag = MutableLiveData(false)

    // 标记位，避免重复查询
    private var lastQueriedFlight = ""
    private var lastQueriedCarId = ""
    private var lastQueriedUld = ""

    /**
     * 初始化
     */
    fun initOnCreated(activity: Activity, intent: Intent? = null) {
        // 监听地磅重量变化 - 暂时注释
        // diBangModel.weight.observe(activity as LifecycleOwner) { weight ->
        //     val w = weight?.toDoubleOrNull() ?: 0.0
        //     totalWeight.value = w.toString()
        //     dataBean.value?.totalWeight = w
        //     // 实时计算装机重和货重
        //     calculateWeights()
        // }

        // 监听通道号变化，设置地磅的key - 暂时注释
        // channel.observe(activity as LifecycleOwner) {
        //     diBangModel.key = it ?: ""
        // }

        // 监听地磅称重输入，单向同步到总重
        diBangWeight.observe(activity as LifecycleOwner) { weight ->
            val w = weight?.toDoubleOrNull() ?: 0.0
            totalWeight.value = w.toString()
            dataBean.value = dataBean.value?.apply { totalWeight = w }
            // 实时计算装机重和货重
            calculateWeights()
        }

        // 监听总重变化，实时计算装机重和货重
        totalWeight.observe(activity as LifecycleOwner) {
            val w = it?.toDoubleOrNull() ?: 0.0
            dataBean.value = dataBean.value?.apply { totalWeight = w }
            calculateWeights()
        }

        // 初始化航班日期为今天
        val today = Date().formatDate()
        flightDate.value = today
        dataBean.value?.fdate = today

        // 编辑模式：从 Intent 中解析列表项 Bean 并回填
        val editBean = intent?.getSerializableExtra(Constant.Key.BEAN) as? GjcUldUseBean
        if (editBean != null) {
            prefillFromBean(editBean)
            loadPassagewayList(editBean.passagewayId)
            loadPlCloseList(editBean.plClose)
        } else {
            loadPassagewayList(null)
            loadPlCloseList(null)
        }
    }

    /**
     * 编辑模式：用列表项数据回填表单
     */
    private fun prefillFromBean(bean: GjcUldUseBean) {
        // 整体绑定（板型/高度/IMP/探板尺寸/目的港/备注/架子车自重/ULD自重等通过 dataBean.* 自动回填）
        dataBean.value = bean

        // 独立字段
        carId.value = bean.carId
        uldNo.value = bean.uld
        flightNo.value = bean.fno
        flightDate.value = bean.fdate

        // 计算字段
        totalWeight.value = bean.totalWeight.toString()
        netWeight.value = bean.netWeight.toString()
        cargoWeight.value = bean.cargoWeight.toString()
        diBangWeight.value = bean.totalWeight.toString()

        // 通道号 Spinner 绑定到 channel（KeyValue.value 即 passagewayId）
        channel.value = bean.passagewayId

        // 抑制重复自动查询（避免回调把已填数据再次刷掉）
        lastQueriedCarId = bean.carId
        lastQueriedUld = bean.uld
        lastQueriedFlight = "${bean.fdate}-${bean.fno}"

        // confirmClick 需要 usingUldData，列表项本身就是当前正在使用的记录
        usingUldData = bean
    }

    /**
     * 架子车号输入完成时调用
     */
    fun onCarIdInputComplete() {
        val id = carId.value
        if (!id.isNullOrEmpty() && id != lastQueriedCarId) {
            lastQueriedCarId = id
            queryFlatcarInfo(id)
        }
    }

    /**
     * ULD编号输入完成时调用
     */
    fun onUldNoInputComplete() {
        val uld = uldNo.value
        if (!uld.isNullOrEmpty() && uld != lastQueriedUld) {
            lastQueriedUld = uld
            queryUldInfo(uld)
        }
    }

    /**
     * 航班号输入完成时调用
     */
    fun onFlightNoInputComplete() {
        queryFlightIfReady()
    }

    /**
     * 航班日期输入完成时调用
     */
    fun onFlightDateInputComplete() {
        // 清除查询标记，以便重新查询
        lastQueriedFlight = ""
        queryFlightIfReady()
    }

    /**
     * 检查航班日期和航班号，如果都有值则查询航班信息
     */
    private fun queryFlightIfReady() {
        val fdate = flightDate.value
        val fno = flightNo.value
        if (!fdate.isNullOrEmpty() && !fno.isNullOrEmpty()) {
            val key = "$fdate-$fno"
            if (key != lastQueriedFlight) {
                lastQueriedFlight = key
                queryFlightInfo(fdate, fno)
            }
        }
    }

    /**
     * 查询航班信息，自动填充目的港
     */
    private fun queryFlightInfo(fdate: String, fno: String) {
        val params = mapOf(
            "fdate" to fdate,
            "fno" to fno,
            "countryType" to "1"  // 国际航班
        ).toRequestBody()

        launchCollect({ NetApply.api.queryFlightByDateAndNo(params) }) {
            onSuccess = { result ->
                val flight = result.data
                if (flight != null) {
                    dataBean.value = dataBean.value?.apply {
                        fdest = flight.fdest
                    }
                }
            }
        }
    }

    /**
     * 加载通道号列表
     * @param checkedValue 编辑模式下需要选中的 passagewayId；为空则按返回顺序展示
     */
    private fun loadPassagewayList(checkedValue: String?) {
        launchCollect({
            NetApply.api.getDictList("GJPASSAGEWAY")
        }) {
            onSuccess = {
                val list = (it.data ?: emptyList()).map { b -> b.toKeyValue() }
                passagewayList.value = reorderChecked(list, checkedValue)
            }
        }
    }

    /**
     * 加载探板收口列表
     * @param checkedValue 编辑模式下需要选中的 plClose 值；为空则按返回顺序展示
     */
    private fun loadPlCloseList(checkedValue: String?) {
        launchCollect({
            NetApply.api.getDictList("PICLOSE")
        }) {
            onSuccess = {
                // 将 DictIdValueBean 转换为 KeyValue
                // 显示和提交都使用 value 字段
                val list = (it.data ?: emptyList()).map { b ->
                    KeyValue(b.value, b.value)
                }
                plCloseList.value = reorderChecked(list, checkedValue)
            }
        }
    }

    /**
     * 若 checkedValue 命中列表中某项，则把该项移到首位（PadDataLayoutNew SPINNER 默认显示首项）
     */
    private fun reorderChecked(list: List<KeyValue>, checkedValue: String?): List<KeyValue> {
        if (checkedValue.isNullOrEmpty()) return list
        val matched = list.firstOrNull { it.value == checkedValue } ?: return list
        return listOf(matched) + list.filter { it !== matched }
    }

    /**
     * 计算重量字段
     * 装机重 = 总重 - 架子车自重
     * 货重 = 装机重 - ULD自重
     */
    private fun calculateWeights() {
        val total = totalWeight.value?.toDoubleOrNull() ?: 0.0
        val carW = dataBean.value?.carWeight ?: 0.0
        val uldW = dataBean.value?.uldWeight ?: 0.0

        val net = total - carW
        val cargo = net - uldW

        netWeight.value = if (net > 0) net.toString() else "0"
        cargoWeight.value = if (cargo > 0) cargo.toString() else "0"

        dataBean.value?.netWeight = if (net > 0) net else 0.0
        dataBean.value?.cargoWeight = if (cargo > 0) cargo else 0.0
    }

    /**
     * 航班日期点击
     */
    fun flightDateClick(view: View) {
        Common.onYearMonthDay(view.context.getActivity(), flightDate.value) { year, month, day ->
            val calendar = Calendar.getInstance()
            calendar.set(year, month - 1, day)
            val date = calendar.time.formatDate()
            // 清除查询标记，以便重新查询
            lastQueriedFlight = ""
            flightDate.value = date
            dataBean.value = dataBean.value?.apply { fdate = date }
            // 日期选择完成后立即触发查询
            onFlightDateInputComplete()
        }
    }

    /**
     * ULD编号扫码
     */
    fun uldScanClick() {
        ScanModel.startScan(getTopActivity(), Constant.RequestCode.ULD)
    }

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

    /**
     * 重置按钮点击
     */
    fun resetClick() {
        val today = Date().formatDate()

        dataBean.value = GjcUldUseBean().apply {
            fdate = today
        }
        diBangWeight.value = "0"
        totalWeight.value = "0"
        netWeight.value = "0"
        cargoWeight.value = "0"
        channel.value = ""
        printTag.value = false

        // 重置独立字段
        carId.value = ""
        uldNo.value = ""
        flightNo.value = ""
        flightDate.value = today

        // 重置查询标记
        lastQueriedFlight = ""
        lastQueriedCarId = ""
        lastQueriedUld = ""

        // 重置 ULD 使用记录
        usingUldData = null
    }

    /**
     * 确定按钮点击
     */
    fun confirmClick() {
        val bean = dataBean.value ?: return

        // 同步独立字段到 dataBean
        bean.carId = carId.value ?: ""
        bean.uld = uldNo.value ?: ""
        bean.fno = flightNo.value ?: ""
        bean.fdate = flightDate.value ?: ""
        bean.passageway = passagewayList.value?.firstOrNull{ it.value == channel.value }?.key ?: ""
        bean.passagewayId = channel.value ?: ""

        // 验证必填字段（架子车号改为非必填）
        if (bean.uld.verifyNullOrEmpty("请输入ULD编号")) return
        if (bean.passageway.verifyNullOrEmpty("请选择通道号")) return

        // 验证是否已组装（复磅场景必须有 useId）
        if (usingUldData == null || usingUldData?.useId == 0L) {
            showToast("未组装，不可复磅")
            return
        }

        // 构建基础提交参数
        val baseParams = mutableMapOf(
            "carId" to bean.carId,
            "passageway" to bean.passageway,
            "passagewayId" to bean.passagewayId,
            "uld" to bean.uld,
            "dgrCode" to bean.dgrCode,
            "boardType" to bean.boardType,
            "height" to bean.height,
            "plClose" to bean.plClose,
            "plCloseSize" to bean.plCloseSize,
            "carWeight" to bean.carWeight,
            "uldWeight" to bean.uldWeight,
            "fdate" to bean.fdate,
            "fno" to bean.fno,
            "fdest" to bean.fdest,
            "remark" to bean.remark,
            "totalWeight" to bean.totalWeight,
            "netWeight" to bean.netWeight,
            "cargoWeight" to bean.cargoWeight,
            "printTag" to printTag.value
        )

        // 如果有 usingUldData（复磅场景），将其所有字段添加到提交参数
        usingUldData?.let { usingData ->
            baseParams["useId"] = usingData.useId
            baseParams["cargoType"] = usingData.cargoType
            baseParams["consumeWeight"] = usingData.consumeWeight
            baseParams["volume"] = usingData.volume
            baseParams["maxVolume"] = usingData.maxVolume
            baseParams["maxWeight"] = usingData.maxWeight
            baseParams["fdep"] = usingData.fdep
            baseParams["fClose"] = usingData.fClose
            baseParams["wtId"] = usingData.wtId
            baseParams["wtUsername"] = usingData.wtUsername
            baseParams["wtDate"] = usingData.wtDate
            baseParams["ldId"] = usingData.ldId
            baseParams["ldUserName"] = usingData.ldUserName
            baseParams["ldDate"] = usingData.ldDate
            baseParams["hoId"] = usingData.hoId
            baseParams["hoUserName"] = usingData.hoUserName
            baseParams["hoDate"] = usingData.hoDate
            baseParams["uldCarrier"] = usingData.uldCarrier
            baseParams["uldFlag"] = usingData.uldFlag
            baseParams["status"] = usingData.status
            baseParams["passagewayName"] = usingData.passagewayName
            baseParams["location"] = usingData.location
            baseParams["checkFlag"] = usingData.checkFlag
            baseParams["emptyUld"] = usingData.emptyUld
        }

        // 转换为 RequestBody
        val params = baseParams.toRequestBody(removeEmptyOrNull = true)

        launchLoadingCollect({
            NetApply.api.submitGjcBoxWeighing(params)
        }) {
            onSuccess = { result ->
                if (result.verifySuccess()) {
                    showToast("完成复磅")

                    // 如果勾选了打印挂签，则执行打印
                    if (printTag.value == true) {
                        executePrint()
                    }

                    // 发送刷新事件
                    viewModelScope.launch {
                        FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
                    }
//                    getTopActivity().finish()
                } else {
                    showToast(result.msg.noNull("添加失败"))
                }
            }
        }
    }

    /**
     * 执行打印
     */
    private fun executePrint() {
        val bean = dataBean.value ?: return

        // 使用 BluetoothDialogModel 选择打印机并打印
        BluetoothDialogModel()
            .showCallBack {
                PrinterUtils.printGjcBoxWeighing(bean)
            }
    }

    /**
     * 处理扫码结果
     */
    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.ULD -> {
                    // 更新独立字段
                    uldNo.value = content
                    dataBean.value = dataBean.value?.apply { uld = content }
                    // 扫码完成后立即查询
                    onUldNoInputComplete()
                }
                Constant.RequestCode.CAR -> {
                    // 更新独立字段
                    carId.value = content
                    dataBean.value = dataBean.value?.apply { carId = content }
                    // 扫码完成后立即查询
                    onCarIdInputComplete()
                }
            }
        }
    }

    /**
     * 查询ULD信息
     */
    private fun queryUldInfo(uldNo: String) {
        launchCollect({ NetApply.api.queryUldByCode(uldNo) }) {
            onSuccess = { result ->
                val uldBean = result.data
                if (uldBean != null) {
                    val weight = uldBean.uldWeight.toDoubleOrNull() ?: 0.0
                    dataBean.value = dataBean.value?.apply {
                        uldWeight = weight
                        maxWeight = uldBean.maxWeight.toDoubleOrNull() ?: 0.0
                        maxVolume = uldBean.maxVolume.toDoubleOrNull() ?: 0.0
                    }
                    // 触发重量计算
                    calculateWeights()
                }
            }
        }

        // 查询正在使用的 ULD 记录（复磅场景）
        launchCollect({ NetApply.api.queryUsingUldByUld(uldNo) }) {
            onSuccess = { result ->
                val usingData = result.data
                if (usingData != null && usingData.useId > 0) {
                    // 保存返回的数据，用于提交时传递
                    usingUldData = usingData
                } else {
                    // 没有 useId，说明未组装，不可复磅
                    usingUldData = null
                    showToast("未组装，不可复磅")
                }
            }
            onFailed = { _, _ ->
                // 接口报错时也认为未组装
                usingUldData = null
                showToast("未组装，不可复磅")
            }
        }
    }

    /**
     * 查询架子车信息
     */
    private fun queryFlatcarInfo(carId: String) {
        launchCollect({ NetApply.api.getFlatcarInfo(carId) }) {
            onSuccess = { result ->
                val flatcarBean = result.data
                if (flatcarBean != null) {
                    val weight = flatcarBean.carWeight.toDoubleOrNull() ?: 0.0
                    dataBean.value = dataBean.value?.apply {
                        carWeight = weight
                    }
                    // 触发重量计算
                    calculateWeights()
                }
            }
        }
    }

    /**
     * 清理资源
     */
    override fun onCleared() {
        super.onCleared()
        // diBangModel.cancelLooperGet()  // 暂时注释
    }
}
