package com.lukouguoji.gjc.viewModel

import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
import android.view.View
import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.activity.GjcUnLoadListActivity
import com.lukouguoji.gjc.dialog.BoxBatchDialogModel
import com.lukouguoji.module_base.bean.GcjBoxAddReqBean
import com.lukouguoji.gjc.dialog.GjcBoxAddSelectDialogModel
import com.lukouguoji.gjc.dialog.GjcUldSelectDialogModel
import com.lukouguoji.module_base.base.BasePageViewModel
import com.lukouguoji.module_base.bean.FlatcarBean
import com.lukouguoji.module_base.bean.GjcBoxAddListBean
import com.lukouguoji.module_base.bean.GjcWaybillBean
import com.lukouguoji.module_base.bean.JianBean
import com.lukouguoji.module_base.bean.ULDBean
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.interfaces.IOnItemClickListener
import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.finish
import com.lukouguoji.module_base.ktx.getActivity
import com.lukouguoji.module_base.ktx.handle
import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.limit
import com.lukouguoji.module_base.ktx.loge
import com.lukouguoji.module_base.ktx.noNull
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toJson
import com.lukouguoji.module_base.ktx.toMap
import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.model.ScanModel
import com.lukouguoji.module_base.util.Common
import dev.DevUtils
import dev.utils.common.NumberUtils
import java.util.LinkedList
import java.util.Queue

class GjcBoxAssembleAddViewModel : BasePageViewModel(), IOnItemClickListener {

    val isAdd = MutableLiveData(true)

    // 平板车或ULD
    val plateOrUld = MutableLiveData<String>()

    // 运单号或件号
    val waybillOrPiece = MutableLiveData<String>()

    val checkPBC = MutableLiveData(true)
    val checkULD = MutableLiveData(false)

    // 平板车信息
    val flatcarBean = MutableLiveData<FlatcarBean>()

    // ULD信息
    val uldBean = MutableLiveData<ULDBean>()

    // 插入数据ID
    var insertId = ""

    // 总件数
    val totalCount = MutableLiveData(0)

    // 总重量
    val totalWeight = MutableLiveData(0.0)

    ///////////////////////////////////////////////////////////////////////////
    // 方法区
    ///////////////////////////////////////////////////////////////////////////

    /**
     * 获取详细信息
     */
    override fun getData() {
        if (isAdd.value != true && insertId.isNotEmpty()) {
            showLoading()
            launchCollect({
                NetApply.api
                    .getGjcBoxAssembleDetail(insertId)
            }) {
                onSuccess = {
                    if (it.verifySuccess()) {
                        val details = it.data!!
                        // 设置ULD和平板车信息
                        flatcarBean.value = details.flatCar
                        uldBean.value = details.eqmUld
                        // 刷新选中列表
                        val list = details.warehousePclistDTOList?.map { it.toGjcBoxAddListBean() }
                            ?: emptyList()
                        pageModel.handleDataList(list)
                        computeTotal(list)
                    } else {
                        showToast(it.msg.noNull("获取数据失败"))
                    }
                }

                onComplete = {
                    dismissLoading()
                }
            }
        }
    }

    /**
     * 筛选点击
     */
    fun onFilterClick(view: View) {
        if (verifyCarULD()) {
            GjcUnLoadListActivity.start(view.context)
        }
    }

    /**
     * 校验当前平板车和ULD是否都扫描成功
     */
    private fun verifyCarULD(): Boolean {
        if ((flatcarBean.value == null || flatcarBean.value?.carId.isNullOrEmpty()) && uldBean.value == null) {
            showToast("请扫描平板车或ULD信息")
            return false
        }
        return true
    }

    /**
     * 校验当前是否已经空数据
     */
    private fun verifyIsEmpty(): Boolean {
        return (pageModel.rv?.commonAdapter()?.itemCount ?: 0) <= 0
    }

