package com.sybotan.android.demo.viewmodel

import android.app.Activity.RESULT_OK
import android.app.Application
import android.graphics.PointF
import android.text.TextUtils
import androidx.lifecycle.viewModelScope
import cn.sagacloud.android.cadengine.Lasso
import cn.sagacloud.android.cadengine.items.PipeLineItem
import cn.sagacloud.android.cadengine.items.PointItem
import cn.sagacloud.android.cadengine.items.SpaceItem
import cn.sagacloud.android.cadengine.items.TunableSpaceItem
import cn.sagacloud.android.cadengine.types.*
import com.framework.mvvm.model.db.entity.*
import com.framework.mvvm.model.repository.AdmRepository
import com.sybotan.android.demo.bean.result.ProblemsModel
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.sybotan.android.demo.activities.BaseActivity
import com.sybotan.android.demo.bean.request.*
import com.sybotan.android.demo.bean.result.*
import com.sybotan.android.demo.bean.result.Position
import com.sybotan.android.demo.bean.result.Z
import com.sybotan.android.demo.retrofit.BaseObserver
import com.sybotan.android.demo.retrofit.BaseViewModelInterface
import com.sybotan.android.demo.retrofit.RetrofitFactory
import com.sybotan.android.demo.tools.CommonUtils
import com.sybotan.android.demo.tools.ToastUtils
import com.sybotan.base.utils.SJsonUtil
import kotlinx.coroutines.launch
import org.json.JSONObject
import org.kodein.di.DI
import org.kodein.di.DIAware
import org.kodein.di.android.x.closestDI
import org.kodein.di.instance
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import com.sybotan.android.demo.bean.*


/**
 * Created by lihao.
 * Date: 2021/6/9
 */
