package com.sybotan.android.demo.viewmodel

import android.app.Application
import android.graphics.PointF
import android.text.TextUtils
import androidx.lifecycle.viewModelScope
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.Photos
import cn.sagacloud.android.cadengine.types.Point
import cn.sagacloud.android.cadengine.types.PointZ
import cn.sagacloud.android.cadengine.types.TunableSpace
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.JsonObject
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 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

/**
 * 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
                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"
                }
                val strInfo = gson.fromJson(objectEntity.strInfos, StrInfos::class.java)

                spaceJobModel.outline = strInfo.outline
                spaceJobModel.objectEntity = objectEntity
                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
    ) {
        viewModelScope.launch {
            //插入问题数据
            val position = PointF()
            position.x = x
            position.y = y
            var toJson = ""
            if (point != null && point.data.mX != 0f) {
                position.x = point.data.mX
                position.y = point.data.mY
                toJson = gson.toJson(position)
            } else {
                toJson = gson.toJson(position)
            }
            var time = SimpleDateFormat("yyyyMMddHHmmss").format(Date(System.currentTimeMillis()))
            var toString = ""
            if (point != null && !TextUtils.isEmpty(point.data.id)) {
                toString = point.data.id!!
            } else {
                toString = UUID.randomUUID().toString().replace("-", "")
            }

            var problem = ProblemArchEntity(
                toString,
                floorId,
                projectId,
                buildingId,
                "point", "",
                "",
                1,
                content,
                "",
                time,
                "android", time, "0", 1, toJson
            )
            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(
                        uuid,
                        "problem_arch",
                        photo.key,
                        "photo",
                        photo.path,
                        toString,
                        "",
                        "",
                        order,
                        projectId,
                        buildingId,
                        floorId,
                        "android",
                        time,
                        "",
                        time,
                        1,
                        "0"
                    )
                    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.getProblem()
            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
                    promodel.position = problem.geom
                    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,
                location = toJson,
                remark = "wall",
                creator = "Anroid",
                creationTime = time,
                modifier = "Android",
                modifiedTime = time,
                valid = 1,
                uploadFlag = "0"
            )
            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.location, 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 {
            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
            }
            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?) {
        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() {
        val bean = ReqFloorPipe()
        bean.floorId = floorId
        val observable = RetrofitFactory.getInstance().floorPipe(getRequestBody(bean))
        sendRequest(
            observable,
            object : BaseObserver<java.util.ArrayList<SpacePipeModel>>(mActivity, this) {
                override fun onSuccess(models: java.util.ArrayList<SpacePipeModel>) {
                    mEmitter.SendDircetive(SPACE_PIPE, models)
                }
            },
            true
        )
    }

    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
            )
            mEmitter.SendDircetive(SPACE_INFO, infoList)
        }
    }

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

    companion object {
        //
        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"

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

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

}