    /**
     * 运单选中返回
     */
    fun onWaybillListSelected(context: Context, list: List<GjcWaybillBean>) {
        val adapter = pageModel.rv!!.commonAdapter()!!
        val items = (adapter.items as List<GjcBoxAddListBean>).map { it.waybillBean }

        // 筛选出来已有的运单信息,并弹窗做选择
        val map = linkedMapOf<String, ArrayList<GjcWaybillBean>>()
        // 添加选中的运单
        list.forEach {
            it.checked.set(false)
            val waybillBeans = map[it.getWaybillCode()] ?: arrayListOf()
            if (waybillBeans.find { b -> b.whid == it.whid } == null) {
                waybillBeans.add(it)
            }
            map[it.getWaybillCode()] = waybillBeans
        }
        // 添加列表中已有的运单
        items.forEach {
            it.checked.set(false)
            val waybillBeans = map[it.getWaybillCode()] ?: arrayListOf()
            if (waybillBeans.find { b -> b.whid == it.whid } == null) {
                waybillBeans.add(it)
            }
            map[it.getWaybillCode()] = waybillBeans
        }

        // 单条数据加入到列表
        map.values.filter { it.size == 1 }
            .forEach { l ->
                val bean = l.first()
                if (items.find { b -> b.getWaybillCode() == bean.getWaybillCode() } == null) {
                    loge("添加到列表 ${bean.getWaybillCode()}")
                    adapter.addItem(GjcBoxAddListBean(bean))
                } else {
                    loge("列表中已经有了 ${bean.getWaybillCode()}")
                }
            }

        // 多条数据转换为队列
        val queue = LinkedList<List<GjcWaybillBean>>()
        loge("数量列表 : ${map.values.map { it.size }.toJson()}")
        map.values.filter { it.size > 1 }
            .forEach { l ->
                queue.offer(l)
            }
        loge("队列数量 : ${queue.size}")
        showSelectDialog(context, queue)
        computeTotal()
    }

    /**
     * 展示选择弹窗
     * 仅用于选择返回
     */
    private fun showSelectDialog(context: Context, queue: Queue<List<GjcWaybillBean>>) {
        val adapter = pageModel.rv!!.commonAdapter()!!
        val list = queue.poll() ?: return
        loge("展示选择弹窗 : ${list.size}")
        GjcBoxAddSelectDialogModel(list) { bean ->
            val items = adapter.items as List<GjcBoxAddListBean>
            items.find { it.waybillBean.getWaybillCode() == bean.getWaybillCode() }
                .handle({
                    // 如果查询到运单号一致的数据,则更新数据
                    if (it.waybillBean.whid != bean.whid) {
                        it.waybillBean = bean
                        adapter.notifyItemChanged(items.indexOf(it))
                    }
                }) {
                    val listBean = GjcBoxAddListBean(bean)
                    adapter.addItem(listBean)
                }
            computeTotal()
            showSelectDialog(context, queue)
        }.show(context)
    }

    /**
     * 确认 点击
     */
    fun onConfirmClick(view: View) {
        val adapter = pageModel.rv!!.commonAdapter()!!
        val items = adapter.items as List<GjcBoxAddListBean>
        if (items.isEmpty()) {
            showToast("请扫描或选择运单")
            return
        }
        if (!verifyCarULD()) {
            return
        }
        Common.secondConfirmDialog(
            DevUtils.getTopActivity(),
            "是否确认组装?"
        ) { dialog ->
            dialog.dismiss()
            doConfirm(view, items)
        }
    }

    private fun doConfirm(view: View, items: List<GjcBoxAddListBean>) {
        val bean = GcjBoxAddReqBean(locId = insertId)
        bean.setGjcBoxAddList(items, uldBean.value?.uldWeight.noNull("0.0"))
        showLoading()
        launchCollect({
            val map = bean.toMap()
            map["isAdd"] = isAdd.value!!
            NetApply.api
                .gjcBoxAddConfirm(map.toRequestBody())
        }) {
            onSuccess = {
                if (it.verifySuccess()) {
                    showToast("操作成功")
                    FlowBus.with<Any>(ConstantEvent.GJC_BOX_ADD_SUCCESS)
                        .tryEmit(true)
                    view.context.finish()
                } else {
                    showToast(it.msg.noNull("操作失败"))
                }
            }
            onComplete = {
                dismissLoading()
            }
        }
    }

    /**
     * 平板或Uld 扫描 点击
     */
    fun onPlateOrUldClick(view: View) {
        if (!verifyIsEmpty()) {
            showToast("请清理所有运单后再进行扫描")
            return
        }
        ScanModel.startScan(
            view.context.getActivity(),
            Constant.RequestCode.gjc_fubang_car_id
        )
    }

    /**
     * 运单或件号 扫描 点击
     */
    fun onWaybillOrPieceClick(view: View) {
        if (!verifyCarULD()) {
            return
        }
        ScanModel.startScan(
            view.context.getActivity(),
            Constant.RequestCode.WAYBILL
        )
    }