class GraphyVM(
    app: Application,
    b: BaseViewModelInterface?, activity: BaseActivity?, //建筑id
    private val buildingId: String, //楼层id
    private val floorId: String,
    private val projectId: String
) : BaseViewModel(app, b, activity), DIAware {
    private val gson = Gson()

    override val di: DI by closestDI()
    val repo: AdmRepository by instance()

    /**
     * 查询空间和任务
     */
    fun getSpaceJob(from: String, spaceList: ArrayList<SpaceItem>) {
        viewModelScope.launch {
            var spaceList: ArrayList<SpaceEntity> = ArrayList()
            if ("space".equals(from)) {
                val spaceByArchState1 = repo.getSpaceByArchStateFloorId(floorId, "1")
                val spaceByArchState2 = repo.getSpaceByArchStateFloorId(floorId, "2")
                spaceList.addAll(spaceByArchState1)
                spaceList.addAll(spaceByArchState2)
            } else {
                val spaceByEquipState1 = repo.getSpaceByEquipStateFloorId(floorId, "1")
                val spaceByEquipState2 = repo.getSpaceByEquipStateFloorId(floorId, "2")
                spaceList.addAll(spaceByEquipState1)
                spaceList.addAll(spaceByEquipState2)
            }
            var spaceJobList = ArrayList<SpaceJobModel>()
            for (spaceEntity in spaceList) {
                var spaceJobModel = SpaceJobModel()
                val objectEntity = repo.getObject(spaceEntity.spaceId)
                spaceJobModel.buildingId = buildingId
                spaceJobModel.id = spaceEntity.spaceId
                spaceJobModel.localName = objectEntity!!.localName
                spaceJobModel.name = objectEntity.name
                spaceJobModel.projectId = projectId
                val strInfo = gson.fromJson(objectEntity.strInfos, StrInfos::class.java)
                spaceJobModel.outline = strInfo.outline
                spaceJobModel.objectEntity = objectEntity
                if (from.equals("space")) {
                    val problems = repo.getProblemByAvalible(floorId)
                    var hasProblem = false
                    var list: ArrayList<PointF> = ArrayList()
                    for (line in spaceJobModel.outline[0]!!) {
                        if (line.size < 1) {
                            list.add(PointF(line[0].x, line[0].y))
                            continue
                        }
                        for (p in line) {
                            list.add(PointF(p.x, p.y))
                        }
                    }
                    for (problem in problems) {
                        val geomList = gson.fromJson<List<PointF>>(
                            problem.strGeom,
                            object : TypeToken<List<PointF?>?>() {}.type
                        )
                        for (gemo in geomList) {
                            val pointF: android.graphics.Point
                            if (geomList.size == 1) {
                                pointF = android.graphics.Point(
                                    gemo.x.toInt(),
                                    -gemo.y.toInt()
                                )
                            } else {
                                pointF = android.graphics.Point(
                                    gemo.x.toInt(),
                                    gemo.y.toInt()
                                )
                            }
                            if (Lasso.isPolygonContainsPoint(list, pointF)) {
                                hasProblem = true
                                break
                            }
                        }
                    }
                    if (spaceEntity.archState == 1) {
                        if (hasProblem) {
                            spaceJobModel.job = "02"
                        } else {
                            spaceJobModel.job = "01"
                        }
                    } else {
                        spaceJobModel.job = "03"
                    }
                } else {
                    if (spaceEntity.equipState == 1) {
                        spaceJobModel.job = "04"
                    } else {
                        spaceJobModel.job = "05"
                    }
                }
//                if (spaceEntity.archState == 1) {
//                    spaceJobModel.job = "01"
//                } else if (spaceEntity.archState == 2 && spaceEntity.equipState == 1) {
//                    if (from.equals("space")) {
//                        spaceJobModel.job = "03"
//                    } else {
//                        spaceJobModel.job = "04"
//                    }
//                } else if (spaceEntity.archState == 2 && spaceEntity.equipState == 2) {
//                    spaceJobModel.job = "05"
//                }
                spaceJobList.add(spaceJobModel)
            }
            mEmitter.SendDircetive(SPACE_JOB, spaceJobList)

        }
//        val bean = ReqSpaceJob()
//        bean.buildingId = buildingId
//        bean.floorId = floorId
//        if ("space" == from) {
//            bean.jobStatus.add("01")
//            bean.jobStatus.add("02")
//            bean.jobStatus.add("03")
//        } else {
//            bean.jobStatus.add("04")
//        }
//        val observable = RetrofitFactory.getInstance().getSpaceJob(getRequestBody(bean))
//        sendRequest(observable, object : BaseObserver<List<SpaceJobModel>>(mActivity, this) {
//            override fun onSuccess(spaceJobModels: List<SpaceJobModel>) {
//                mEmitter.SendDircetive(SPACE_JOB, spaceJobModels)
//            }
//        }, true)
    }

    /**
     * 添加空间核查问题
     *
     * @param choseSpace 选中的空间
     * @param x          x坐标
     * @param y          y坐标
     */
    fun addProblem(
        point: PointItem?,
        photos: ArrayList<Photos>,
        content: String,
        choseSpace: TunableSpaceItem,
        x: Float,
        y: Float,
        linePoints: ArrayList<PipeLineItem>,
        isLine: Boolean
    ) {
        viewModelScope.launch {
            //插入问题数据
            val array = ArrayList<PointF>()
            var toJson = ""
            if (!isLine) {
                val position = PointF()
                position.x = x
                position.y = y
                if (point != null && point.data.mX != 0f) {
                    position.x = point.data.mX
                    position.y = point.data.mY
                }
                array.add(position)
            } else {
                val list = linePoints.get(linePoints.size - 1)
                for (p in list.data.points) {
                    val position = PointF()
                    position.x = p.x
                    position.y = p.y
                    array.add(position)
                }
            }
            toJson = gson.toJson(array)
            var toString = ""
            if (point != null && !TextUtils.isEmpty(point.data.id)) {
                toString = point.data.id!!
            } else {
                toString = UUID.randomUUID().toString().replace("-", "")
            }

            var problem = ProblemArchEntity(
                id = toString,
                floorId = floorId,
                projectId = projectId,
                buildingId = buildingId,
                geomType = if (array.size == 1) "point" else "line",
                workId = "",
                problemType = "",
                problemState = 1,
                message = content,
                creator = "",
                creationTime = "",
                modifier = "android",
                modifiedTime = "",
                uploadFlag = "",
                valid = 1,
                strGeom = toJson,
                state = "1",
                geom = null
            )
            repo.insProblem(problem)


            //插入文件数据
            var order = 0
            for (photo in photos) {
                if (order != 0) {
                    var uuid = ""
                    if (TextUtils.isEmpty(photo.id)) {
                        uuid = UUID.randomUUID().toString().replace("-", "")
                    } else {
                        uuid = photo.id
                    }

                    val file = FileEntity(
                        id = uuid,
                        bizType = "problem_arch",
                        filePath = photo.key,
                        fileType = "photo",
                        clientPath = photo.path,
                        refObjId = toString,
                        refInfoCode = "",
                        remark = "",
                        orderNum = order,
                        projectId = projectId,
                        buildingId = buildingId,
                        floorId = floorId,
                        creator = "android",
                        creationTime = "",
                        modifier = "",
                        modifiedTime = null,
                        valid = 1,
                        uploadFlag = "", state = "1"
                    )
                    repo.insFile(file)
                }
                order++
            }
            mEmitter.SendDircetive(ADD_PROBLEM, null)
        }
//        val bean = ReqAddProblem()
//        bean.spaceId = choseSpace.data.id
//        bean.floorId = floorId
//        val position = Position()
//        position.x = x.toString() + ""
//        position.y = y.toString() + ""
//        bean.position = position
//        val observable = RetrofitFactory.getInstance().addProblem(getRequestBody(bean))
//        sendRequest(observable, object : BaseObserver<AddProblemModel>(mActivity, this) {
//            override fun onSuccess(model: AddProblemModel) {
//                mEmitter.SendDircetive(ADD_PROBLEM, model)
//            }
//        }, true)
    }

    /**
     * 查询空间核查问题
     *
     * @param choseSpace 选中的空间
     */
    fun getProblem(choseSpace: TunableSpaceItem?) {
        viewModelScope.launch {
            val problems = repo.getProblemByFloor(floorId)
            var models: ArrayList<ProblemsModel> = ArrayList()
            for (problem in problems) {
                if (problem.problemState == 1) {
                    val promodel = ProblemsModel()
                    promodel.content = problem.message
                    promodel.floorId = floorId
                    promodel.spaceId = choseSpace!!.data.id
                    promodel.id = problem.id

                    val geomList = gson.fromJson<List<PointF>>(
                        problem.strGeom,
                        object : TypeToken<List<PointF?>?>() {}.type
                    )
                    promodel.geomType = problem.geomType
                    if (problem.geomType!!.equals("point")) {
                        promodel.position = gson.toJson(geomList.get(0))
                    } else if (problem.geomType.equals("line")) {
                        promodel.position = gson.toJson(geomList)
                    }
                    val refFiles = repo.getRefFile(problem.id)
                    for (file in refFiles) {
                        var photo = Photos()
                        photo.key = file.filePath
                        photo.id = file.id
                        photo.itemType = 0
                        photo.path = file.clientPath
                        promodel.photos.add(photo)
                    }
                    models.add(promodel)
                }
            }
            mEmitter.SendDircetive(GET_PROBLEM, models)
        }

//        val bean = ReqProblems()
//        bean.floorId = floorId
////        bean.spaceId = choseSpace!!.data.id
//        val observable = RetrofitFactory.getInstance().problems(getRequestBody(bean))
//        sendRequest(observable, object : BaseObserver<List<ProblemsModel>>(mActivity, this) {
//            override fun onSuccess(models: List<ProblemsModel>) {
//                mEmitter.SendDircetive(GET_PROBLEM, models)
//            }
//        }, true)
    }

    /**
     * 关闭空间核查问题
     *
     * @param point      点位
     * @param choseSpace 选中的空间
     */
    fun closeProblem(point: PointItem, choseSpace: TunableSpaceItem?) {
        viewModelScope.launch {
            val problem = repo.getProblemById(point.data.id!!)
            problem.problemState = 2
            repo.insProblem(problem)
            mEmitter.SendDircetive(CLOSE_PROBLEM, null)
        }
//        val bean = ReqCloseProblem()
//        bean.problemId = point.data.id
//        bean.spaceId = choseSpace!!.data.id
//        val observable = RetrofitFactory.getInstance().closeProblem(getRequestBody(bean))
//        sendRequest(observable, object : BaseObserver<CloseProblemModel>(mActivity, this) {
//            override fun onSuccess(setProblemModel: CloseProblemModel) {
//                mEmitter.SendDircetive(CLOSE_PROBLEM, null)
//            }
//        }, true)
    }

    /**
     * 绑定二维码
     *
     * @param choseSpace 选中的空间
     * @param result     二维码uuid
     * @param point      点位信息
     * @param toString   z轴描述
     */
    fun bindQrcode(choseSpace: TunableSpaceItem?, result: String?, point: Point, toString: String) {
        viewModelScope.launch {
            var pointZ = PointZ()
            pointZ.x = point.mX
            pointZ.y = point.mY
            pointZ.z = toString.toFloat()
            val toJson = gson.toJson(pointZ)
            var time = SimpleDateFormat("yyyyMMddHHmmss").format(Date(System.currentTimeMillis()))
            val qrcode = QrCodeEntity(
                id = UUID.randomUUID().toString(),
                qrCode = result!!,
                objId = choseSpace!!.data.id!!,
                projectId = projectId,
                buildingId = buildingId,
                floorId = floorId,
                strLocation = toJson,
                remark = "wall",
                creator = "Anroid",
                creationTime = "",
                modifier = "Android",
                modifiedTime = "",
                valid = 1,
                uploadFlag = "", state = "1", location = null
            )
            repo.insQrcode(qrcode)
            mEmitter.SendDircetive(BIND_QECODE, null)
        }
//        val bean = ReqBindQrcode()
//        bean.objId = choseSpace!!.data.id
//        bean.objType = "space"
//        bean.uuid = result
//        val position = Position()
//        position.x = java.lang.String.valueOf(point.mX)
//        position.y = java.lang.String.valueOf(point.mY)
//        position.z = Z()
//        position.z.offset = toString
//        position.z.region = "wall"
//        bean.position = position
//        val observable = RetrofitFactory.getInstance().bindQrcode(getRequestBody(bean))
//        sendRequest(observable, object : BaseObserver<BindQrcodeModel?>(mActivity, this) {
//            override fun onSuccess(bindQrcodeModel: BindQrcodeModel?) {
//                mEmitter.SendDircetive(BIND_QECODE, null)
//            }
//        }, true)
    }

    /**
     * 查询对象绑定的二维码
     *
     * @param choseSpace 选中的空间
     */
    fun getQrcode(choseSpace: TunableSpaceItem?) {
        viewModelScope.launch {
            val qrcodes = repo.getQrcode(choseSpace!!.data.id!!)
            val qrcodeModels = ArrayList<QrcodeModel>()
            for (qrcode in qrcodes!!) {
                var qrcodeModel = QrcodeModel()
                qrcodeModel.obj_id = qrcode.objId
                qrcodeModel.qr_code = qrcode.qrCode
                var pointZ = gson.fromJson(qrcode.strLocation, PointZ::class.java)
                val position = Position()
                position.x = pointZ.x.toString()
                position.y = pointZ.y.toString()
                position.z = Z()
                position.z.offset = pointZ.z.toString()
                position.z.region = "wall"
                qrcodeModel.position = gson.toJson(position)
                qrcodeModels.add(qrcodeModel)
            }
            mEmitter.SendDircetive(GET_QECODE, qrcodeModels)
        }
//        val bean = ReqQrcode()
//        bean.objId = choseSpace!!.data.id
//        val observable = RetrofitFactory.getInstance().qrcode(getRequestBody(bean))
//        sendRequest(observable, object : BaseObserver<ArrayList<QrcodeModel>>(mActivity, this) {
//            override fun onSuccess(qrcodeModels: ArrayList<QrcodeModel>) {
//                mEmitter.SendDircetive(GET_QECODE, qrcodeModels)
//            }
//        }, true)
    }

    /**
     * 设置空间的任务状态(新建和修改)
     *
     * @param choseSpace 选中的空间
     * @param toString   数字化交付编码
     */
    fun setJob(choseSpace: TunableSpaceItem?, jobStatus: String) {
        viewModelScope.launch {
            if (jobStatus.equals("03")) {
                val qrcodes = repo.getQrcode(choseSpace!!.data.id!!)
                if (CommonUtils.IsNull(qrcodes)) {
                    ToastUtils.showMyToast("未安装空间二维码，不能完成空间核查")
                    return@launch
                }
            }
            var space = repo.getSpaceBySpaceId(choseSpace!!.data.id!!)
            if (jobStatus.equals("01")) {
                space.archState = 1
            } else if (jobStatus.equals("03")) {
                space.archState = 2
            } else if (jobStatus.equals("04")) {
                space.archState = 2
                space.equipState = 1
            } else if (jobStatus.equals("05")) {
                space.archState = 2
                space.equipState = 2
            }
            space.state = "1"
            repo.insSpace(space)
            mEmitter.SendDircetive(SET_JOB, null)
        }
//        val bean = ReqSetJob()
//        bean.buildingId = buildingId
//        bean.floorId = floorId
//        bean.spaceId.add(choseSpace!!.data.id)
//        bean.jobStatus = jobStatus
//        bean.spaceCode = "test"
//        val observable = RetrofitFactory.getInstance().setJob(getRequestBody(bean))
//        sendRequest(observable, object : BaseObserver<SetJobModel>(mActivity, this) {
//            override fun onSuccess(model: SetJobModel) {
//                mEmitter.SendDircetive(SET_JOB, null)
//            }
//        }, true)
    }

    /**
     * 查询空间下的设备(所在关系)
     *
     * @param choseSpace 选中的空间
     */
    fun getSpaceEq(choseSpace: TunableSpaceItem?) {
        viewModelScope.launch {
            var equips = repo.getEquipByFloorId(floorId)

            var models: ArrayList<SpaceEqModel> = ArrayList()
            for (equip in equips) {
                var hasParent = false
                for (model in models) {
                    if (model.type!!.equals(equip.classCode)) {
                        hasParent = true
                        val child = Children()
                        child.deviceId = equip.id
                        child.name = equip.name
                        val strInfo = gson.fromJson(equip.strInfos, StrInfosforEquip::class.java)
                        val eqProblems = repo.getEqProblem(equip.id)
                        if (eqProblems != null && !TextUtils.isEmpty(eqProblems.id)) {
                            child.type = 3
                        } else if (strInfo.equipCheck) {
                            child.type = 2
                        } else {
                            child.type = 1
                        }
                        val position = Position()
                        position.x = strInfo.location.x.toString()
                        position.y = strInfo.location.y.toString()
                        val z = Z()
                        z.offset = strInfo.location.z.toString()
                        z.region = strInfo.zRegion
                        position.z = z
                        child.position = gson.toJson(position)
                        model.children.add(child)
                    }
                }
                if (!hasParent) {
                    val spaceModel = SpaceEqModel()
                    spaceModel.type = equip.classCode
                    var equipEntity = repo.getEquipByCode(equip.classCode)
                    spaceModel.typeName = equipEntity?.name
                    val child = Children()
                    child.deviceId = equip.id
                    child.name = equip.name
                    val strInfo = gson.fromJson(equip.strInfos, StrInfosforEquip::class.java)
                    val eqProblems = repo.getEqProblem(equip.id)
                    if (eqProblems != null && !TextUtils.isEmpty(eqProblems.id)) {
                        child.type = 3
                    } else if (strInfo.equipCheck) {
                        child.type = 2
                    } else {
                        child.type = 1
                    }
                    val position = Position()
                    position.x = strInfo.location.x.toString()
                    position.y = strInfo.location.y.toString()
                    val z = Z()
                    z.offset = strInfo.location.z.toString()
                    z.region = strInfo.zRegion
                    position.z = z
                    child.position = gson.toJson(position)
                    spaceModel.children.add(child)
                    models.add(spaceModel)
                }
            }
            mEmitter.SendDircetive(SPACE_EQ, models)
        }
//        val bean = ReqSpaceEq()
//        bean.group = true
//        bean.spaceId = choseSpace!!.data.id
//        val observable = RetrofitFactory.getInstance().getSpaceEq(getRequestBody(bean))
//        sendRequest(observable, object : BaseObserver<List<SpaceEqModel>>(mActivity, this) {
//            override fun onSuccess(models: List<SpaceEqModel>) {
//                mEmitter.SendDircetive(SPACE_EQ, models)
//            }
//        }, true)
    }

    /**
     * 获取管线类型
     */
    fun pipeList() {
        val bean = ReqPipeList()
        val observable = RetrofitFactory.getInstance().pipeList(getRequestBody(bean))
        sendRequest(observable, object : BaseObserver<ArrayList<PipeListModel>>(mActivity, this) {
            override fun onSuccess(models: ArrayList<PipeListModel>) {
                mEmitter.SendDircetive(PIPE_LIST, models)
            }
        }, true)
    }

    /**
     * 添加管线
     * @param model         管线类型
     * @param pipeLineList  位置坐标
     * @param remark        描述
     * @param choseSpace    被选中的空间
     */
    fun addPipe(
//        model: PipeListModel,
//        pipeLineList: java.util.ArrayList<PointF>,
//        remark: String,
//        choseSpace: TunableSpaceItem?
    ) {
//        val bean = ReqAddPipe()
//        bean.spaceId = choseSpace!!.data.id
//        bean.sys = model.sysCode
//        bean.type = model.code
//        bean.position = pipeLineList
//        bean.remark = remark
//        bean.name = model.name
//        val observable = RetrofitFactory.getInstance().addPipe(getRequestBody(bean))
//        sendRequest(observable, object : BaseObserver<AddPipeModel>(mActivity, this) {
//            override fun onSuccess(models: AddPipeModel) {
//                mEmitter.SendDircetive(ADD_PIPE, null)
//            }
//        }, true)
    }

    /**
     * 查询楼层下的管道数据
     */
    fun floorPipe() {
//        viewModelScope.launch {
//            val pipeModels = ArrayList<SpacePipeModel>()
//            val pipes = repo.getPipeByFloorId(floorId)
//            for (pipe in pipes) {
//                var hasParent = false
//                for (model in pipeModels) {
//                    if (model.type!!.equals(pipe.pipeType)) {
//                        val child = ChildrenZ()
//                        val objFrom = repo.getObject(pipe.objFrom!!)
//                        val objTo = repo.getObject(pipe.objTo!!)
//                        val strInfoFrom =
//                            gson.fromJson(objFrom!!.strInfos, StrInfosforEquip::class.java)
//                        child.position.add(PointF(strInfoFrom.location.x, strInfoFrom.location.y))
//
//                        val strInfoTo =
//                            gson.fromJson(objTo!!.strInfos, StrInfosforEquip::class.java)
//                        child.position.add(PointF(strInfoTo.location.x, strInfoTo.location.y))
//                        model.children.add(child)
//                        hasParent = true
//                    }
//                }
//                if (!hasParent) {
//                    val pipeModel = SpacePipeModel()
//                    pipeModel.typeName = pipe.pipeSubType + "--" + pipe.pipeType
//                    pipeModel.type = pipe.pipeType
//                    val child = ChildrenZ()
//                    val objFrom = repo.getObject(pipe.objFrom!!)
//                    val objTo = repo.getObject(pipe.objTo!!)
//                    val strInfoFrom =
//                        gson.fromJson(objFrom!!.strInfos, StrInfosforEquip::class.java)
//                    child.position.add(PointF(strInfoFrom.location.x, strInfoFrom.location.y))
//
//                    val strInfoTo = gson.fromJson(objTo!!.strInfos, StrInfosforEquip::class.java)
//                    child.position.add(PointF(strInfoTo.location.x, strInfoTo.location.y))
//                    pipeModel.children.add(child)
//                    pipeModels.add(pipeModel)
//                }
//
//            }
//            mEmitter.SendDircetive(SPACE_PIPE, pipeModels)
//        }
    }

    fun getInfosConfig(spaceId: String) {
        viewModelScope.launch {
            val infosConfig = repo.getInfosConfigByObjType("space")
            val strInfos = infosConfig.get(0).strInfos

//            var infoList = gson.fromJson(strInfos, ArrayList<Infos>()::class.java)
            var infoList = gson.fromJson<List<Infos>>(
                strInfos,
                object : TypeToken<List<Infos?>?>() {}.type
            )
            var spaceObject = repo.getObject(spaceId)
            val infos = gson.fromJson(spaceObject!!.strInfos, HashMap::class.java)

            mEmitter.SendDircetive(SPACE_INFOS, infos)
            mEmitter.SendDircetive(SPACE_INFO, infoList)
        }
    }

    fun jsonObjectToHashMap(jsonObj: JSONObject?): HashMap<String, String>? {
        if (jsonObj == null) {
            return null
        }
        val data = HashMap<String, String>()
        val it: Iterator<*> = jsonObj.keys()
        while (it.hasNext()) {
            val key = it.next().toString()
            data[key] = jsonObj[key].toString()
        }
        System.out.println(data)
        return data
    }

    fun refreshObject(space: TunableSpace, hashMap: HashMap<String, Any>) {
        viewModelScope.launch {
            var space = repo.getObject(space.id!!)
//            space!!.infos = JSONObject(hashMap as Map<*, *>)
            space!!.strInfos = gson.toJson(hashMap)
            space.state = "1"
            repo.insObject(space)
            mActivity.setResult(RESULT_OK)
            mActivity.finish()
//            var objectEntity = ObjectEntity(
//                id = space.id!!,
//                name = space.name!!,
//
//            )
//            repo.insObject()
        }
    }


    fun getEquipment(deviceId: String) {
        viewModelScope.launch {
            val equips = repo.getEquipment()
            for (equip in equips) {
                if (!TextUtils.isEmpty(equip.systemCode)) {
                    val systemEntity = repo.getSysByCode(equip.systemCode!!)
                    equip.systemName = systemEntity?.name
                }
            }
            mEmitter.SendDircetive(EQUIP_CLASS, equips)

            if (!TextUtils.isEmpty(deviceId)) {
                var equip = repo.getObject(deviceId)
                val infos = gson.fromJson(equip!!.strInfos, HashMap::class.java)
                mEmitter.SendDircetive(SPACE_INFOS, infos)
                mEmitter.SendDircetive(Equip_INFOS, equip)
            }


//            var infoList = gson.fromJson(strInfos, ArrayList<Infos>()::class.java)

        }
    }

    fun getEquipInfosConfig(equipmentEntity: EquipmentEntity) {
        viewModelScope.launch {
            val infosConfig = repo.getInfosConfigByEquipCode(equipmentEntity.code!!)
            if (CommonUtils.IsNull(infosConfig)) {
                mEmitter.SendDircetive(EQUIP_INFO, null)
                return@launch
            }
            val strInfos = infosConfig.get(0).strInfos
            val infoList = gson.fromJson<List<Infos>>(
                strInfos,
                object : TypeToken<List<Infos?>?>() {}.type
            )
            mEmitter.SendDircetive(EQUIP_INFO, infoList)

        }
    }

    fun insEquip(
        uuid: String,
        deviceId: String?,
        hashMap: HashMap<String, Any>?,
        equipContent: String,
        beans: ArrayList<Photos>,
        equipEntity: EquipmentEntity,
        localName: String,
        localId: String,
        checked: Boolean,
        position: Position
    ) {
        viewModelScope.launch {
            val objects = repo.getObjects()
            if (!CommonUtils.IsNull(objects)) {
                for (obj in objects) {
                    if (!TextUtils.isEmpty(obj.localId) && obj.localId!!.toUpperCase()
                            .equals(localId.toUpperCase())
                    ) {
                        ToastUtils.showMyToast("已有此编码的设备")
                        return@launch
                    }
                }
            }
            hashMap!!.put("equipContent", equipContent)
            hashMap!!.put("equipPhoto", gson.toJson(beans))
            hashMap!!.put("equipCheck", checked)
            val z = PointZ()
            z.x = position.x.toFloat()
            z.y = -position.y.toFloat()
            z.z = position.z.offset.toFloat()
            hashMap!!.put("location", z)
            hashMap!!.put("zRegion", position.z.region)
            if (TextUtils.isEmpty(deviceId)) {
                val objectEntity = ObjectEntity(
                    id = uuid,
                    name = localName,
                    projectId = projectId,
                    objType = "equipment",
                    classCode = equipEntity.code!!,
                    localId = localId,
                    localName = localName,
                    groupCode = "",
                    grouping = 1,
                    buildingId = buildingId,
                    floorId = floorId,
                    creator = "Android",
                    createApp = "",
                    creationTime = "",
                    modifier = "Android",
                    modifiedTime = "",
                    clientDevice = "",
                    clientId = uuid,
                    updateApp = "",
                    uploadFlag = "",
                    valid = 1,
                    deliveryState = null,
                    d2mState = null,
                    virtualCodes = null,
                    infos = null,
                    strInfos = gson.toJson(hashMap),
                    floorMap = null, state = "1"
                )
                repo.insObject(objectEntity)
            } else {
                val equip = repo.getObject(deviceId!!)
//                equip!!.infos = JSONObject(hashMap as Map<*, *>)
                equip!!.classCode = equipEntity.code!!
                equip.localId = localId
                equip.strInfos = gson.toJson(hashMap)
                equip.state = "1"
                repo.insObject(equip)
            }
            //插入文件数据
            var order = 0
            for (photo in beans) {
                if (photo.itemType != 1) {
                    if (order != 0) {
                        var phUuid = ""
                        if (TextUtils.isEmpty(photo.id)) {
                            phUuid = UUID.randomUUID().toString().replace("-", "")
                        } else {
                            phUuid = photo.id
                        }

                        val file = FileEntity(
                            id = phUuid,
                            bizType = "problem_arch",
                            filePath = photo.key,
                            fileType = "photo",
                            clientPath = photo.path,
                            refObjId = if (TextUtils.isEmpty(deviceId)) uuid else deviceId,
                            refInfoCode = "",
                            remark = "",
                            orderNum = order,
                            projectId = projectId,
                            buildingId = buildingId,
                            floorId = floorId,
                            creator = "android",
                            creationTime = "",
                            modifier = "",
                            modifiedTime = null,
                            valid = 1,
                            uploadFlag = "", state = "1"
                        )
                        repo.insFile(file)
                    }
                    order++
                }
            }
            mActivity.setResult(RESULT_OK)
            mActivity.finish()
        }
    }

    fun getMap() {
        viewModelScope.launch {
            val floors = repo.getFloors()
            for (floor in floors) {
                if (floor.id.equals(floorId)) {
                    if (TextUtils.isEmpty(floor.floorMap)) {
                        ToastUtils.showMyToast("没有地图")
                        break
                    }
                    val floorOfflineData =
                        SJsonUtil.fromJson(floor.floorMap!!, FloorData::class.java)
                    mEmitter.SendDircetive(MAP_LOAD, gson.toJson(floorOfflineData))
                    break
                }
            }

        }
    }

    fun getRelConfig(entity: EquipmentEntity, deviceId: String, uuid: String) {
        viewModelScope.launch {
            val equipId = if (TextUtils.isEmpty(deviceId)) uuid else deviceId
            //获取关系二级列表
            val configParent = ArrayList<RelConfigEntityPackClass>()
            val relList = mutableListOf<List<RelationPackClass>>()
            val fromList = repo.getRelConfigByCodeFrom(entity.code!!)
            val toList = repo.getRelConfigByCodeTo(entity.code!!)
            loadCfgs(entity.code, fromList, true, configParent)
            loadCfgs(entity.code, toList, true, configParent)
            for (parent in configParent) {
                var rel = ArrayList<RelationPackClass>()
                for (child in parent.targetTypes) {
                    if (child.canFrom) {
                        val to = repo.getRelByCodeTo(
                            parent.entity.graphCode!!,
                            parent.entity.relCode!!,
                            equipId
                        )
                        loadRelation(to, child, parent, rel)
                    }

                    if (child.canTo) {
                        val from = repo.getRelByCodeFrom(
                            parent.entity.graphCode!!,
                            parent.entity.relCode!!,
                            equipId
                        )
                        loadRelation(from, child, parent, rel)
                    }
                }
                relList.add(rel)
            }
            val hashMap = HashMap<String, Any>()
            hashMap.put("parent", configParent)
            hashMap.put("child", relList)
            mEmitter.SendDircetive(EQUIP_REL, hashMap)

            //获取管道二级列表
            val pipeParent = ArrayList<PipeConfigEntityPackClass>()
            val pipeChildren = mutableListOf<List<PipeEntity>>()
            val pipeFromList = repo.getPipeConfigByCodeFrom(entity.code)
            val pipeToList = repo.getPipeConfigByCodeTo(entity.code)
            loadPipeCfgs(entity.code, pipeFromList, true, pipeParent)
            loadPipeCfgs(entity.code, pipeToList, true, pipeParent)
            val floorPipes = repo.getPipeByFloorId(floorId)
            for (parent in pipeParent) {
                var pipes = ArrayList<PipeEntity>()
                for (floorPipe in floorPipes) {
                    if ((floorPipe.objFrom.equals(equipId) || floorPipe.objTo.equals(equipId)) && floorPipe.pipeType.equals(
                            parent.entity.pipeType
                        ) && floorPipe.pipeSubType.equals(parent.entity.pipeSubType)
                    ) {
                        bindPipeName(floorPipe)
                        pipes.add(floorPipe)
                    }
                }
                pipeChildren.add(pipes)
            }
            val hashMap1 = HashMap<String, Any>()
            hashMap1.put("parent", pipeParent)
            hashMap1.put("child", pipeChildren)
            mEmitter.SendDircetive(PIPE, hashMap1)

        }
    }

    private suspend fun bindPipeName(floorPipe: PipeEntity) {
        val from = repo.getObject(floorPipe.objFrom!!)
        if (from == null) {
            floorPipe.objFromLocalId = "该设备"
        } else {
            floorPipe.objFromLocalId =
                if (from!!.id.startsWith("Eq")) from!!.localId else from!!.localName
        }
        val to = repo.getObject(floorPipe.objTo!!)
        if (to == null) {
            floorPipe.objToLocalId = "该设备"
        } else {
            floorPipe.objToLocalId = if (to!!.id.startsWith("Eq")) to!!.localId else to!!.localName
        }
    }

    private fun loadPipeCfgs(
        srcCode: String,
        cfgs: List<PipeConfigEntity>,
        targetAsTo: Boolean,
        groups: ArrayList<PipeConfigEntityPackClass>
    ) {
        for (cfg in cfgs) {
            var group: PipeConfigEntityPackClass? = null
            for (g in groups) {
                if (g.samePipeConfig(cfg)) {
                    group = g
                    break
                }
            }
            if (group == null) {
                group = PipeConfigEntityPackClass()
                group.entity = cfg
                groups.add(group)
            }
            val cfgTarget = if (targetAsTo) cfg.classCodeTo else cfg.classCodeFrom

            var targetType: PipeConfigEntityPackClass.TargetPipeType? = null
            for (t in group.targetTypes) {
                if (t.targetCode.equals(cfgTarget)) {
                    targetType = t
                    break
                }
            }
            if (targetType == null) {
                targetType = PipeConfigEntityPackClass.TargetPipeType()
                targetType.srcCode = srcCode
                targetType.pipeType = group.entity.pipeType
                targetType.pipeSubType = group.entity.pipeSubType
                targetType.targetCode = cfgTarget
                group.targetTypes.add(targetType)
            }
            if (cfg.pipeDirection == 1) {
                if (targetAsTo) {
                    targetType.canTo = true
                } else {
                    targetType.canFrom = true
                }
            } else if (cfg.pipeDirection == -1) {
                if (targetAsTo) {
                    targetType.canFrom = true
                } else {
                    targetType.canTo = true
                }
            } else if (cfg.pipeDirection == 0) {
                targetType.canConnect = true
            }
        }
    }

    private suspend fun loadRelation(
        to: List<RelationEntity>,
        child: RelConfigEntityPackClass.TargetRelType,
        parent: RelConfigEntityPackClass,
        rel: ArrayList<RelationPackClass>
    ) {
        bindRelationEntityName(to)
        if (!CommonUtils.IsNull(to)) {
            for (t in to) {
                if (child.targetCode.equals(parent.entity.classCodeTo)) {
                    val pack = RelationPackClass()
                    pack.entity = t
                    pack.targetPipeType = child
                    rel.add(pack)
                }
            }
        }
    }

    private suspend fun bindRelationEntityName(
        entitys: List<RelationEntity>
    ) {
        for (rel in entitys) {
            val from = repo.getObject(rel.objFrom!!)
            if (from == null) {
                rel.objFromLocalId = "该设备"
            } else {
                rel.objFromLocalId =
                    if (from!!.id.startsWith("Eq")) from!!.localId else from!!.localName
            }
            val to = repo.getObject(rel.objTo!!)
            if (to == null) {
                rel.objToLocalId = "该设备"
            } else {
                rel.objToLocalId = if (to!!.id.startsWith("Eq")) to!!.localId else to!!.localName
            }
        }
    }

    private fun loadCfgs(
        srcCode: String,
        cfgs: List<RelConfigEntity>,
        targetAsTo: Boolean,
        groups: ArrayList<RelConfigEntityPackClass>
    ) {
        for (cfg in cfgs) {
            var group: RelConfigEntityPackClass? = null
            for (g in groups) {
                if (g.sameRelConfig(cfg)) {
                    group = g
                    break
                }
            }
            if (group == null) {
                group = RelConfigEntityPackClass()
                group.entity = cfg
                groups.add(group)
            }
            val cfgTarget = if (targetAsTo) cfg.classCodeTo else cfg.classCodeFrom
            var tartgetType: RelConfigEntityPackClass.TargetRelType? = null
            for (t in group.targetTypes) {
                if (t.targetCode.equals(cfgTarget)) {
                    tartgetType = t
                    break
                }
            }
            if (tartgetType == null) {
                tartgetType = RelConfigEntityPackClass.TargetRelType()
                tartgetType.srcCode = srcCode
                tartgetType.graphCode = group.entity.graphCode
                tartgetType.relCode = group.entity.relCode
                tartgetType.targetCode = cfgTarget
                tartgetType.direction = cfg.direction
                group.targetTypes.add(tartgetType)
            }
            if (targetAsTo) {
                tartgetType.canTo = true
            } else {
                tartgetType.canFrom = true
            }

            if ("fixed".equals(cfg.direction)) {
                if (targetAsTo)
                    tartgetType.canTo = true
                else
                    tartgetType.canFrom = true
            } else if ("optional".equals(cfg.direction)) {
                tartgetType.canTo = true
                tartgetType.canFrom = true
            } else {
                tartgetType.connect = true
                // !targetCanBeTo && !targetCanBeFrom 表示无方向选择
            }

        }
    }

    fun getRelObj(group: RelConfigEntityPackClass, code: String) {
        viewModelScope.launch {
            val objects: ArrayList<ObjectEntity> = ArrayList()
            for (type in group.targetTypes) {
                val objs = repo.getObjectByCode(type.targetCode!!)
                if (!CommonUtils.IsNull(objs)) {
                    objects.addAll(objs)
                }
            }
            mEmitter.SendDircetive(REL_OBJECT, objects)
        }
    }

    fun getPipeObj(group: PipeConfigEntityPackClass, code: String) {
        viewModelScope.launch {
            val objects: ArrayList<ObjectEntity> = ArrayList()
            for (type in group.targetTypes) {
                val objs = repo.getObjectByCode(type.targetCode!!)
                if (!CommonUtils.IsNull(objs)) {
                    objects.addAll(objs)
                }
            }
            mEmitter.SendDircetive(PIPE_OBJECT, objects)
        }
    }

    fun addRel(
        deviceId: String, uuid: String, equipEntity: EquipmentEntity,
        equip: ObjectEntity,
        groupRelConfigEntity: RelConfigEntity,
        eq: Boolean
    ) {
        viewModelScope.launch {
            var equipId: String
            if (TextUtils.isEmpty(deviceId)) {
                equipId = uuid
            } else {
                equipId = deviceId
            }
            val objFrom: String
            val objto: String
            if (eq) {
                objFrom = equipId
                objto = equip.id
            } else {
                objto = equipId
                objFrom = equip.id
            }

            val relEntity = RelationEntity(
                id = UUID.randomUUID().toString(),
                projectId = projectId,
                buildingId = buildingId,
                floorId = floorId,
                graphCode = groupRelConfigEntity.graphCode,
                graphId = null,
                groupCode = null,
                relCode = groupRelConfigEntity.relCode,
                relValue = null,
                objFrom = objFrom,
                objTo = objto,
                createApp = null,
                updateApp = null,
                creator = null,
                creationTime = "",
                modifiedTime = "",
                modifier = null,
                clientId = null,
                clientDevice = null,
                uploadFlag = null,
                deliveryState = null,
                valid = 1, d2mState = null, objFromLocalId = null, objToLocalId = null, state = "1"
            )
            repo.insRelation(relEntity)
            getRelConfig(equipEntity, deviceId, uuid)
        }
    }

    fun addPipe(
        deviceId: String, uuid: String, equipEntity: EquipmentEntity,
        equip: ObjectEntity,
        groupPipeConfigEntity: PipeConfigEntity,
        direction: String
    ) {
        viewModelScope.launch {
            var equipId: String
            if (TextUtils.isEmpty(deviceId)) {
                equipId = uuid
            } else {
                equipId = deviceId
            }
            val objFrom: String
            val objto: String
            if (groupPipeConfigEntity.classCodeFrom.equals(equipEntity!!.code)) {
                objFrom = equipId
                objto = equip.id
            } else {
                objto = equipId
                objFrom = equip.id
            }
            var pipeDirection: Int
            if (direction.equals("->")) {
                pipeDirection = 1
            } else if (direction.equals("<-")) {
                pipeDirection = -1
            } else {
                pipeDirection = 0
            }

            val relEntity = PipeEntity(
                id = UUID.randomUUID().toString(),
                projectId = projectId,
                buildingId = buildingId,
                floorId = floorId,
                objFrom = objFrom,
                objTo = objto,
                creator = null,
                creationTime = "",
                modifiedTime = "",
                modifier = null,
                uploadFlag = null,
                deliveryState = null,
                valid = 1,
                d2mState = null,
                objFromLocalId = null,
                objToLocalId = null,
                direction = pipeDirection,
                typeFrom = "equipment",
                typeTo = "equipment",
                pipeType = groupPipeConfigEntity.pipeType,
                pipeSubType = groupPipeConfigEntity.pipeSubType,
                route = null,
                infos = null, state = "1"
            )
            repo.insPipe(relEntity)
            getRelConfig(equipEntity, deviceId, uuid)
        }
    }

    fun insProblemEquip(space: TunableSpaceItem, deviceId: String) {
        viewModelScope.launch {
            val equip = repo.getObject(deviceId)
            if (TextUtils.isEmpty(equip?.clientId)) {
                val proEntity = repo.getEqProblem(deviceId)
                if (proEntity == null) {
                    val entity = ProblemEquipEntity(
                        id = UUID.randomUUID().toString(),
                        floorId = floorId,
                        projectId = projectId,
                        buildingId = buildingId,
                        equipId = deviceId,
                        workId = null,
                        problemType = null,
                        problemState = 1,
                        message = null,
                        creator = null,
                        creationTime = "",
                        modifier = null,
                        modifiedTime = "",
                        uploadFlag = null,
                        valid = 1, state = "1"
                    )
                    repo.insProblemEquipEntity(entity)
                }
            } else {
                equip?.valid = 0
                equip?.state = "1"
                repo.insObject(equip!!)
            }
            getSpaceEq(space)
        }
    }

    fun deleteRel(
        item: RelationEntity,
        equipEntity: EquipmentEntity?,
        deviceId: String,
        uuid: String
    ) {
        viewModelScope.launch {
            var rel = repo.getRelById(item.id)
            rel.valid = 0
            repo.insRelation(rel)
            getRelConfig(equipEntity!!, deviceId, uuid)
        }
    }

    fun deletePipe(
        item: PipeEntity,
        equipEntity: EquipmentEntity?,
        deviceId: String,
        uuid: String
    ) {
        viewModelScope.launch {
            var rel = repo.getPipeById(item.id)
            rel.valid = 0
            repo.insPipe(rel)
            getRelConfig(equipEntity!!, deviceId, uuid)
        }
    }

    fun queryAutoUpdate() {
        val bean = ApkVersionBean()
        val observable = RetrofitFactory.getInstance().autoUpdateApp(getRequestBody(bean))
        sendRequest(
            observable,
            object : BaseObserver<java.util.ArrayList<AutoUpDateBean.Content>>(mActivity, this) {
                override fun onSuccess(models: ArrayList<AutoUpDateBean.Content>) {
                    if (!CommonUtils.IsNull(models)) {
                        mEmitter.SendDircetive(UPDATE_APP, models.get(0))
                    }
                }
            },
            true
        )
    }

    fun insEquip(ob: ObjectEntity, position: Position) {
        viewModelScope.launch {
            var obj = repo.getObject(ob.id)
            val hashMap = gson.fromJson(obj!!.strInfos, HashMap::class.java) as HashMap<String, Any>
            val z = PointZ()
            z.x = position.x.toFloat()
            z.y = -position.y.toFloat()
            z.z = position.z.offset.toFloat()
            hashMap.put("location", z)
            hashMap.put("zRegion", position.z.region)
            obj.strInfos = gson.toJson(hashMap)
            obj.state = "1"
            repo.insObject(obj)
            mEmitter.SendDircetive(UPDATE_LOCATION, null)
        }

    }

    companion object {
        const val UPDATE_APP = "UPDATE_APP"
        const val MAP_LOAD = "MAP_LOAD"
        const val EQUIP_CLASS = "EQUIP_CLASS"

        //
        const val REFRESH_OBJECT = "SPACE_JOB"

        //查询空间和任务
        const val SPACE_JOB = "SPACE_JOB"

        //添加空间核查问题
        const val ADD_PROBLEM = "ADD_PROBLEM"

        //查询空间核查问题
        const val GET_PROBLEM = "GET_PROBLEM"

        //设置空间核查问题的信息和状态
        const val SET_PROBLEM = "SET_PROBLEM"

        //关闭空间核查问题
        const val CLOSE_PROBLEM = "CLOSE_PROBLEM"

        //绑定二维码
        const val BIND_QECODE = "BIND_QECODE"

        //查询对象绑定的二维码
        const val GET_QECODE = "GET_QECODE"

        //设置空间的任务状态(新建和修改)
        const val SET_JOB = "SET_JOB"

        //设置空间的任务状态(新建和修改)
        const val SPACE_EQ = "SPACE_EQ"

        //查询管道类型树
        const val PIPE_LIST = "PIPE_LIST"

        //添加管线
        const val ADD_PIPE = "ADD_PIPE"

        //查询空间下的管道Equip_INFOS
        const val SPACE_PIPE = "SPACE_PIPE"

        //查询空间详情
        const val SPACE_INFO = "SPACE_INFO"
        const val SPACE_INFOS = "SPACE_INFOS"


        //查询设备详情
        const val EQUIP_INFO = "EQUIP_INFO"
        const val Equip_INFOS = "Equip_INFOS"
        const val EQUIP_REL = "EQUIP_REL"

        const val REL_OBJECT = "REL_OBJECT"
        const val PIPE_OBJECT = "PIPE_OBJECT"
        const val PIPE = "PIPE"
        const val UPDATE_LOCATION = "UPDATE_LOCATION"
    }

}