    /**
     * 条目点击事件
     */
    override fun onItemClick(position: Int, type: Int) {
        val adapter = pageModel.rv!!.commonAdapter()!!
        val items = adapter.items as List<GjcBoxAddListBean>
        when (type) {
            R.id.tv_batch -> {
                val bean = items[position].waybillBean
                BoxBatchDialogModel(bean) {
                    addWaybillInfo(bean.getWaybillCode(), whid = bean.whid.noNull())
                }.show(DevUtils.getTopActivity())
            }

            R.id.tv_delete_order -> {
                Common.secondConfirmDialog(
                    DevUtils.getTopActivity(),
                    "是否确认删除该运单信息?"
                ) { dialog ->
                    adapter.removeItem(position)
                    computeTotal()
                    dialog.dismiss()
                }
            }
            // 删件
            R.id.tv_delete_matter -> {
                val bean = items[position]
                if (bean.jianList.filter { it.checked.get() }.isEmpty()) {
                    showToast("请先选择要删除的件号")
                    return
                }
                Common.secondConfirmDialog(
                    DevUtils.getTopActivity(),
                    "是否确认删除选中件号?"
                ) { dialog ->
                    bean.jianList.removeIf { it.checked.get() }
                    adapter.notifyItemChanged(position)
                    computeTotal()
                    dialog.dismiss()
                }
            }

            R.id.iv_show -> {
                if (items[position].show.get()) {
                    items[position].show.set(false)
                } else {
                    items.forEachIndexed { index, bean ->
                        if (bean.show.get() != (index == position)) {
                            bean.show.set(index == position)
                        }
                    }
                }
            }

            else -> {}
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (resultCode == RESULT_OK && data != null) {
            when (requestCode) {
                Constant.RequestCode.gjc_fubang_car_id -> {
                    val id = data.getStringExtra(Constant.Result.CODED_CONTENT).noNull()
                    plateOrUld.value = id
                    onPbcOrUldChange()
                }

                Constant.RequestCode.WAYBILL -> {
                    val id = data.getStringExtra(Constant.Result.CODED_CONTENT).noNull()
                    waybillOrPiece.value = id
                    onWaybillOrPieceChange()
                }

                else -> {}
            }
        }
    }

    /**
     * 平板车或ULD 改变
     */
    fun onPbcOrUldChange(focused: Boolean = false) {
        if (focused) {
            return
        }
        val id = plateOrUld.value ?: return
        if (!verifyIsEmpty()) {
            return
        }
        if (checkPBC.value!!) {
            getFlatcarInfo(id)
        } else {
            getUldInfo(id)
        }
    }

    /**
     * 运单号或件号 改变
     */
    fun onWaybillOrPieceChange(focused: Boolean = false) {
        if (focused) {
            return
        }
        val code = waybillOrPiece.value ?: return
        if (NumberUtils.isNumber(code)) {
            // 运单号
            if (code.length == 11) {
                addWaybillInfo(code)
            }
            // 运单号 + 件号
            else if (code.length == 16) {
                addWaybillInfo(code.substring(0, 11), code.substring(11))
            }
        }
        if (code.length > 16) {
            loge("件号 : $code")
            addWaybillInfo(code, code)
        }
    }

    /**
     * 获取运单信息
     * @param waybillCode 运单号
     * @param jianCode 件号
     * @param whid 仓库ID, 不为空,则视为更新
     */
    private fun addWaybillInfo(waybillCode: String, jianCode: String = "", whid: String = "") {
        // 非更新
        if (whid.isEmpty()) {
            val find =
                (pageModel.rv!!.commonAdapter()!!.items as List<GjcBoxAddListBean>).find { it.waybillBean.getWaybillCode() == waybillCode }
            if (find != null) {
                if (jianCode.isEmpty()) {
                    showToast("该运单已在列表中")
                } else {
                    addJian(jianCode, find)
                }
                return
            }
        }
        launchCollect({
            NetApply.api.getGjcWaybillInfo(waybillCode)
        }) {
            onSuccess = {
                if (it.verifySuccess() && it.data != null && !it.data!!.whList.isNullOrEmpty()) {
                    val filter = it.data!!.whList!!.filter { bean -> bean.location.isNullOrEmpty() }
                    if (filter.isEmpty()) {
                        showToast("该运单已装配到设备上")
                    } else {
                        // 重新获取列表
                        val adapter = pageModel.rv!!.commonAdapter()!!
                        val list = adapter.items as List<GjcBoxAddListBean>
                        if (whid.isNotEmpty()) {
                            // 更新数据
                            filter.find { b -> b.whid == whid }?.let { b ->
                                list.find { l -> l.waybillBean.whid == whid }?.let { f ->
                                    f.waybillBean = b
                                    adapter.notifyItemChanged(list.indexOf(f))
                                    addJian(jianCode, f)
                                }
                            }
                        } else if (filter.size > 1) {
                            GjcBoxAddSelectDialogModel(filter) {
                                val listBean = GjcBoxAddListBean(it)
                                adapter.addItem(listBean)
                                loge("新增数据 ${it.whid} , 添加件 : $jianCode")
                                addJian(jianCode, listBean)
                            }.show(DevUtils.getTopActivity())
                        } else {
                            val first = filter.first()
                            val listBean = GjcBoxAddListBean(first)
                            adapter.addItem(listBean)
                            loge("新增数据 ${first.whid} , 添加件 : $jianCode")
                            addJian(jianCode, listBean)
                        }
                    }
                    computeTotal()
                } else {
                    showToast(it.msg.noNull("获取运单信息失败"))
                }
            }
        }
    }

    /**
     * 添加件号
     */
    private fun addJian(code: String, bean: GjcBoxAddListBean) {
        if (code.isEmpty()) {
            computeTotal()
            return
        }
        if (bean.jianList.find { b -> b.code == JianBean.getCode(code) } == null) {
            bean.jianList.add(JianBean.create(code))
        }
        computeTotal()
    }

    /**
     * 获取平板车数据
     */
    private fun getFlatcarInfo(id: String) {
        launchCollect({
            NetApply.api
                .getFlatcarInfo(id)
        }) {
            onSuccess = {
                if (it.verifySuccess() && it.data != null) {
                    flatcarBean.value = it.data
                    insertCarOrULD()
                } else {
                    showToast(it.msg.noNull("该平板车不存在"))
                }
            }
        }
    }

    /**
     * 获取ULD数据
     */
    private fun getUldInfo(id: String) {
        launchCollect({
            NetApply.api
                .getUldInfo(id)
        }) {
            onSuccess = {
                if (it.verifySuccess() && it.data != null && it.data!!.isNotEmpty()) {
                    val data = it.data!!
                    if (data.size == 1) {
                        uldBean.value = data.first()
                        insertCarOrULD()
                    } else {
                        GjcUldSelectDialogModel(data) { b ->
                            uldBean.value = b
                            insertCarOrULD()
                        }.show()
                    }
                } else {
                    showToast(it.msg.noNull("获取ULD信息失败"))
                }
            }
        }
    }

    /**
     * 插入数据
     */
    private fun insertCarOrULD() {
        val map = hashMapOf(
            "carid" to flatcarBean.value?.carId,
            "carweight" to flatcarBean.value?.carWeight,
            "locId" to insertId,
            "gjcLoading" to listOf(
                mapOf(
                    "carid" to flatcarBean.value?.carId,
                    "locId" to insertId,
                    "maxweight" to flatcarBean.value?.maxWeight,
                    "maxvolume" to uldBean.value?.maxVolume,
                    "uld" to uldBean.value?.uld,
                    "uldflag" to uldBean.value?.uldFlag,
                    "uldweight" to uldBean.value?.uldWeight,
                )
            )
        )
        launchCollect({
            NetApply.api
                .gjcBoxInsert(map.toRequestBody())
        }) {
            onSuccess = {
                if (!it.verifySuccess()) {
                    showToast(it.msg.noNull("插入数据失败"))
                    if (checkPBC.value!!) {
                        flatcarBean.value = FlatcarBean()
                    } else {
                        uldBean.value = ULDBean()
                    }
                } else {
                    it.data?.locId?.let { id -> insertId = id }
                }
            }
        }
    }

    /**
     * 计算总数
     */
    private fun computeTotal(list: List<GjcBoxAddListBean>? = null) {
        val adapter = pageModel.rv!!.commonAdapter()!!
        val items = list ?: adapter.items as List<GjcBoxAddListBean>
        var count = 0
        var weight = 0.0
        items.forEach { bean ->
            count += if (bean.jianList.isEmpty()) bean.waybillBean.pc.noNull("0")
                .toInt() else bean.jianList.size
            weight += (bean.waybillBean.weight.noNull().toDouble())
        }
        totalCount.value = count
        totalWeight.value = weight.limit(2).toDouble()
    }
}